Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
9.5 KiB
Custodian fleet input publication contract
Owner recommendation, 2026-10-19; source preparation only. Repo Manager owns commit selection and work-record publication. Activity Core owns scheduling, private consumer storage, admission and run evidence. Custodian owns daily report semantics. These are proposed defaults, not runtime acceptance or an activation.
Reuse and exact missing boundary
rmgr freshness run --limit N --max-seconds S already observes Forge default HEAD,
verifies the primary Hub projection and writes durable
repo-manager.freshness-receipt.v1 receipts. It explicitly makes no checkout.
The classification publisher's snapshots contain metadata, not work-record files.
Neither command currently supplies a filesystem tree to Custodian commands.
Do not reinterpret Hub rows or a classification snapshot as those input files.
The new offline prerequisite is:
python -m repo_manager.fleet_snapshot --request selected-commits.json --output snapshots/<unique-run-id>
It reads existing local Git objects, never fetches, checks out, changes a repo, contacts Hub/Forge, or reads a credential. This is a module CLI rather than a new daemon or scheduler. The publication owner supplies object stores using its existing approved Git delivery path. Choosing that runtime source/access path is still required; the exporter itself needs no network or authentication.
Request contract:
{
"observed_at": "2026-10-19T07:00:00+02:00",
"repositories": [
{"slug": "the-custodian", "path": "/accepted/local/object-store/the-custodian", "commit": "<full-40-character-commit>"}
]
}
The example commit is a placeholder, deliberately not runnable. The publisher
must retain each matching Forge observation/receipt ID separately; observed_at
is supplied evidence, not a freshness assertion made by the offline exporter.
Only workplans/**/*.md (including archived dependencies) and decisions/*.md
are copied. Git symlinks, submodules at selected record paths, invalid slugs,
non-full commit IDs, absent workplans and oversize records are refused. Dirty
working files, .git, credentials and unrelated files are not copied. Limits are
2MiB per record and 64MiB total per export; exceeding either is an explicit
publication failure, never partial accepted coverage.
Each new unique output contains <slug>/workplans, optional <slug>/decisions,
manifest.json and finally COMPLETE. Manifest schema
repo-manager.fleet-input.v1 records the requested observation time, all commits,
file byte lengths and SHA-256 values. freshness_verified: false is intentional.
COMPLETE contains the manifest SHA-256. Consumers must validate this marker,
manifest and every file before accepting a publication. Failed promotion leaves
no COMPLETE and must never be consumed. Names are never overwritten, even empty
existing directories. The owner protects the output parent against concurrent
untrusted writers. This is completion-marked publication, not a crash-durable
transaction or automatically enforced read-only store. Do not change published
files; mount the selected immutable directory read-only for the consumer.
Recommended default daily policy
Initial scope is the existing report estate: the-custodian, net-kingdom, railiance-platform, activity-core, access-engine, secrets-engine, ops-mason, ops-warden, key-cape, user-engine, tenant-engine, gate-house, kings-guard, policy-nexus and rapp-policy-nexus. This is a proposed explicit allowlist, not permission to publish every registered repo. The same selected set bounds both workplan reporting and decision synchronization. Review additions for cross-repo dependency completeness; missing dependencies remain unknown.
Recommend one pre-run publication step in the existing native daily workflow,
not a separate timer. Reuse Repo Manager's Forge HEAD/primary receipt verification
for the selected set, then export those exact commits from accepted object stores.
rmgr freshness run --repos <comma-separated-set> --limit 15 --max-seconds <budget>
now targets exactly the approved active set, rejecting missing active repos or a
limit smaller than the set. The default untargeted mode still rotates fleet
members. The publisher must inspect deferred/failure results and join successful
per-repo receipts for every selected repo; command invocation alone is not
complete coverage. No fabricated receipt or forced reconciliation is acceptable.
Recommended admission: observations at most 2 hours old at daily start, no future
observation beyond 5 minutes of clock tolerance, all required repos present,
full commits matching the verified observations, exact file hashes, and COMPLETE
valid. Old commit age is not failure when its HEAD was recently re-observed.
Never rewrite an old snapshot's timestamp to make it fresh. On missing/stale
inputs, fail before security_flow_daily.py --apply, retain a sanitized missing
repo/reason receipt and notify through the existing Activity Core failure path.
Do not silently reuse yesterday's tree. Activity Core now requires the consumer freshness/content gate and supports
immutable descriptor selection. The remote capture/transfer publication step
is still unimplemented; neither local source test proves runtime publication.
Hold a specific snapshot path throughout a run and its retries. Avoid current
symlinks (executor rejects them) and in-place directory replacement. Placement
must supply an immutable per-run path or a serialized binding update while
consumers are quiescent. Activity Core's prepared consumer selects an immutable child directory from a
regular descriptor carrying manifest/receipt hashes. The receiver must finish
retaining both artifacts before atomically replacing that descriptor. Transport
and receiver implementation remain required before activation.
Retention and weekly boundary
Recommend retaining 35 days of daily publications plus every snapshot referenced by an unresolved failure, checkpoint, audit or accepted recommendation. Capacity planning must use measured export sizes, not assume the shared 1Gi claim suffices. Pruning is owner-reviewed initially; this exporter performs no deletion. Keep manifest/receipt hashes with run evidence and back up private state separately. Restore testing and capacity alarms are delivery gates, not established here.
Weekly sizing uses the existing cluster, resource-control, telemetry, inventory, provenance and optional previous-report/review inputs. Repo Manager must not manufacture telemetry or impersonate those collectors. Recommend retaining at least 13 weekly bundles plus all referenced/open recommendation evidence, with evaluation windows preserved. Custodian owns the weekly request and collector coverage validation; Activity Core owns immutable request handoff and retained report storage. Daily Git snapshots do not satisfy weekly measurement coverage.
Owner handoff and validation
Repo Manager recommendation: use this bounded offline export after the existing Forge receipt checks, with the explicit 15-repo set and 2-hour admission default. Activity Core should add the manifest/freshness gate and per-run immutable binding when implementing the chosen worker placement; never loosen symlink validation. No public API, broad clone service, extra schedule or new credential path is needed. Production receipt verification, object-store provisioning, consumer gate, retention/storage acceptance and first scheduled evidence remain unfinished.
Local tests use temporary Git repositories and prove committed-byte export despite dirty files, strict path selection, hashes/completion marker, immutable names, invalid-request refusal, selected symlink refusal and size bounds. They perform no network, production reads, schedule changes or Hub writes.
Wind-down checkpoint: disabled remote capture source
custodian_snapshot.py and the existing runtime now prepare a fixed-policy
POST /ports/repositories/custodian-snapshot endpoint. Default is404/disabled.
Configuration requires REPO_MANAGER_CUSTODIAN_SNAPSHOT_ENABLED=true,
REPO_MANAGER_CUSTODIAN_SNAPSHOT_POLICY and
REPO_MANAGER_CUSTODIAN_SNAPSHOT_HUB; existing PublisherSettings supplies the
authorized Forge reader. Existing optional API-token admission is preserved.
No caller paths/refs/repos/commands are used. No source endpoint is deployed.
Capture targets the complete configured set through native freshness, then reads allowlisted files at those exact commits through Forge contents API. It verifies Git blob identity, refuses unexpected/symlink files and returns a content- addressed manifest/receipt/file bundle. Default hard payload bound8MiB and per-response bound3MiB fail closed. Publisher state has no new persistent volume.
Validation: 47 publisher/capture/freshness/exporter tests passed with mocked HTTP;
one existing Starlette/httpx deprecation warning. Source lint review remains a
restart check. The source endpoint uses a process-local concurrency lock and
240-second native budget; it does NOT cancel producer work on client disconnect
or retain durable in-progress receipt state. Do not treat it as ready for the
proposed45-second combined daily pre-run phase. Existing15-repo capture timing
has not been measured. Activity Core receiver is standalone and unintegrated;
see its k8s/custodian-release/RESTART.md for exact restart steps.
The core-hub publisher's existing CCR0031 reader remains in that namespace. New Activity Core access to private workplan/decision content and publisher-to-Hub egress require the explicit source-reviewed data/network delta before live promotion. No credential route, access scope or schedule was changed here.