diff --git a/AGENTS.md b/AGENTS.md index e3a010e..7c6b4cc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -186,6 +186,38 @@ get wrong. --- +## Agent supervision at session start + +Read `docs/agent-autonomy-decision.md` and the record for the identified agent. +For the Custodian Codex assignment, that record is +`.kaizen/agents/custodian-codex/supervision.json`. Check its scope, supervisor, +mode and runtime-enforcement status before privileged work. Do not inherit a +record belonging to another agent or scope. Missing promotion evidence means +supervised-mode; neither a mode label nor preapproved shell prefixes establish +credential isolation or an autopilot grant. + +Summarize the existing record without changing authority: + +```bash +python3 scripts/summarize_agent_supervision.py .kaizen/agents/custodian-codex/supervision.json +``` + +Before submitting a new privileged-action proposal, retain its stable proposal +ID, exact original revision/digest, target, expected result, verification and +rollback, and cost/risk estimates in the existing record or referenced receipt. +Record the supervisor disposition and approved revision, then the exact executed +revision, verified outcome, refinements and recovery. A revision is part of the +same trial, not another success. Preserve failed and unverified outcomes. Do not +backfill missing approval evidence into a scored success. + +Existing session authorization remains valid within its scope; do not ask again +merely to populate a record. Routine authorized preparation, local edits and +checks continue. The reporting utility cannot approve actions or promote the +agent. Autopilot requires an explicit scoped grant, EUR cost/risk limits and +verified runtime enforcement; it is not enabled for this assignment. + +--- + ## Workplan Convention (ADR-001) Work items originate as files in this repo — not in the hub. The hub is a diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index dcf4544..2be68ab 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -465,7 +465,7 @@ | task | CUST-WP-0072-T04 | done | — | workplans/CUST-WP-0072-fleet-flavor-and-depends-on-backfill.md | | task | CUST-WP-0073-T01 | done | — | workplans/CUST-WP-0073-agent-credential-separation.md | | task | CUST-WP-0073-T02 | progress | — | workplans/CUST-WP-0073-agent-credential-separation.md | -| task | CUST-WP-0073-T03 | wait | — | workplans/CUST-WP-0073-agent-credential-separation.md | +| task | CUST-WP-0073-T03 | done | — | workplans/CUST-WP-0073-agent-credential-separation.md | | task | CUST-WP-0073-T04 | progress | — | workplans/CUST-WP-0073-agent-credential-separation.md | | task | CUST-WP-0073-T05 | wait | — | workplans/CUST-WP-0073-agent-credential-separation.md | | task | THE-WP-0001-T01 | done | — | workplans/THE-WP-0001-federation-interface.md | diff --git a/docs/changes/CUST-WP-0073/README.md b/docs/changes/CUST-WP-0073/README.md index b9ee99c..ed60118 100644 --- a/docs/changes/CUST-WP-0073/README.md +++ b/docs/changes/CUST-WP-0073/README.md @@ -75,10 +75,9 @@ refreshes of all 39 ExternalSecrets. The platform owner's pinned revision `7daf7e9` is authoritative; the original proposal file is retained for history. Reference: [ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/). -Before any retry, fix and verify the 31 ESO declarations described in the rollout -receipt, then in one attended railiance-platform window: remove existing last-applied -annotations without logging values; persist the manifest in that owner's -deployment path; dry-run and diff; install policy and binding. Use only a +For future changes, preserve the explicit ESO target metadata already deployed. +Use the owner's source and deployment path, dry-run and diff, and the safe +maintenance helper for any required annotation cleanup. Use only a synthetic, non-credential Secret in a scratch namespace to verify clean create and update succeed, annotated create/update (including empty annotation) fail, and client-side apply fails. Verify the policy type-check status, then remove @@ -92,8 +91,8 @@ not revoke any credential or stop other ways of reading secrets. ## Guidance and deferred rotation (T04/T05) -The September 24 standing notice exists. The raw presence template is now -withdrawn: absent annotations can trigger a dump of the full Secret. Use only +The September 28 standing notice supersedes September 24 and explicitly +withdraws the raw presence template: absent annotations can trigger a dump of the full Secret. Use only the maintenance helper, which captures and suppresses kubectl output on errors. Claude's recorded guard remains a stopgap. No equivalent Codex/Grok read-denial hook has been established by this work; this session has broad kubectl/SSH permissions, so instructions are the diff --git a/docs/evidence/2026-09-28-secret-guidance-notice.json b/docs/evidence/2026-09-28-secret-guidance-notice.json new file mode 100644 index 0000000..babade0 --- /dev/null +++ b/docs/evidence/2026-09-28-secret-guidance-notice.json @@ -0,0 +1,9 @@ +{ + "from_agent": "the-custodian", + "to_agent": "broadcast", + "kind": "standing", + "supersedes_id": "9bf2dba7-7bf8-40b4-b100-f74db80e0dd8", + "subject": "STANDING: Secret checks require the safe helper; inline template exception withdrawn (2026-09-28)", + "body": "Read the-custodian/docs/agent-environment-orientation.md before production, credential or GitOps work. This supersedes the September 24 orientation notice.\n\nSection 6 withdraws the inline Secret presence-check exception. Even a metadata-only template can fail and dump the entire Secret when annotations are absent. Never run standalone go-template/jsonpath against real Secrets, including the old presence check, and never print raw kubectl error output or Secret annotations.\n\nUse railiance-platform/scripts/secret_annotation_maintenance.py through the authorized admin path. Default mode inspects; --clean removes only the duplicate last-applied annotation. The helper captures and suppresses subprocess output/errors and emits only identities, counts and booleans. Keep that output boundary intact.\n\nThe reject-secret-last-applied admission guard is now active on railiance01. Secret writers must avoid client-side apply annotations. ESO target metadata is explicit in all 31 corrected declarations; all 39 ExternalSecrets passed fresh refreshes under enforcement. Do not remove those metadata templates on a later deployment. Rollout evidence: the-custodian/docs/evidence/2026-09-28-secret-annotation-rollout.md.\n\nAgent autonomy is per agent and scope: supervised first; promotion requires an explicit grant and enforced EUR cost/risk limits. A record or acceptance rate does not isolate credentials or authorize autopilot. Actual interactive agent isolation remains unfinished under CUST-WP-0073-T02. Decision and startup procedure: the-custodian/docs/agent-autonomy-decision.md and the-custodian/AGENTS.md.", + "published_id": "51e9eace-06d2-46d6-921a-4b92440df68f" +} diff --git a/workplans/CUST-WP-0073-agent-credential-separation.md b/workplans/CUST-WP-0073-agent-credential-separation.md index 0315192..373f66a 100644 --- a/workplans/CUST-WP-0073-agent-credential-separation.md +++ b/workplans/CUST-WP-0073-agent-credential-separation.md @@ -136,7 +136,7 @@ drill Secret was deleted with its UID precondition; absence verified and the - Add a `ValidatingAdmissionPolicy` (v1.35 is available) with its binding. It rejects any Secret carrying `kubectl.kubernetes.io/last-applied-configuration`. - Strip the annotation from existing Secrets first, cluster-wide, using the - presence-check template, or the policy blocks their next update. Known: + output-suppressing maintenance helper, or the policy blocks their next update. Known: `sso/keycape-config`, `sso/authelia-secrets`, `sso/lldap-secrets`, `mfa/privacyidea-config`. - Proof: a client-side `kubectl apply` of a test Secret in a scratch namespace @@ -151,10 +151,10 @@ priority: medium state_hub_task_id: "90725511-4e31-549f-b567-47feff1a9ca4" ``` -- Orientation doc §6: add the template-error dump; state that no template or - jsonpath may run against a Secret except the tested presence check; point to - the agent identity once T02 lands. Announce it as a standing notice that - supersedes the 2026-09-21 one. +- Orientation doc §6 documents the template-error dump and requires the safe + maintenance helper; standalone Secret templates/jsonpath are forbidden. The + September 28 standing notice supersedes the September 24 inline-check exception. + Add the verified agent identity/execution path once T02 lands. - Claude Code guard, **done on the workstation 2026-09-24**: `~/.claude/hooks/guard-secret-reads.py` (PreToolUse on Bash). It denies Secret reads, `helm get`, `config view --raw` and kubeconfig reads, and asks before @@ -195,85 +195,47 @@ Reopen on the first of: The passage of time alone reopens nothing. -## September 28 implementation review +## Current evidence and handoff — September 28 -The founder asks for minimal additional tasks/workplans/functionality. Keep -execution and all unresolved evidence in T01–T05. No new plan or task was opened. +The founder requests minimal additional tasks, workplans and functionality. +All remaining work stays in T02, T04 and the original deferred T05. No new +workplan, task, controller or supervisor service was introduced. -Reviewable package: `docs/changes/CUST-WP-0073/README.md` and -`reject-secret-last-applied.yaml` beside it. Live read-only inspection confirms -`tegwick` has unrestricted passwordless sudo, k3s kubeconfig is still 644, and -Kubernetes uses `system:admin` / `system:masters`. The public host inventory maps -agent and admin principals to this same account. A kubeconfig switch or chmod -alone is insufficient; do not claim the agent boundary has landed. +T01 is done: autonomy is per agent and scope, supervised initially, with later +promotion bounded by EUR cost and risk limits. The decision and descriptive +per-agent record do not establish runtime enforcement or grant autopilot. -T01's initial permanent observation-only proposal is superseded by the founder's -agent-specific supervised/autopilot decision in `docs/agent-autonomy-decision.md`. -T01 is done; T02 must -verify the actual agent execution environment has no route back through admin -SSH/sudo, tokens, sockets or automated deployment. This adds no new broker. +T02 remains in progress. The existing sand-boxer `profile.bwrap-local` passed a +synthetic process-isolation proof: admin homes, privileged environment variables, +Kubernetes/container sockets absent; only loopback networking; observation and +proposal paths work; wrong consumer rejected; workspace destroyed. Receipt: +`docs/evidence/2026-09-28-supervised-sandbox-proof.json`. It was not an interactive +agent migration. The selected GLAS local-profile acceptance remains blocked; +existing coordination receipt: `docs/evidence/2026-09-28-supervised-runtime-coordination.json`. +Actual account/profile admission and denial of old admin SSH/sudo/credential +paths are still required. The inspected legacy account has unrestricted sudo +and k3s kubeconfig mode 644; changing its default kubeconfig alone is insufficient. -T02 in progress: the existing sand-boxer `profile.bwrap-local` passed a -synthetic supervised-process proof: admin homes, Kubernetes/container socket -paths and privileged environment variables absent; only loopback networking; -observation readable; proposal writable; wrong consumer identity rejected; -workspace destroyed. Receipt: `docs/evidence/2026-09-28-supervised-sandbox-proof.json`. -This was not an interactive agent or a credential migration. Existing GLAS -local-profile acceptance and actual admin-path denial remain required in T02. +T03 is done. All 31 affected ESO declarations have explicit target metadata in +23 files across 12 owning repositories, committed and published. The guard is +active and Synced/Healthy at platform source `7daf7e9`, pinned by `db51ec8`. +Nine native admission checks and 39/39 fresh ESO refreshes under Deny passed. +The founder-approved UID-bound deletion removed only the orphan drill Secret; +the 3 GiB PVC was unchanged. The final complete scan checked 257 Secrets with +zero forbidden annotations and zero orphan exceptions. The earlier failed +rollout and rollback remain historical evidence in +`docs/evidence/2026-09-28-secret-annotation-rollout.md`; they are not the live state. -T03 in progress: policy source `railiance-platform@800cbfa`, application `54885ac` -and nine passing native admission checks were followed by ESO refresh failures. -ESO v0.16.1 copies source metadata when an ExternalSecret has no target template; -31 declarations need explicit metadata before the strict guard is compatible. -The binding was removed and all 39 ExternalSecrets recovered. GitOps now pins -policy-only `6016f72` via application commit `c5d65b0`; the application is Synced -and Healthy, and enforcement is disabled. Detailed rollout and recovery receipt: -`docs/evidence/2026-09-28-secret-annotation-rollout.md`. +T04's local guidance and reporting are implemented. AGENTS.md now loads the +supervision decision and per-agent record at startup and describes recording +original proposals before approval and verified outcomes afterwards. The +September 28 standing notice withdraws the unsafe inline presence check: +51e9eace-06d2-46d6-921a-4b92440df68f. Receipt: `docs/evidence/2026-09-28-secret-guidance-notice.json`. +Codex/Grok have no equivalent read-denial hook established by this work. The +remaining T04 step is to document the actual verified T02 execution path. +The original rollout remains an unscored failed proposal with refinement and +recovery; successful remediation does not become unchanged-success credit. +There is no eligible acceptance-rate sample or autopilot grant yet. -Cleanup removed the duplicate annotation from 49 distinct active-namespace -Secrets across the recorded passes, but ESO can regenerate it while enforcement -is off. An orphan `platform-pg-drill/drill-minio` Secret cannot be patched because -its namespace is absent; a referencing Deployment, PVC and Service remain. No -orphan was deleted. Neither stable cluster-wide cleanup nor T03 completion is -claimed. Keep remediation and integration proof in this existing task. - -T04 in progress: orientation §6 withdraws the unsafe raw presence template; -only the capturing/sanitizing maintenance helper is allowed. A logical -per-agent supervised record lives at `.kaizen/agents/custodian-codex/supervision.json`. -Its summary separates unchanged acceptance from verified unchanged execution, -retains failed outcomes and rescue, and grants no authority. The rollout is an -unscored historical approval with a failed outcome and recovery, not promotion -evidence. There is no eligible acceptance-rate sample yet, no autopilot grant, -and no enforced interactive-runtime migration. Codex/Grok have no established -equivalent read-denial hook. Final guidance still needs the actual T02 path. -T05 remains the original trigger-based founder deferral, not cancelled or done. - -## Corrected admission rollout — September 28 continuation - -T03: all 31 affected ExternalSecrets now have explicit target metadata in their -owner sources (23 files, 12 repositories, committed and published). Server -dry-run verified only the target template changes; credential data mappings and -policies remain unchanged. All 39 ExternalSecrets refreshed successfully before -and after re-enabling Deny enforcement. All nine native admission checks pass. -The guard is Synced/Healthy at platform source `7daf7e9`, pinned by `db51ec8`. -The earlier rollback is historical, not the current live state. Detailed evidence: -`docs/evidence/2026-09-28-secret-annotation-rollout.md`. - -A complete scan of all 257 Secrets in existing namespaces found no forbidden -annotation after the writer fixes. T03 now waits only for the orphan -`platform-pg-drill/drill-minio`: its namespace is absent, so an annotation patch -is refused. UID-bound deletion of that one Secret is prepared and awaits -explicit authorization; no PVC deletion or namespace recreation is proposed. -All remaining work stays in existing tasks; no new task, workplan, controller -or service was introduced. T02 still needs actual supervised-runtime admission; -T05 keeps its founder-deferred rotation triggers. - -Post-enforcement scan: all 257 active-namespace Secrets remain annotation-free. -The exact orphan deletion also passed server-side dry-run; execution awaits -the founder response. Receipt: `docs/evidence/2026-09-28-secret-annotation-scan-enforced.json`. - -Final orphan disposition: the founder explicitly selected “Delete only the -orphan Secret.” The UID-bound deletion succeeded and absence was verified; -the bound 3 GiB PVC retained the same UID, resourceVersion, volume and status. -No other resources were changed. T03 is done and its human-needed flag cleared. -Receipt: `docs/evidence/2026-09-28-orphan-secret-deletion.json`. +T05 remains the founder's trigger-based rotation deferral, not cancelled or done. +Neither workplan completion nor live credential separation is claimed.