T04 was the last open task, waiting on key-cape to accept or refuse ownership of the coding-agent OpenBao issuance identity. They accepted, in KEY-WP-0009-T03, on 2026-08-23: codex-railiance-platform is published in their config/service-clients.example.yaml with subject service:codex:railiance-platform, role coding-agent, scope openbao:login, 15m lifetime, and the service-auth semantics in docs/openbao-service-auth-contract.md. The split is the one we routed for — KeyCape issues, railiance-platform binds the OpenBao role, OpenBao enforces, no secret value in either repo. We found it by reading their repository. KEY-WP-0009-T04 records replying to ops-warden; the inbox has zero messages from key-cape, read or unread. The task sat `wait` on an answer that already existed. That is T05's own lesson arriving on T04: a blocker is a claim about the world at a date. So the same pass re-verified the two lanes pointing at key-cape against their source instead of bumping dates: - rapp-qonto-keycape-client -> verified: source-read. KEY-WP-0009-T02 did add bounded service-auth, but that is client_credentials JWT issuance for OpenBao machine login and does not front this client_secret_basic exchange or its rotation. Blocker stands, now with evidence rather than memory. - key-cape-oidc-login -> asked of key-cape today, which the entry had recorded as still outstanding since 2026-08-21. Also cleared the inbox that hid this: 9 stale unread, all superseded by shipped work, with late closes sent to secrets-engine and llm-connect on the two threads that had asked ops-warden something and never got an answer. 391 tests pass, ruff clean, boundary coverage 0 uncovered. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ Assistant: claude-code Assistant-Model: opus Assistant-Process: 4014535@bnt-lap001 Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
17 KiB
| id | type | title | domain | repo | status | owner | topic_slug | planning_priority | depends_on_workplans | created | updated | state_hub_workstream_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| WARDEN-WP-0033 | workplan | Native lane handoff — review secrets-engine's catalog admission, and fix what it exposed | infotech | ops-warden | finished | ops-warden | netkingdom | P1 |
|
2026-08-21 | 2026-08-28 | 4627d89b-4b00-562a-81e9-76e96f90fa7e |
WARDEN-WP-0033 — Native lane handoff
On 2026-08-20 secrets-engine accepted five of ops-warden's seven interim
proxy lanes for catalog admission (SECRETS-WP-0006, decision
ae676382-1826-4e04-aa4e-bb77990c7a0d), rejected two with reasons ops-warden
agrees with, drafted the five entries itself rather than waiting for the offered
contribution, and asked for a line-by-line review of the non-secret metadata.
In the same hour railiance-platform closed the RISK-F-0009 coverage gap and
asked ops-warden for two things back.
This workplan is the response to both, plus the defect the review turned up in ops-warden's own grading model — which is the most consequential item here and would not have been found without the second pair of eyes.
Why a workplan and not an adhoc
Four counterparties are waiting, one deliverable is a cross-repo interface
another repo will consume on a schedule, and the review carries approval
semantics — secrets-engine holds interim proxy ownership open until each lane
has approved native verification. The convention reserves adhocs for low-risk
work completed directly; this is none of those.
Tasks
id: WARDEN-WP-0033-T01
status: done
priority: high
state_hub_task_id: "154f2f03-387d-5fe6-a0f5-1929c46a2bd8"
Review the five drafted catalog entries and reply.
issue-core-ingestion-api-key, reuse-surface-hub-write-token,
openrouter-llm-connect, forgejo-admin-api-token,
email-connect-transactional at secrets-engine@784be97.
Review the axes they asked for: owner-repo coordinates, field grouping, workload
consumers, rotation/deactivation owners, delivery intent. Verify claims against
the authoritative railiance-platform CCRs — never against a secret read;
bao kv get on any of these paths is the 2026-07-16 vector and three of the five
are risk: high.
Accept their two rejections. openbao-api-key is a routing template rather than
one lane and key-cape-oidc-login belongs to key-cape — that is ADR-0005
applied to ops-warden by someone else, correctly.
id: WARDEN-WP-0033-T02
status: done
priority: high
state_hub_task_id: "6996d07f-63bb-5708-a171-68c4b1bbddde"
Correct ops-warden's per-path risk grading — the defect T01 exposed.
secrets-engine graded issue-core-ingestion-api-key high; ops-warden grades
it standard, and deliberately: WP-0032-T05 regraded it down on 2026-08-19,
operator-sanctioned, because test_high_risk_lanes_classified asserted standard
and was judged right — "ordinary internal workload secrets are standard".
That reasoning was incomplete, and CCR-2026-0002 says so explicitly: the path
carries both ISSUE_CORE_API_KEY and GITEA_BACKEND_TOKEN, a Forgejo
backend token, and the CCR records keeping both as a deliberate field-set
decision.
The root cause is structural, not a single bad call. ops-warden grades a
lane by its headline field — the catalog carries one fetch_command naming one
field and no fields list at all — but the disclosure unit is the path: a
bao kv get returns every field stored there. So a lane can be graded on its
least dangerous contents. ADR-0007 says every lane carries an explicit grade;
it does not say the grade must cover everything a read of that path would
disclose, and it should.
Fix the grade, then fix the model that produced it: record fields per lane and
grade on the union. Check the other 25 lanes for the same shape.
Done 2026-08-21 — and it was two lanes, not one. While verifying
reuse-surface-hub-write-token I told secrets-engine their second field was
unevidenced and asked them to confirm it. It was evidenced: CCR-2026-0005's
kv_path block lists both fields and its notes describe the HMAC's alignment
with Forgejo org webhook id=1. A truncated grep, and a retraction sent within
twenty minutes so they would not spend time on it. That lane was under-graded on
exactly the same reasoning, and both had been regraded down in the same T05
pass — which is what makes this a systematic flaw rather than one bad call.
Blast radius checked and bounded: of the 8 remaining standard lanes, 6 have no
KV path at all (SSH, policy check, tunnel, principals, issue-sink, key-cape
login) so nothing is disclosed by a read. Two do have paths and no CCR field
evidence — rein-openweights-openrouter-approle and coulomb-social-runtime-env
(a whole k8s env Secret, which by shape almost certainly holds several fields).
Deliberately not regraded: ADR-0008 §3 says an unknown field set is stated
rather than assumed, and grading is operator-sanctioned judgement, not backfill.
They are the open item on this task.
Shipped: both regrades with their evidence and the superseded reasoning kept
inline, fields recorded with its CCR source, the test that had been holding the
wrong answer inverted with an explanation of why it was wrong to trust it, and
ADR-0008 — a lane's grade covers every field its path discloses. That is a
new binding rule, so it is a record rather than a wiki note.
id: WARDEN-WP-0033-T03
status: done
priority: high
state_hub_task_id: "a736f983-94da-5a4a-aaf9-5114485518a6"
Emit the generated high-risk data-path artifact for railiance-platform.
They asked for a versioned artifact of concrete high-risk data paths
(id + data_path + catalog revision) to consume instead of hand-maintaining
the deny list — the half of the RISK-F-0009 fix ops-warden explicitly declined
to build for them. Emitting the artifact is not the same as amending their
policy: they still own what to deny. That boundary is the point of ADR-0002
and must survive this task.
Must be generated, never hand-edited, and must carry the catalog revision so a consumer can tell what it was derived from. Depends on T02 — publishing the deny set before fixing the grades would ship the wrong list to a consumer who will apply it.
Done 2026-08-21. scripts/emit_high_risk_paths.py →
registry/generated/high-risk-data-paths.yaml: 19 high-risk lanes, 14 concrete
data paths, 5 with no single KV address listed separately so a consumer does not
read the absence as an omission. Carries catalog_revision, its date, and a
catalog_dirty flag — a revision that does not describe the file it came from is
worse than none.
The T02 dependency was not theoretical. The two regrades land in this artifact,
and check_agent_read_boundary.py now reports 2 uncovered against a policy
railiance-platform closed to 0 yesterday. Emitting before regrading would have
handed them a list that confirmed a coverage claim that had just stopped being
true.
fields is emitted as null where no CCR declares the set, never as a
single-element guess — ADR-0008 §3. Two CI tests: the artifact must be current,
and every high-risk lane must appear in it, so a lane graded high after the last
emit cannot silently fail to reach the consumer.
Boundary held: the header states this is an input and not a policy, and that
railiance-platform may deny more, deny less, or dispute a grade (ADR-0002).
id: WARDEN-WP-0033-T04
status: done
priority: medium
state_hub_task_id: "5acac140-a586-5db3-b231-bbf236710786"
Route the coding-agent issuance identity question.
RAILIANCE-WP-0017 is blocked on defining a distinct coding-agent issuance
identity and proving deny-wins when that identity is combined with workload read.
They asked ops-warden to route ownership.
Route it; do not absorb it (ADR-0005, ADR-0003). ops-warden owns actor
identity for adm/agt/atm SSH certificates and nothing else — a coding
agent's OpenBao issuance identity is an IAM question. The likely owner is
key-cape, with user-engine and zone-engine both plausibly involved. Say so
with reasoning rather than guessing, and record the answer either way.
Note the interaction with ADR-0004: the agent read-boundary already depends on
WARDEN_AGENT_ID being set, which is an honour-system marker on the ops-warden
side. A real issuance identity is what would make that boundary hold on the
OpenBao side too, so ops-warden is an interested consumer, not a bystander.
Routed 2026-08-21 to key-cape (msg 903b2223); waiting on accept or refuse.
Reasoning given: it is an identity and issuance question about a principal
authenticating to OpenBao, which is key-cape/Keycloak's. The precedent is an hour
old and runs the same direction — secrets-engine declined key-cape-oidc-login
as ops-warden's to hand them, on the grounds that login and identity-token
issuance stay with key-cape. Absorbing this would contradict agreeing with them.
Named the adjacent parties explicitly rather than leaving them to inference:
zone-engine has an interest (a coding-agent identity is a strong candidate zone
subject) and user-engine is not involved — this is a machine principal, not
an end-user account. Stated so nobody concludes it by elimination.
Asked for a refusal-with-pointer as an equally good answer. The failure mode to
avoid is the 2026-08-17 one recorded in .claude/rules/finding-routing.md:
ops-warden answered a question well and never routed it, and another repo ended
up filing it.
Followed up 2026-08-23 after the immediate enforcement gap closed.
RAILIANCE-WP-0022 no longer waits for this ownership decision: the platform
owner deployed a dedicated coding-agent AppRole, proved deny-wins when it is
combined with workload read, and identified an exact-bound KeyCape JWT role as
the migration target. That makes the remaining question narrower and more
important rather than obsolete: who owns issuance of the durable
KeyCape/Keycloak-backed machine identity?
Direct follow-up d25d4604-5713-42a8-8e3a-1ea31b5a5cc7 asks key-cape to
accept that target identity with an authoritative workplan/interface, or refuse
and name the actual owner. T04 remains wait until one of those two answers is
recorded; the live AppRole is operational evidence, not an ownership answer.
Answered — accepted. Closed 2026-08-28. key-cape accepted issuance
ownership in KEY-WP-0009-T03 (status: done, 2026-08-23): the non-secret static
registration codex-railiance-platform is published in
key-cape/config/service-clients.example.yaml — subject
service:codex:railiance-platform, tenant tenant:coulomb, role coding-agent,
scope openbao:login, client_credentials, 15-minute lifetime — with the
service-auth claims, renewal, expiry and failure semantics in
key-cape/docs/openbao-service-auth-contract.md (T02). The split is exactly the
one the routing asked for: KeyCape owns JWT issuance and client disablement,
railiance-platform owns the exact-bound OpenBao role and policy, OpenBao owns
enforcement, and no secret value enters either repository.
The answer was found by reading their repo, not by receiving it.
KEY-WP-0009-T04 records replying to ops-warden; no such message exists in the
ops-warden inbox — 0 messages from key-cape, read or unread. The acceptance had
been sitting done for five days while this task sat wait on it.
That is the T05 lesson landing on T04: a blocker is a claim about the world at a
date, and this one had stopped being true. verified: source-read is doing real
work here — it is the difference between "we asked" and "we checked". The
mechanism is right; what it needs is for someone to run it, which is why the
lanes below were re-verified in the same pass rather than date-bumped.
Consequence for ADR-0004: the honour-system WARDEN_AGENT_ID marker now has a
real issuance identity behind it on the OpenBao side. ops-warden remains a
consumer of that identity and does not own it.
id: WARDEN-WP-0033-T05
status: done
priority: medium
state_hub_task_id: "75051d17-399b-5129-860b-ae00dae91c47"
Make blocker staleness a mechanism instead of an intention.
Four stale blockers surfaced in twelve hours: an OpenBao token recorded expired
that was valid, a verification script recorded ready that had never been written,
a ten-day secrets-engine question answerable from their source, and
FLEX-WP-0007 cited as blocking policy.enabled seven weeks after it read
finished. .claude/rules/finding-routing.md has said re-read a blocker before
trusting it since RISK-F-0001. Saying it has not worked.
warden route gaps had a --stale-days threshold defaulting to 90, which was
not loose but inert — the register was created 2026-08-15, so it could not
fire before November.
Done 2026-08-21. Two changes, and the second matters more:
-
Split the cadences.
DEFAULT_STALE_DAYS(90) still governs pointer freshness — "is this the right owner and page" genuinely is quarterly. NewDEFAULT_BLOCKER_STALE_DAYS(14) governs interim blockers, calibrated on the cases that cost something: ten days for the secrets-engine lanes, one day forRISK-F-0001, ~50 forFLEX-WP-0007. At ~15 lanes it surfaces about one a day rather than a wall, and it fires on zero lanes on age today.Then scaled by risk, after risk-nexus answered. They accepted the offer to converge and published their convention: 14 days critical/high, 30 medium, 60 low, with fix state read from the owning repo rather than remembered. Their framing — "point
warden route gapsat those windows and the two will agree without either of us building a shared mechanism" — is better than a joint tool, soblocker_stale_days()now maps laneriskonto exactly those windows.ungradedtakes the shortest, not the longest:ADR-0007makes an absent grade a defect, so its blocker is the least trustworthy of all. -
verified:distinguishes re-checking from re-editing.reviewedrecords when someone touched the entry; nothing recorded whether the claim was re-established.owner-confirmedandsource-readcount;asked-and-waitingandunverifieddo not, and a lane in those states is stale regardless of its date.key-cape-oidc-loginis the proof: asked today, zero days old, correctly flagged.
Current state: 14 non-draft interim lanes — 5 owner-confirmed, 1
asked-and-waiting, 8 unverified. The 8 are honest; they were carried forward
this session without a check and now say so instead of hiding behind a fresh date.
--fail-on-stale exits 3 so a cron job or gate can act. Deliberately not a CI
test on age: a date-triggered failure breaks the build on a calendar day with
no code change, punishing whoever commits next rather than whoever owns the
blocker. The CI test is structural instead — every interim lane must record
how it was verified, which fails on the commit that introduces the omission.
id: WARDEN-WP-0033-T06
status: done
priority: high
state_hub_task_id: "94f77f5a-f919-5328-832c-ba1d24c6431b"
Correct first-time OpenBao administration routing. rapp-postgres reported
on 2026-08-22 that warden plan mapped first-time
database/config/platform-pg-2 administration to the generic
openbao-api-key template. It consequently proposed paste-once KV provisioning
and a workload OIDC role, neither of which can configure database connections,
policies, auth roles, or token roles. Their Desk session stopped without an
approval or secret action.
The authoritative platform runbook and rapp-postgres's live T04 evidence agree
on the missing distinction: this is one attended KeyCape-backed OpenBao identity
act at auth mount netkingdom, role platform-admin. It is not a credential
value handoff. Root stays offline break-glass authority and a workload role must
never be widened to make the operation pass.
Add an exact openbao-platform-admin-login lane, an operator playbook, and a
regression that makes the reported request resolve to founder_required with
oidc_login — never paste_once_provision. Verify the route, then return the
corrected non-secret command to rapp-postgres.
Done 2026-08-22. The new active lane resolves the exact reported request at
score 20, ahead of the generic KV template at 11, and returns one
founder_required act:
bao login -no-print -method=oidc -path=netkingdom role=platform-admin.
Planner output offers only warden access openbao-platform-admin-login --fetch
and the exact owner command; login lanes no longer inherit secret-value
transports (--exec, --out, --wrap). The lane is explicitly a high-risk,
non-workload human identity act, so the generated boundary artifact lists it as
having no KV address rather than inventing one.
Verification: 384 tests pass, Ruff passes, workload accounting resolves all 28 lanes (3 resolved, 17 unknown, 8 not-applicable), and the boundary invariant reports 20 high-risk lanes, 14 concrete paths covered, 6 non-KV/pattern lanes, 0 uncovered. No login or credential action was performed.
Related
secrets-engineSECRETS-WP-0006— catalog admission, decisionae676382RISK-F-0009— closed by railiance-platform 2026-08-21; 0 uncoveredrailiance-platformRAILIANCE-WP-0022(boundary coverage),RAILIANCE-WP-0017ADR-0002,ADR-0003,ADR-0004,ADR-0005,ADR-0007WARDEN-WP-0030— the delegation register these five lanes retire from