diff --git a/docs/evidence/2026-10-11-issue-core-credential/contract-sealed-2026-10-20.json b/docs/evidence/2026-10-11-issue-core-credential/contract-sealed-2026-10-20.json new file mode 100644 index 0000000..40fc679 --- /dev/null +++ b/docs/evidence/2026-10-11-issue-core-credential/contract-sealed-2026-10-20.json @@ -0,0 +1,19 @@ +{ + "destination": "argocd/rapp-issue-core-repository", + "execution_mode": "attended-founder-bounded", + "expires_at": "2026-10-27T23:59:59+00:00", + "new_network_scope": false, + "openbao_path": "platform/operators/argocd/repositories/rapp-issue-core", + "owner_review_ref": "railiance-platform:docs/evidence/2026-10-11-issue-core-credential/owner-review.json@sha256:8835eafe5b46809d9c57e1d998673e3e01fe03b0b92f61d69e98b94dc8791ab5", + "project": "railiance-tenants", + "read_only": true, + "repository": "coulomb/rapp-issue-core", + "rollback_ref": "railiance-platform:docs/evidence/2026-10-11-issue-core-credential/owner-review.json#rollback; docs/runbooks/rpf-wp-0044-t04-attended.md#rollback", + "runtime_identity_ref": "attended founder Platform OpenBao OIDC/MFA via `warden access openbao-platform-admin-login --exec` enclosing nested `warden access forgejo-admin-api-token --exec`; owner-review.json runtime_authority_limits; D2 89f1058f", + "scope_approval_ref": "89f1058f-33bc-47a8-8a49-0b44d426c67e", + "ssh_egress_existing_proof_ref": "the-custodian:docs/evidence/2026-10-11-issue-core-public-transport/public-authority-observation.json (repository_server_tcp_30022_reachable=true, no new network scope); railiance-platform:docs/evidence/2026-10-11-issue-core-transport/2026-10-20-verify-r1.json (host pin + project admission verified live 2026-10-20)", + "ssh_known_hosts_sha256": "7b6114ff6b96c9923d3c6139fdbaec02bb4e1fd93e6c9c9ac5064beb4570c652", + "url": "ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git", + "work_record": "RPF-WP-0044-T04", + "wrap_ttl_seconds": 60 +} diff --git a/docs/evidence/2026-10-11-issue-core-transport/2026-10-20-dry-run-r1.json b/docs/evidence/2026-10-11-issue-core-transport/2026-10-20-dry-run-r1.json new file mode 100644 index 0000000..c339100 --- /dev/null +++ b/docs/evidence/2026-10-11-issue-core-transport/2026-10-20-dry-run-r1.json @@ -0,0 +1 @@ +{"action": "dry-run", "approval_ref": "89f1058f-33bc-47a8-8a49-0b44d426c67e", "captured_at": "2026-10-20T06:50:49.729226+00:00", "failure": "target_preimage_changed", "mutation_attempted": false, "passed": false, "plan_sha256": "2e3094f4970f600b13b145386eab323f41e344e379a9e8b83282178e387a5920", "resources": [], "schema": "argocd-public-transport-receipt/v1", "secret_or_credential_calls": false, "task": "RPF-WP-0044-T04"} diff --git a/docs/evidence/2026-10-11-issue-core-transport/2026-10-20-verify-r1.json b/docs/evidence/2026-10-11-issue-core-transport/2026-10-20-verify-r1.json new file mode 100644 index 0000000..639793a --- /dev/null +++ b/docs/evidence/2026-10-11-issue-core-transport/2026-10-20-verify-r1.json @@ -0,0 +1 @@ +{"action": "verify", "approval_ref": "89f1058f-33bc-47a8-8a49-0b44d426c67e", "captured_at": "2026-10-20T06:51:26.635213+00:00", "mutation_attempted": false, "passed": true, "plan_sha256": "2e3094f4970f600b13b145386eab323f41e344e379a9e8b83282178e387a5920", "resources": [{"after_sha256": "d581e92dd00161e8624bb3ee9e172f31f103ea9655975aaa0cc3ed32323b1dd2", "before_sha256": "54ecbee860c225158ae45e2bd93cba8b5b0418d27c2b06f8f1487b1c7453a8da", "field": "/data/ssh_known_hosts", "kind": "configmap", "name": "argocd-ssh-known-hosts-cm", "uid": "e1481984-dc5d-4fcc-9f2a-118c054865b7", "verified": true}, {"after_sha256": "d07d4296f3cb0c726dd30ea2c908982f197a7aaaa48862560e3776960e4fac5d", "before_sha256": "636ee06479d4be73d956cdbeb9d4bddb24cd463bbbb70de10b8cfd043791eb31", "field": "/spec/sourceRepos", "kind": "appproject", "name": "railiance-tenants", "uid": "f899f3ec-2c55-4cd0-9cb0-b2b4c6eb9be2", "verified": true}], "schema": "argocd-public-transport-receipt/v1", "secret_or_credential_calls": false, "task": "RPF-WP-0044-T04"} diff --git a/docs/runbooks/rpf-wp-0044-t04-attended.md b/docs/runbooks/rpf-wp-0044-t04-attended.md new file mode 100644 index 0000000..1ce8446 --- /dev/null +++ b/docs/runbooks/rpf-wp-0044-t04-attended.md @@ -0,0 +1,99 @@ +# 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) + +0. Tunnel up (agent can do this beforehand): `bridge status` must show `openbao-ui-railiance01 connected`; + otherwise `bridge up openbao-ui-railiance01`. + +1. Run, from the repo root, exactly: + +```bash +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`. + +2. Read the result, not the exit code (warden exit codes are unreliable): + +```bash +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 ` → 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. + +## 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 ` then `kubectl apply -f ` 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: + +```bash +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}}}}}' +``` + +5. Bounded owner verifier, from `~/rapp-issue-core`: + +```bash +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). diff --git a/workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md b/workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md index 99b7360..d4d1031 100644 --- a/workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md +++ b/workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md @@ -271,6 +271,7 @@ id: RPF-WP-0044-T04 status: wait needs_human: true intervention_note: "Orange attended Platform OpenBao OIDC/MFA login for the already D2-approved exact repository reader; no second source-scope approval." +blocking_reason: "Only the founder attended Platform OpenBao OIDC/MFA login running the fixed executor remains; runbook docs/runbooks/rpf-wp-0044-t04-attended.md." decision_id: 89f1058f-33bc-47a8-8a49-0b44d426c67e priority: high state_hub_task_id: "0e619658-0453-51ed-b9a0-bed28b5544fd" @@ -282,6 +283,8 @@ Source preparation now disables wrapper direct deployment/rollback and verifies Public host trust and exact project admission are prepared in owner source and the bounded `scripts/argocd_public_transport.py`; its server dry-run passed. Preserve each exact attempt and any partial failure. Finish those prerequisites, seal the owner-reviewed contract, use the attended login, then pin the newly committed wrapper source in the Application, inspect client-side native diff, manually sync with prune/force disabled, and run the bounded owner verifier. Image releases and rollback use Git revisions plus Argo; direct `make rollback` is disabled. Never adopt the stale wrapper revision that predates the ExternalSecret metadata guard. +2026-10-20 (CUST-WP-0079-T06 attended-window prep, agent): prerequisites done. Host trust and exact project admission were executed 2026-10-11 (the-custodian `docs/evidence/2026-10-11-issue-core-public-transport/execution.json`); a fresh dry-run refused with `target_preimage_changed` (already applied, kept as `docs/evidence/2026-10-11-issue-core-transport/2026-10-20-dry-run-r1.json`) and `--action verify` passed (`2026-10-20-verify-r1.json`). ssh-keyscan from railiance01 matches the pinned provider key. Sealed contract `docs/evidence/2026-10-11-issue-core-credential/contract-sealed-2026-10-20.json` (sha256 `1ce9d2fdc39395407a01e358bfd0179f83f35c0a448e6658eb8f5aab351d3d3a`, expires 2026-10-27) passes the executor's `validate_contract`; 17 executor/transport tests pass. Wrapper pin target is rapp-issue-core `186c817b67d3919a64acdddbd3889e539841f946`. The only remaining step is the founder's attended login running the executor; exact commands and the agent follow-on (pin, diff, manual sync, verifier) are in `docs/runbooks/rpf-wp-0044-t04-attended.md`. No secret, credential or OpenBao call was made. + ## Adopt target-revenue ```task