From 5fe38bc6d1847923fdec9ee415d9570e918bffb8 Mon Sep 17 00:00:00 2001 From: codex Date: Sat, 3 Oct 2026 03:12:09 +0200 Subject: [PATCH] CUST-WP-0075: security gate assessment; route CUST-WP-0073-T05 to decision packet D3 Co-Authored-By: Claude Fable 5.1 --- history/20261003-security-gate-packets.md | 139 ++++++++++++++++++ ...UST-WP-0073-agent-credential-separation.md | 3 +- 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 history/20261003-security-gate-packets.md diff --git a/history/20261003-security-gate-packets.md b/history/20261003-security-gate-packets.md new file mode 100644 index 00000000..4c149799 --- /dev/null +++ b/history/20261003-security-gate-packets.md @@ -0,0 +1,139 @@ +--- +id: 20261003-security-gate-packets +type: assessment +title: "What the dependency graph says about how security work gets blocked, and what to change" +date: "2026-10-03" +assessor: the-custodian (Claude) +audience: founder +status: recorded +related_workplans: + - CUST-WP-0075 + - CUST-WP-0074 + - CUST-WP-0072 + - RPF-WP-0035 + - WARDEN-WP-0027 +origin: "Founder request 2026-10-03: use the dependency facility to shrink the blocked set and learn how to make the security infrastructure easier to maintain and extend." +--- + +# What the dependency graph says about security work + +Snapshot 2026-10-03 from the workplan files of 145 registered repos +(`docs/evidence/2026-10-03-dependency-graph-triage/`). This is an +assessment with proposals. It changes no canon and authorizes nothing. + +## 1. The shape of the blockage + +| Measure | Value | +| --- | ---: | +| Open workplans | 108 (100 blocked) | +| Wait tasks inside them | 232 | +| Human gates (`needs_human: true`) | 69 | +| Human gates that named a hub decision | 0 | +| Owner-return waits (`blocked_on: message-from:`) | 20 | +| Wait tasks whose blockers were already terminal | 8 | +| Cycles | 0 | + +Three facts matter more than the counts. + +**The graph has no cycles and few true roots.** Removing the already- +satisfied and mis-statused cases, the open set hangs off roughly a dozen +root nodes. The two largest, `SAND-WP-0015-T04` (7 workplans behind it) +and `SECRETS-WP-0009-T03` (5), are themselves owner-return waits on +railiance-platform and glas-harness, which in turn wait on one attended +OpenBao session. So the single largest lever is not a repo and not a +workplan; it is one kind of act by one person. + +**Human gates were invisible to the hub.** The wait-qualifier standard +(`canon/standards/task-wait-qualifiers_v0.1.md`) and C-40 rule 4 already +let a resolved decision clear a task. Nobody used it: all 69 gates were +prose. Bernd therefore had 69 places to read and no list to resolve. +`CUST-WP-0075-T03` routed 68 of them to eleven hub decisions (one has no +stated gate at all, `WARDEN-WP-0037-T03`, and goes back to its owner). + +**Security work is where this concentrates.** Of the 69 gates, 19 are +attended OpenBao provisioning acts (packet D1), 14 are the ArgoCD +production-ownership sequence (D2), 3 are trust-root and custody design +(D3), 3 are destructive cleanups behind retention windows (D4), 7 are +production risk acceptances (D5). That is 46 of 69 in the credential, +identity, delivery and custody space. Product and research gates are the +minority. + +## 2. Why credential work blocks the way it does + +Reading the lane documents in railiance-platform +(`docs/credential-lane-designs/`, `docs/openbao-approved-automation-delegation.md`, +`docs/credential-lane-lifecycle-runbook.md`) and the ops-warden catalog +(38 routing entries) gives a consistent picture: + +1. **Metadata is delegated, values are not.** The delegated applier may + write policies and auth roles from an approved CCR; secret *values* + stay an attended operator act "unless a later workplan approves a + stronger dual-control flow". Almost every D1 task is blocked at + exactly that value step: the policy is designed, reviewed, often + dry-run, and then waits for a session. +2. **Each lane negotiates its own session.** Nineteen tasks in twelve + repos describe the same act in their own words, with their own + evidence expectations. Nothing aggregates them, so no session is ever + "worth" scheduling and each lane waits for its own. +3. **Owner-return waits chain across repos.** sand-boxer waits on + railiance-platform, which waits on secrets-engine, which waits on the + session. Each hop is a hub message that may or may not be answered; + the C-25 unread-reply check exists but nothing sweeps it. +4. **The read model lags the files.** The hub carried 201 dependency + edges where the files carry more; task-level edges from the September + backfill were "parked" behind a deploy. Anyone querying the hub for + the graph got a thinner picture than the files hold. + +None of this is a design flaw in OpenBao, KeyCape or ops-warden. It is +the absence of a *batching* and *routing* layer between well-designed +lanes and one scarce person. + +## 3. Proposals (ease of maintenance and extension) + +**P1 — Gates are born routed.** Extend C-39: a `needs_human: true` wait +in an open, non-residual workplan without `decision_id` is a WARN. Owner +repos then attach a decision at the moment they create the gate, and the +hub's open-decision list *is* Bernd's queue. (state-hub, small.) + +**P2 — The attended provisioning window is a standing event.** Instead +of per-lane sessions, one dated window (fortnightly is enough at current +volume). Its checklist is generated, not written: every task carrying +the window's `decision_id`, joined to its CCR and lane doc, rendered by +`credential-change.py` as a numbered attended sequence with the receipt +each owner needs. Owners prepare to that checklist; the session runs it +top to bottom; resolving the decision raises C-40 on every task. +(railiance-platform owns the renderer; the-custodian owns the cadence.) + +**P3 — Decide the dual-control value path once.** The delegation doc +leaves "stronger dual-control" open. The honest options are (a) keep +values attended but batched (P2 alone), (b) response-wrapped delivery +where the issuing system writes the value into OpenBao under a +one-time wrapping token the operator only *unwraps*, or (c) a scoped +operator-write role under MFA used by a wrapped command that never +prints. Pick one in packet D3 alongside the trust-root ruling; it removes +the value step from most future lanes. (railiance-platform workplan.) + +**P4 — Catalog lane as the unit of extension.** A new consumer today +costs a design workplan, a CCR, an attended apply and bespoke evidence. +Make the ops-warden catalog entry the template: entry + CCR skeleton + +policy/role rendering + ExternalSecret manifest + evidence script +scaffolded from one command. Then a new lane is a reviewed PR, not a +workplan, and only its value step needs the window. (ops-warden + +railiance-platform.) + +**P5 — Owner-return sweep.** A weekly the-custodian task lists every +`blocked_on: message-from:` task whose awaited agent has an +unread or unanswered message older than seven days and nudges the owner +in one message per agent. It uses C-25 output, not a new mechanism. + +**P6 — Keep the hub graph current.** Run `statehub fix-consistency --all +--remote` on railiance01 nightly so C-20 keeps the edge table equal to +the files, and finish the deploy that carries task-level edges. The +graph scripts in this triage can then run against the hub alone. + +## 4. What this does not change + +The hub stays a read model. Decisions were recorded through the +sanctioned route and every `decision_id` lives in the owner file, synced +by fix-consistency. No workplan or task was registered by hand. No +credential was requested, printed or moved. diff --git a/workplans/CUST-WP-0073-agent-credential-separation.md b/workplans/CUST-WP-0073-agent-credential-separation.md index 90fa5868..58f1efd1 100644 --- a/workplans/CUST-WP-0073-agent-credential-separation.md +++ b/workplans/CUST-WP-0073-agent-credential-separation.md @@ -9,7 +9,7 @@ owner: the-custodian topic_slug: custodian flavor: implementation created: "2026-09-24" -updated: "2026-09-28" +updated: "2026-10-03" related: - KEY-WP-0033 - RPF-WP-0044 @@ -183,6 +183,7 @@ id: CUST-WP-0073-T05 status: wait priority: low needs_human: true +decision_id: 1591daa1-6e85-4dfd-aadd-5a9fe1ef47fa blocking_reason: "Deferred by founder decision 2026-09-24; reopened only by the founder on one of the three triggers below, in one attended rotation window." state_hub_task_id: "1b41b532-38a2-5f39-b387-28737934811a" ```