Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
7.9 KiB
Custodian runtime binding proposal
Review artifact, 2026-10-19. Not a deployment or activation approval. Both native
ActivityDefinitions remain enabled: false. No manifests, images or schedules
were changed for this proposal. Read with custodian-bounded-operations.md.
Verified source boundary
The worker in k8s/railiance/20-runtime.yaml runs as UID/GID 1000 and already
uses actcore-ops-artefacts for freshness and owner-return subdirectories. Its
image does not contain the Custodian commands; its current mounts contain
neither the accepted fleet workplans/decisions nor the new private state.
CUSTODIAN_REPO_ROOT=/var/custodian only binds existing prompts/working memory;
it does not satisfy any ACTIVITY_CORE_CUSTODIAN_* binding.
The existing immutable ConfigMap plus read-only mount pattern documented in
k8s/backup-release/README.md is sufficient for the small command bundle. No
new packaging service is needed. Proposed source pin:
the-custodian@60d893af1bf77f457504b64ff1c9ffb5c6ae6579.
These four files total 30,169 bytes and use Python standard-library modules;
the daily command imports/calls the two sibling helper scripts.
| Path under owner root | SHA-256 |
|---|---|
| scripts/security_flow_daily.py | 4a4e84702b3fb38d086695bb6d601430d8914bd79286b4f683794206f110c353 |
| scripts/security_flow_report.py | eac9fdcc56d7f3ff613e6848c7523fb9a421d82a3b564a51c36f8c2b842eef02 |
| scripts/sync_resolved_decisions.py | 182433ca7cd31e2b2773246ec1be02569ba6f089ac009add6543e5e48777b5ec |
| scripts/weekly_allocation_report.py | 93f546243331308d7e60f8db36e988d9847537a2fe46cce49ee2fffba1f7f247 |
A reviewed immutable ConfigMap can map these four keys to scripts/<name>
below /opt/custodian-commands. Kubernetes ConfigMap volume projections use
symlinks, which the executor deliberately rejects. Therefore copy the mounted
immutable bundle into a dedicated emptyDir in an init container, verify all four
hashes there, then mount that copy read-only in the worker. Do not bind the
projected ConfigMap directly or weaken executor symlink checks. Alternatively,
copy the same pinned files into the existing worker image during its reviewed
build. The latter avoids the init-container copy and is the narrower runtime
mount boundary, but requires an accepted source-delivery/build input. Neither
alternative has been chosen or implemented here.
Exact proposed bindings and outstanding choices
| Binding | Proposed value / owner decision |
|---|---|
| ACTIVITY_CORE_CUSTODIAN_ROOT | /opt/custodian-commands, regular files, read-only, hashes above |
| ACTIVITY_CORE_CUSTODIAN_FLEET_ROOT | /var/lib/custodian-inputs/fleet, read-only accepted snapshots |
| ACTIVITY_CORE_CUSTODIAN_STATE_ROOT | /var/lib/activity-core/custodian, persistent, UID 1000, mode 0700 |
| ACTIVITY_CORE_CUSTODIAN_REPOS | Explicit operator-approved subset of the daily report estate; each must have workplans/ |
| ACTIVITY_CORE_CUSTODIAN_HUB | http://state-hub.state-hub.svc.cluster.local:8000, subject to admitted network verification |
| ACTIVITY_CORE_CUSTODIAN_ALLOCATION_REQUEST | /var/lib/activity-core/custodian/requests/current.json, regular file protected against concurrent writers |
For daily input, preserve <repo>/workplans/**/*.md including dependency records
and <repo>/decisions/*.md only for approved decision-sync scope. The decision
helper scans every repo under the fleet root independently of the report list.
Do not mount a whole workstation home, .git, credential directories or arbitrary
mutable repositories. Fleet snapshots need per-repo revision, capture time,
refresh owner and an explicit staleness policy. No existing publication contract
for this combined input was found in the worker manifests. Choosing its publisher
is a real prerequisite; a pinned old snapshot alone cannot support daily freshness.
Weekly input remains the existing retained collector outputs plus request JSON,
not a new collector. Its owner must bind actual input/report paths and evaluation
time, freeze the request across retries, and publish a new request for the next
week. The executor does not advance a static current.json automatically.
Snapshot publication must be atomic relative to execution and preserve retained
inputs needed to reproduce reports. Never substitute synthetic readings.
Storage choice: reuse a new custodian subdirectory of existing
actcore-ops-artefacts only after its owner accepts capacity, retention and backup
coverage, or provision a dedicated claim with those properties. The existing
rollout document describes a 1Gi local-path claim, and October 4 evidence reports
it Bound; neither proves present capacity or backup coverage. Precreate state,
security-flow, requests and output/input retention directories with correct
ownership. Do not chown/chmod the whole shared claim. A PVC subPath is acceptable
if actual mounted paths are regular directories and pass executor validation.
The proposed direct Hub service matches the worker's existing
STATE_HUB_API_BASE; the shared config also contains an edge-relay URL. Daily
message delivery requires a central message ID. A relay queued receipt is pending
evidence and is not interchangeable with that ID; do not select relay delivery
without an explicit adapter/replay contract. Needed operations are GET open
decisions, POST decision resolution, POST messages, and the existing progress
sink. Runtime network authorization remains unverified. The shared worker already
has secret env and kube mounts: this proposal does not establish credential isolation.
Placement choices for owner review:
- Existing production worker: choose image-baked scripts or verified copied immutable bundle, choose fleet publisher and state claim above, then review normal owner GitOps changes. This reuses the present Temporal task queue.
- Workstation execution: requires an explicitly routed worker/task queue and
a durable always-on ownership/connectivity contract. Merely starting another
worker on
orchestrator-tqis unsafe because either worker may receive these activities. No workstation routing or second scheduler is proposed.
Verification and rollback before activation
Prepare the accepted source bundle and manifest diff outside active kustomization until the choices above are recorded. Preserve both disabled definitions; native schedule synchronization creates disabled definitions paused. Verify their DB versions and Temporal paused state after any later deployment, without firing. Mount/env changes exceed image-only promotion authority; follow owner-reviewed GitOps promotion, not a widened image-only helper.
Local source tests already cover parsing both disabled definitions, missing-binding refusal before subprocess, fixed commands, symlink rejection, bounded timeouts and sanitized receipts. At delivery review, independently verify pinned hashes, worker Python imports, UID/modes, mount read-only flags, free retained capacity, scoped fleet revision/age and actual request/output confinement. Use fixture inputs for initial process verification; daily dry-run still reads Hub and therefore is not an offline test. Obtain separate authorization for real Hub operations.
After operator-approved runtime placement, retain exact worker image/bundle and input revisions, operation context, owner report hash, progress sink result and owner acknowledgment. Scheduled activation and first unattended run remain ACTIVITY-WP-0047-T02/T03 and CUST-WP-0071-T04/T05 gates. An exit-zero fixture or a paused schedule does not satisfy them.
Rollback: keep both schedules paused, restore the previous reviewed worker image/config/bundle references through GitOps, and keep old bundle objects until no rollback ReplicaSet references them. Preserve private reports, checkpoints and requests; do not delete the state claim. Inspect partially delivered daily checkpoints before retrying, because rollback cannot undo Hub writes. Do not reuse or overwrite an immutable weekly output for revised inputs.