Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013EPuTc18FjU5WFqoSEKH3C Assistant: claude-code Assistant-Model: opus Assistant-Process: 1276224@bnt-lap001 Assistant-Session: 426ec497-e1c4-4dd3-b417-dfce1ca1dbc3
3 KiB
| id | type | title | domain | repo | status | owner | topic_slug | planning_priority | depends_on_workplans | created | updated | state_hub_workstream_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| WARDEN-WP-0038 | workplan | warden plan must distinguish reading a secret from mutating one | infotech | ops-warden | proposed | ops-warden | netkingdom | P1 |
|
2026-09-08 | 2026-09-08 | 751ad530-e44b-52c4-b70e-cb47568a0179 |
WARDEN-WP-0038 — Read versus mutate intent in the policy front door
The defect
warden plan scores a need against catalog lanes by keyword overlap and returns
a verdict. It has no notion of what the caller wants to do. So a need that
says generate a successor secret and CAS-write it to two custodians matches the
lane that reads that path, scores well on the shared nouns, and returns:
verdict: autonomous
commands: warden access <lane> --exec / --out / --wrap
Three read transports offered as the answer to a write, under the verdict that
means "proceed without the founder". Reproduced 2026-09-08 against
rapp-qonto-keycape-client (ADHOC-2026-09-08-T04).
Why this is worse than a bad suggestion
warden plan is the documented first step before drafting any founder credential
step (.claude/rules/credential-routing.md), and autonomous is consumed as an
authorization signal by agents that have no other check. WARDEN-WP-0029 shipped
the verdict because instinct was not auditable; a verdict that is confidently
wrong in the permissive direction is worse than no verdict.
key-cape hit this and refused to rely on it — "we are not treating a generic match as authorization" — which is the only reason it surfaced as a design question rather than as an unadmitted custody mutation. The control that caught it was a counterparty's caution. That is not a control.
WARDEN-WP-0033-T06 is the same shape (rapp-postgres, generic
openbao-api-key match → paste_once_provision for an act that could not work)
and was fixed by adding one exact lane plus one regression. That fixed the
instance. This is the class.
Shape of the fix (to be designed, not assumed)
- Classify need intent — read / mutate / establish — before scoring, and never answer a mutate need with a read lane's transports.
- A mutate need against a lane ops-warden does not own is
unroutablewith a CCR stub naming the custody owner, notautonomous.ADR-0003: cover gaps, never silently own them; a permissive verdict on someone else's custody act is a silent claim of ownership. - Consider whether
rotation.stepsshould be reachable fromplanat all, given they are advisory prose and several are explicitly not automatable. - Regression from the reproduced case, in the manner of T06.
Open question for design
Whether intent belongs in the matcher or in the lane. A lane could declare which
acts it admits (read, rotate, provision) and plan could refuse any act a
lane does not declare — stricter, and it fails closed on lanes that say nothing,
which is the majority today. That is a catalog schema change and needs its own
argument.