Layer declaration (gate-house). INTENT.md now carries the declaration in its own voice with layer.yaml as the machine-readable form, adapted from ops-warden's reference. railiance-platform is Staff: operating OpenBao is not a claim to the Tooling layer, because §4 is explicit that no operator-of-third-party-Tooling shape exists and that someone running it stays a declared gap. Six direct Tooling contacts are mapped by capability rather than by file — one §5.2 conduit, one §5.1 diagnostic, four §5.3 gaps with intended owners and review dates — and the uncatalogued contacts are listed so the check is total. We are PEP-shaped and the unreachable-engine stance map is NOT published; that is recorded as an open obligation to build against v0.8, not left silent. Placement admission. canned-prompts was added as a PostgresConsumer on platform-pg-2 in rapp-postgres 1b68b4c without a placement owner here, which is exactly the cross-repo drift the assurance check exists to catch; the check had been failing on it. Registered with its real boundary evidence, corrected the stale test expectation that pinned the overflow cell at one consumer, and updated the SCOPE occupancy line to 2/4. Also records owner input received today: key-cape's issuer view on CCR-2026-0020's presenting actor, and their confirmation that codex-railiance-platform correctly stays tenant:coulomb, so the flagged T02 discrepancy is closed as not-a-defect. The whynot-design npm field is NOT changed. Two dated live receipts here name NPM_AUTH_TOKEN as the field, including an attended founder fetch; that is recorded against the counterparty claim rather than either side being flipped before the session settles it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WLUjpv3ssxNRAEPPgLFnEB Assistant: claude-code Assistant-Model: opus Assistant-Process: 1275505@bnt-lap001 Assistant-Session: 97265baa-f08f-4032-b290-a1e2965a69c5
6.5 KiB
Attended OpenBao session — four open custody questions
One founder-attended session that settles the questions currently blocking four owner threads. Everything in it is read-only against OpenBao. It provisions nothing, approves nothing, and rotates nothing.
Prepared 2026-09-09 under RPF-WP-0035. Not yet run.
Why a session rather than a reply
Four owner threads are each blocked on a fact that only an authenticated read can establish, and each has been answered so far with "I will not guess":
| Question | Thread | What is undecidable from repo source |
|---|---|---|
| Q1 | secrets-engine 546403e4 |
Whether the legacy path secret/coulomb/whynot-design/npm/publish still exists and holds a real token |
| Q2 | secrets-engine 546403e4, ops-warden b6212006 |
Which field backs the authoritative npm lane. Two dated live receipts here name NPM_AUTH_TOKEN; secrets-engine says npm_token and ops-warden has already changed their catalog to it. Both can be true if the path carries both fields. Field names are not visible in KV v2 metadata |
| Q3 | internal | The 2026-09-09 activation receipt records policy_applied: false for both KeyCape approval lanes while role_applied: true. Reads verified, so the policies must exist — but existence and repo agreement were never confirmed |
| Q4 | CCR-2026-0019 | Which netkingdom OIDC roles and bound group claims already exist, as input to the operator group claim that lane is missing |
| Q5 | risk-nexus ee702ac9 |
Which fields the governed backup lane actually carries, as RPF-WP-0029-T02 context |
Authority and containment
Authority is the governed openbao-platform-admin-login lane: founder_required,
attended OIDC through bao login -method=oidc -path=netkingdom role=platform-admin.
The owner command is never run directly.
scripts/openbao-attended-exec.py -- \
/usr/bin/python3 /home/worsch/railiance-platform/scripts/openbao_open_questions_session.py \
--receipt /tmp/<new-unique-name>.json
scripts/openbao-attended-exec.py supplies the WSL browser launcher and then
execs into warden access openbao-platform-admin-login --exec, so Warden keeps
the envelope: it captures both streams, owns the temporary token helper and
self-revokes when the command returns. Use a receipt path that does not exist —
the writer opens it O_EXCL at mode 0600 and refuses to overwrite.
The runner prints nothing. Its entire output is the receipt.
What the runner reads, and the one honest caveat
| Step | Call | Emitted |
|---|---|---|
| Q1 | secrets list, then kv metadata get on the legacy path if the mount exists |
mount present, path present, current version, created/updated time |
| Q2 | kv get on platform/workloads/coulomb/whynot-design/npm-publish |
sorted field names only, plus KV version |
| Q3 | policy read for both KeyCape approval policies |
present, matches-repo-source, sha256 of each normalized text |
| Q4 | list auth/netkingdom/role, then read each |
role names, bound claims, groups/user claim, token policies, TTL |
| Q5 | kv get on platform/workloads/railiance/backup/offsite-lane |
sorted field names only, plus KV version |
The caveat, stated plainly: Q2 and Q5 are data reads. Field names cannot be
obtained from KV v2 metadata, so the value transits the runner's memory. It is
never printed, never passed on argv, never written to disk, and never placed in
the receipt — field_names() returns key names and the values go out of scope
with the function. If that is not acceptable for the backup lane in particular,
drop Q5: it is context for RISK-F-0010, not a dependency of it.
For Q5 the receipt records predecessor_material_recorded: false, and no value,
fingerprint, length or shape of any predecessor credential is captured — which is
the constraint risk-nexus set.
What each answer unblocks
- Q1 + Q2 → secrets-engine and ops-warden. Q2 is now the more urgent of the
two. ops-warden changed their catalog and playbook from
NPM_AUTH_TOKENtonpm_tokenon secrets-engine's statement, while this repository holds two dated live receipts — including an attended founder fetch that exited zero — namingNPM_AUTH_TOKENas the field. If those receipts are right, that change points the front door at a field that does not exist and the lane breaks on next use. Q2 enumerates the real field names:npm_tokenonly,NPM_AUTH_TOKENonly, or both, and each outcome names exactly one side that has to move, as a reviewed lane change carrying its own approval. If Q1 finds a populated legacy path, that is a stale duplicate holding a real token and becomes its own disposition item — do not delete it inside this session. - Q3 → internal. Either the policies match the repo, and the activation's
policy_applied: falsemeant "no change needed", or they drift and that is a finding to fix under RPF-WP-0035 before anyone treats the verifier lanes as clean. - Q4 → CCR-2026-0019. Existing bound claims show what the estate already uses for operator lanes. This is input, not confirmation — the authorized group claim is NetKingdom's and KeyCape's to state, and the receipt says so in-line so a later reader cannot mistake the listing for an approval.
- Q5 → risk-nexus. Confirms the governed lane is populated with the expected field names, supporting the fail-closed argument already made on that thread.
Explicitly out of scope
- The rapp-qonto KeyCape client rotation (ops-warden
c1aafba4). It is a two-custodian CAS write with a service restart and needs its own reviewed request first. Do not fold it into a read-only session because the operator happens to be authenticated. - Predecessor share invalidation for RPF-WP-0029-T02. That is a provider-side action in the Nextcloud UI, not an OpenBao operation, and it needs the provider owner. It can share the same sitting, but it is a separate step with a separate receipt.
- Any write, seed, rotation or policy apply. The runner contains no mutating verb; if a question turns out to need one, it comes back as a request.
- Client-side reads for the approval clients. CCR-2026-0019/0020 remain in_flight; this session does not advance them beyond Q4's input.
After the session
- Store the receipt under
docs/evidence/with the run date, values absent. - Reply to secrets-engine (Q1/Q2), risk-nexus (Q5) and, if Q3 drifts, record the finding against RPF-WP-0035.
- If Q1 finds a populated legacy path, open a disposition item for it rather than acting on it in the moment.