# 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](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`.