railiance-platform/docs/runbooks/rpf-wp-0044-t04-attended.md
codex 1228cd8407
All checks were successful
CCR intake gate / gate (push) Successful in 2m11s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
RPF-WP-0044-T06: founder cluster route and attended ESO adoption script
KUBECTL_ROUTE (agent default, founder-sudo = ssh railiance01 sudo -n) for the
bounded proof scripts; one attended script with go/no-go gates, typed ADOPT
confirmation, prune/force-off SSA sync and post-checks; evaluator and tests.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 527080@bnt-lap001
Assistant-Session: 5a0e864a-67be-4605-a77a-16635f7dd292
2026-10-21 01:23:16 +02:00

6.5 KiB

RPF-WP-0044-T04 — attended issue-core repository reader (founder runbook)

Authority: D2 (hub decision 89f1058f-33bc-47a8-8a49-0b44d426c67e) authorizes this exact read-only repository reader and the ordered adoption. No further approval is needed. The only founder act is the orange-lane Platform OpenBao OIDC/MFA login that wraps the fixed executor.

State on 2026-10-20 (agent-prepared, no secrets touched)

Prerequisite State Receipt
Host trust [forgejo.coulomb.social]:30022 in argocd-ssh-known-hosts-cm live since 2026-10-11, re-verified docs/evidence/2026-10-11-issue-core-transport/2026-10-20-verify-r1.json (original execute: the-custodian docs/evidence/2026-10-11-issue-core-public-transport/execution.json)
Provider host key = pinned key (ssh-keyscan from railiance01) match this runbook, 2026-10-20
AppProject railiance-tenants admits the exact SSH URL live + in source (argocd/railiance01/bootstrap/01-railiance-tenants-project.yaml) same verify receipt
Sealed executor contract valid, expires 2026-10-27T23:59:59Z docs/evidence/2026-10-11-issue-core-credential/contract-sealed-2026-10-20.json
Contract sha256 1ce9d2fdc39395407a01e358bfd0179f83f35c0a448e6658eb8f5aab351d3d3a
Live known_hosts sha256 (pinned in contract) 7b6114ff6b96c9923d3c6139fdbaec02bb4e1fd93e6c9c9ac5064beb4570c652
Wrapper source to pin rapp-issue-core 186c817b67d3919a64acdddbd3889e539841f946 (Argo owner + ExternalSecret metadata guard)

A 2026-10-20 dry-run returned target_preimage_changed because the change was already applied; that refusal is kept as 2026-10-20-dry-run-r1.json. It is not a failure.

If the contract has expired, or the known_hosts hash changed, the executor refuses (expired_contract, host_pin_changed). An agent then re-seals; the founder does not edit it.

Founder steps (own terminal, TTY + browser)

  1. Tunnel up (agent can do this beforehand): bridge status must show openbao-ui-railiance01 connected; otherwise bridge up openbao-ui-railiance01.

  2. Run, from the repo root, exactly:

cd ~/railiance-platform && git pull --ff-only && \
BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 \
warden access openbao-platform-admin-login --exec -- \
  python3 scripts/provision_argocd_issue_core_repository.py \
  --contract docs/evidence/2026-10-11-issue-core-credential/contract-sealed-2026-10-20.json \
  --contract-sha256 1ce9d2fdc39395407a01e358bfd0179f83f35c0a448e6658eb8f5aab351d3d3a \
  --journal docs/evidence/2026-10-11-issue-core-credential/execution-journal-r1.json

Complete the KeyCape OIDC/MFA in the browser. The executor is silent by design (all child output goes to /dev/null) and itself nests warden access forgejo-admin-api-token --exec.

  1. Read the result, not the exit code (warden exit codes are unreliable):
python3 -c "import json;d=json.load(open('docs/evidence/2026-10-11-issue-core-credential/execution-journal-r1.json'));print(d['state'],d.get('failure'))"
  • delivered_not_adopted None → success. Hand back to the agent.
  • preflight_refused <reason> → nothing was issued. Hand the reason to the agent; it fixes the precondition and seals a new contract; you rerun with a new journal name (-r2).
  • any other state (e.g. uncertain_do_not_replay) → do not rerun. Hand back; the agent reconciles provider key ID / custody / destination first.

The journal contains only IDs, hashes and stage names, never key material.

Cluster route (since 2026-10-21)

After the CUST-WP-0073 cutover the agent SSH login has no kubeconfig. Run the commands below through the founder admin path: prefix each remote kubectl with sudo -n, for example ssh railiance01 "sudo -n kubectl …", and export KUBECTL_ROUTE=founder-sudo for the bounded scripts (argocd_public_transport.py, rapp-issue-core make verify-live, make argocd-pin-drift). The JSON in a -p patch must be escaped as \" inside the single quotes when the whole remote command is in double quotes (see the T06 runbook for the verified form). T04 is done (acd1ade); this section is kept for replays and rollback.

Agent steps after delivered_not_adopted

  1. Commit the journal. Pin the Application: move argocd/railiance01/drafts/issue-core.application.yaml to argocd/railiance01/applications/, set repoURL: ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git and targetRevision: 186c817b67d3919a64acdddbd3889e539841f946, keep no automated block and no finalizer. Commit and push through the normal flow.
  2. make argocd-pin-drift — any DRIFT stops the root sync. The root is currently OutOfSync; if its diff holds more than the issue-core child, apply only the child (kubectl apply --dry-run=server -f <child> then kubectl apply -f <child> on railiance01).
  3. Wait for repo-server to fetch the SSH source (no ComparisonError), then inspect the client-side native diff of the issue-core Application. Stop on any spec change other than Argo tracking metadata.
  4. Manual sync, apply strategy, prune off, force off:
ssh railiance01 "kubectl -n argocd patch application issue-core --type merge -p '{\"operation\":{\"initiatedBy\":{\"username\":\"rpf-wp-0044-t04\"},\"sync\":{\"revision\":\"186c817b67d3919a64acdddbd3889e539841f946\",\"prune\":false,\"syncStrategy\":{\"apply\":{\"force\":false}}}}}'"
  1. Bounded owner verifier, from ~/rapp-issue-core:
make verify-live VERIFY_ARGS="--expected-revision 186c817b67d3919a64acdddbd3889e539841f946 --expected-source-url ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git"

Add --smoke for the authenticated smoke (one controlled issue created and closed). Retain the output as a receipt and update RPF-WP-0044-T04.

Rollback

  • Before Argo adoption: revoke only the journal's provider deploy key ID on coulomb/rapp-issue-core (same Forgejo admin exec lane), remove only Secret argocd/rapp-issue-core-repository, soft-delete only the new custody version at platform/operators/argocd/repositories/rapp-issue-core. Never touch shared policy or other keys.
  • After adoption: restore the previous Application source/revision in Git and manually sync. Direct make rollback in rapp-issue-core is disabled by design.
  • Transport prerequisites: scripts/argocd_public_transport.py --action rollback with the same plan and hash (guarded exact after→before), plus revert of the owner source patches.

Abort owner: railiance-platform (transport/AppProject with railiance-enablement).