Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
124 lines
7.9 KiB
Markdown
124 lines
7.9 KiB
Markdown
# 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:
|
|
|
|
1. 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.
|
|
2. Workstation execution: requires an explicitly routed worker/task queue and
|
|
a durable always-on ownership/connectivity contract. Merely starting another
|
|
worker on `orchestrator-tq` is 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.
|