Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
5.4 KiB
Custodian bounded operations
Daily security-flow and weekly allocation definitions remain disabled. They use the existing ACT-ADR-007 bounded-operation stage and Temporal schedule ownership, with one fixed owner command per run. They emit no agent task, ops_run or model invocation. The former harness.agent-dev-local@1.1.1 pin is incompatible: its green-commit-only tools forbid Python, its sandbox denies Hub egress, and its operational readiness is unverified.
Trusted operator bindings
| Environment variable | Required contract |
|---|---|
| ACTIVITY_CORE_CUSTODIAN_ROOT | Absolute pinned owner source bundle, including owner scripts and dependencies. |
| ACTIVITY_CORE_CUSTODIAN_FLEET_ROOT | Absolute accepted repository snapshot/mount root, without credential directories. |
| ACTIVITY_CORE_CUSTODIAN_STATE_ROOT | Precreated private directory, worker-owned, mode 0700, outside source and fleet roots; retained/backed up by executor owner. |
| ACTIVITY_CORE_CUSTODIAN_REPOS | Daily flow's explicit comma-separated canonical repo slugs, each with workplans under fleet root. |
| ACTIVITY_CORE_CUSTODIAN_HUB | Daily flow's explicitly admitted HTTP(S) base URL without embedded credentials, query or fragment. |
| ACTIVITY_CORE_CUSTODIAN_ALLOCATION_REQUEST | Weekly executor-owned request JSON within private state, binding real inputs, fixed evaluation time and retained output. |
These are trusted deployment configuration, never definition command parameters. Missing bindings, traversal, symlinks, unbound inputs and output/input aliases are refused before execution. Weekly inputs remain under accepted roots and output stays in private state. The state root must be separate: when fleet root is /home/worsch, its ~/.local/state default is not accepted. Provision a separate retained mount and precreate its security-flow subdirectory.
Keep paths/request files protected from concurrent untrusted writers and mount source read-only. Checks are not a sandbox or credential-isolation boundary. Owner code and dependencies need accepted revision/digest. The adapter uses the worker Python and installs nothing. Daily decision sync scans decision logs throughout the fleet root; reporting scans the explicit repository list. Bind the root to approved decision-sync scope, not an arbitrary home directory.
Execution and receipts
Daily: worker Python runs security_flow_daily.py with fixed --root, --repos, --hub, --state-dir, and --apply only when explicitly declared. Owner locking and checkpoints govern duplicate messages. The adapter suppresses stdout/stderr, requires a refreshed valid report.json, and retains only SHA-256, exit status, apply flag and category counts. No message bodies enter its receipt.
Weekly: worker Python runs weekly_allocation_report.py --request with the bound request. The owner's immutable retention and identical retry semantics remain, including unchanged mtime on identical retries. The adapter executes a private snapshot of validated request bytes, preserving relative-path resolution; pointer changes cannot redirect that run. Freeze each request across retries; use a new retained path for revised evidence. The receipt contains report hash and recommendation count, without inventing measurements.
Both use fixed argv, no shell, at most 240 seconds within a 300-second Temporal activity timeout, and one attempt. Subprocess timeout terminates the process group including helpers. Nonzero exits and missing/invalid reports fail; raw command errors are not persisted. Checkpointed writes can precede failure: inspect owner state before retry. No parallel scheduler/retry loop is added.
The existing workflow retains the compact result in activity context and sends it through the declared State Hub progress evidence sink. This replaces ops_run close evidence for these routines. Command success does not prove sink delivery or owner acknowledgment; verify sink outcomes and owner artifacts separately.
Remaining acceptance
ACTIVITY-WP-0047-T02/T03 retain daily activation/first fire; CUST-WP-0071-T05 retains weekly acceptance after T04. Runtime owner must verify placement, scoped mounts, Python/dependencies, retained state/backup, admitted Hub connectivity and exact owner command behavior. No bindings or schedule installation are established by source tests. Exercise stale/missed/failed-run detection, ambiguous failure recovery, delivery and owner acknowledgment. Misfires skip; recovery requires a named owner. Weekly collection and recommendation upserts also remain. Retain the first unattended activity, report, sink and owner receipts.
tests/test_custodian_operations.py uses temporary fixture commands or mocked dispatch. It never invokes the real security command, Hub or schedule activation.
Concrete delivery options and unresolved owner choices are recorded in custodian-runtime-binding-proposal.md.
Daily execution requires ACTIVITY_CORE_CUSTODIAN_INPUT_POLICY and ACTIVITY_CORE_CUSTODIAN_FRESHNESS_RECEIPTS, a protected JSON array of
existing Repo Manager receipts. Admission verifies exact complete snapshot
contents and fresh per-repo Forge observations before starting subprocesses.
The existing-worker candidate configures this gate; missing policy or receipts
refuse execution before subprocess. Native freshness noops rely on protected
Repo Manager issuer custody: the issuer checks HEAD against its last successful
commit before emitting forge_head_matches_last_success.