railiance-platform/docs/rpf-wp-0015-attended-windows.md
codex dad91e8c44 Route the sender lane's cluster writes through AUDIT_KUBECONFIG too.
Round-10 review (railiance-platform) found that ContainedOperator inherited
an ssh-only kubectl, so an E2 would write OpenBao and then fail its sync,
restart and rollback. Also: a bad AUDIT_KUBECONFIG now leaves window-error
evidence, and the receipt script validates bodies and lets a later
request-changes withdraw an approval.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 236506@bnt-lap001
Assistant-Session: 09087018-91e1-48c5-ab2f-acfbb62c92e4
2026-11-03 15:09:59 +01:00

4.3 KiB

RPF-WP-0015 attended windows — founder checklist

Procedures approved by all owners on 2026-10-14 against review contract 1c08ba7ae064eddde89cdc15d36f0e1c1c372e1ba5c00f09f4b665409aa337a7 (railiance-platform 8cfbf64). Approval covers the procedures only. Each window below still needs its own explicit founder GO; D5 (2fd5849c) authorizes the exercise class, not a specific window. The runbooks are authoritative; this page only orders the human steps.

Before either window

# Item Owner State 2026-10-14
1 Push ops-warden 6e14300 (login output fail-closed fix, accepted in reviews/RPF-WP-0017-ops-warden-reacceptance-2026-10-14.json), then uv tool install --reinstall /home/worsch/ops-warden from that clean checkout founder go, then agent committed locally, not pushed
2 Value-safe retrospective of WARDEN-WP-0036-T02 (2026-09-01 live op ran while the relaxed check was in source) ops-warden / railiance-platform open

T02 — database lease recovery (≤15 min window)

Runbook: docs/audit-core-database-lease-recovery.md.

  1. Pick a window that is not within 20 min of 03:17 UTC (attest-chain CronJob).
  2. Fill an approval receipt from docs/audit-core-database-lease-approval.example.json: approval id, window start/end, named abort operator, owner acknowledgement message ids (audit-core, rapp-postgres, railiance-platform), synthetic load RAILIANCE-WP-0024-T02-SYNTHETIC-01 with driver revision sha256:941ba251… (audit-core 8c8bcf4), and the synthetic_sender block.
  3. Announce two short audit-core restart gaps (projection and cleanup).
  4. In the window: one contained ops-warden login runs the whole sequence — make audit-t02-attended-window (approval receipt, driver path, confirm string, bearer file and evidence dir outside Git). Through scripts/openbao-attended-exec.py it runs lane project (restart #1) → ssh-bounded port-forward → contained T02 exercise → 0600 evidence JSON → lane cleanup with that evidence (restart #2). No token file is used.
  5. Abort: the window script stops the port-forward and runs cleanup --abort-reason itself; if it could not, run make audit-synthetic-sender-cleanup AUDIT_SYNTHETIC_SENDER_ABORT_REASON=... (one more login). Never restart the pod by hand.

T03 — coordinated railiance01 reboot

Runbook: docs/railiance01-coordinated-reboot.md. Additional gates before the window:

# Item Owner
1 Prove provider console / rescue / hard-reset access and file a RAIL01-CONSOLE-<ts> receipt (railiance-infra docs/railiance01-console-access.md, RAIL-HO-WP-0011-T09). Today no out-of-band console is established. founder
2 Remove the stuck PVC platform-pg-drill/platform-pg-drill-1 (pvc-protection finalizer) in a separately approved attended step, or keep it explicitly listed rapp-postgres + founder go
3 Fresh backup or written waiver for state-hub-db, user-engine-pg, net-kingdom-pg, target-revenue-pg (no CNPG backup configured) each DB owner
4 New scenario id and fresh human decision (08-23 decisions/scenario are consumed) founder
5 Fresh encrypted off-host OpenBao snapshot receipt (≤24 h) platform custody, attended
6 2-of-3 Shamir unseal holders present; named abort operator; railiance-infra abort-owner ack founder
7 Pre-reboot preflight run to capture the evidence file (boot id, failing-pod baseline, CNPG identities) agent

Stop immediately, self-revoke and never retry on any unexpected credential output from the attended login.

Cluster access since 2026-10-20

RCLUSTER-WP-0019 removed node-account access to the k3s admin kubeconfig. The preflight, sender lane and window scripts therefore take AUDIT_KUBECONFIG=$HOME/.kube/config-railiance01 for one attended command. Cluster reads and the port-forward then run locally against that file; host reads such as uptime and boot id stay on ssh railiance01. Without the variable the scripts keep the earlier ssh path, which now fails at read node state.

This includes the sender lane's projection and cleanup writes (ExternalSecret sync and audit-core restart). Set the variable on the one command only, never in the shell profile:

AUDIT_KUBECONFIG=$HOME/.kube/config-railiance01 make audit-t02-attended-window AUDIT_T02_MODE=e2 ...