diff --git a/canon/standards/build-mode-change-authorization_v0.1.md b/canon/standards/build-mode-change-authorization_v0.1.md new file mode 100644 index 00000000..d3bdfc8e --- /dev/null +++ b/canon/standards/build-mode-change-authorization_v0.1.md @@ -0,0 +1,86 @@ +--- +id: canon-build-mode-change-authorization +type: standard +title: "Build-Mode Change Authorization v0.1" +domain: custodian +status: accepted +version: "0.1" +owner: the-custodian +revision: "accepted-1" +last_reviewed: "2026-10-11" +review_interval: 3m +created: "2026-10-11" +updated: "2026-10-11" +scope: fleet +expires_on: production-close-down +related_workplans: + - CUST-WP-0079 +--- + +# Build-Mode Change Authorization v0.1 + +> Decided by the founder on 2026-10-11 (hub decisions 877c268b, 0d6792b6, e071b34e, ab85ae8a; record +> `docs/decisions/2026-10-11-security-unblock-decisions.md`). This is a **raising-autonomy decision** +> under `autonomy-lanes_v0.1.md`, scoped to build mode. It ends at production close-down, when the +> re-arm list below is applied. + +## The rule + +A live change on Railiance infrastructure is **blue-lane** (reversible execution, logged, no +founder go) when it meets **all** of these conditions: + +1. it has a reviewed diff or dry-run; +2. it has a declared rollback; +3. it names an abort owner; +4. it emits a receipt (a machine-readable evidence file linked from the task). + +A conditional approval executes as soon as its listed evidence exists. Nobody asks the founder again. + +The following stay **red-lane** (founder-gated; agents prepare one package): + +- destructive deletion of data or hosts; +- changes to access or secret policy **scope** (who can read or do what). Removing access is not + a scope expansion; +- new or raised spend ceilings; +- public publication. + +Live acts that need the founder's own identity, MFA factor or platform-admin login are **orange-lane**. +They are batched into the attended window (`docs/attended-window/`), never asked one at a time. + +## Machine-checkable form + +```yaml +rule: build-mode-change-authorization +version: 0.1 +applies_while: build-mode +blue_lane_requires: # every field must be present on the change record + - diff_ref # path or commit of reviewed diff / dry-run output + - rollback # command or procedure reference + - abort_owner # repo or agent name + - receipt_path # where the execution receipt is written +red_lane_categories: + - destructive-deletion + - access-scope-expansion + - secret-scope-expansion + - spend-ceiling + - public-publication +orange_lane_categories: + - founder-identity-act + - platform-admin-login +``` + +A checker returns `blue` if no red or orange category is declared and all `blue_lane_requires` +fields are present. It returns the highest declared lane otherwise. A change record that lacks +the fields is not red. It is incomplete, and the owner completes it. + +## Re-arm at production close-down + +- Narrow the blue lane to the production change process (change window, second reviewer). +- Split OpenBao unseal and recovery to a quorum with a second holder, and formalize break-glass (D3). +- Re-evaluate the single-node / shared-control-plane risk before the first customer (D5). + +## References + +- `autonomy-lanes_v0.1.md`: lane vocabulary and the raising-autonomy rule +- `task-wait-qualifiers_v0.1.md`: a lane-blue change never needs `needs_human: true` +- `docs/decisions/2026-10-11-security-unblock-decisions.md` diff --git a/docs/attended-window/2026-10-11-checklist.md b/docs/attended-window/2026-10-11-checklist.md new file mode 100644 index 00000000..3b994c29 --- /dev/null +++ b/docs/attended-window/2026-10-11-checklist.md @@ -0,0 +1,48 @@ +# Attended window checklist — generated 2026-10-11 + +Regenerate at any time with: + +```bash +python3 ~/the-custodian/scripts/security_flow_report.py # see the ATTENDED section +``` + +Under the standing rules of 2026-10-11 (`docs/decisions/2026-10-11-security-unblock-decisions.md`), +everything below is **already authorized**. The window is for acts that need *you physically*: +your real identity or MFA factor, your platform-admin login, or one of the few remaining +founder-gated choices. Budget: about 2 hours. Order: A → B → C. Each item ends with a receipt +that the owner agent picks up. You do not write evidence yourself. + +**Prerequisites:** `bridge status` is green. OpenBao admin login works +(`warden access openbao-platform-admin-login --exec`, `BAO_ADDR=http://127.0.0.1:18200`; see memory +`reference_openbao_admin_login`). Have your phone or passkey ready for MFA. + +## A. Only you, as a real person (≈45 min) + +| # | Task | What you do | +|---|---|---| +| A1 | USER-WP-0027-T04, USER-WP-0028-T03 | On users.coulomb.social: run MFA journeys U05–U08 (enroll, cancel, replace, lost-factor recovery, fresh login) and P04–P06 with your real factor. Note anything odd. Findings become defects, not decisions. | +| A2 | USER-WP-0026-T03 | Sign in and confirm your account shows your real application access (the "signed-in account projection"). | +| A3 | FLEX-WP-0027-T03 (decision `e1868a8d`) | Sign in with your KeyCape account and fresh MFA, review the three pinned T03 memos, and acknowledge them in the native service. | + +## B. Your platform-admin login (≈45 min). Agents prepared the commands + +| # | Task | What you do | +|---|---|---| +| B1 | RPF-WP-0043-T03, RPF-WP-0044-T08 | Read-only: `helm history` / `kubectl diff` for policy-nexus, and a look at coulombcore's ArgoCD. Paste the output into the task's evidence path. | +| B2 | RPF-WP-0027-T03 / -T06 | Run the packaged KeyCape resolver sequence (one receipt-producing command, if NetKingdom has published it; otherwise skip) and publish the non-secret routing receipt. | +| B3 | SECRETS-WP-0006-T05 | Apply only the lanes whose scoped apply command is published (standing rule D1). Skip the rest. | +| B4 | RPF-WP-0035-T10 | Joint disablement of the KeyCape approval-engine operator client (reverse provisioning order, per key-cape message `7f2128fb`), once approval-engine has reconfirmed that there is no presenter. | + +## C. Remaining founder-gated choices (≈15 min) + +| # | Task | Choice | +|---|---|---| +| C1 | RPF-WP-0038-T04 | Pick the independent archive prefix and retention for Forgejo primary backup on Scaleway. | +| C2 | RPF-WP-0053-T02 / -T03 | Approve the coulomb-social paired archive authority (proposal: daily 03:15 UTC, RPO 24 h, RTO 60 min). | +| C3 | USER-WP-0035-T02 | Confirm the transactional-mail lane (email-connect + OpenBao delivery token) should be provisioned now. | +| C4 | NK-WP-0022-T08 | Only after a passing railiance01 restore/restart drill receipt: execute the approved CoulombCore cleanup batch (D4). | + +## After the window + +Run the report again. The owner agents requalify their tasks from your receipts (C-40). Nothing +else needs your attention until the report's ATTENDED section is non-empty again. diff --git a/history/20261011-netkingdom-security-progress-assessment.md b/history/20261011-netkingdom-security-progress-assessment.md index 39d6434d..b169fd39 100644 --- a/history/20261011-netkingdom-security-progress-assessment.md +++ b/history/20261011-netkingdom-security-progress-assessment.md @@ -55,10 +55,12 @@ The hub has 61 open decisions. The decision ids cited most in wait tasks: | `62aa95e4` Attended OpenBao provisioning window | 9 | open | One attended session clears credential lanes | | `1591daa1` Trust root / unseal & recovery custody | 4 | open | Founder design decision, gates seal/break-glass work | | `caafe4be` secrets-engine-openbao client live go | 4 | **resolved** | Tasks still wait: check whether the remaining blocker is the platform Secret, not the decision | -| `d426c67e`, `b005b483` | 11, 9 | not found as hub decisions | Probably local/task ids: verify they resolve to something actionable | So **about 35 wait tasks (~45 %) hang on three open decisions and one resolved one.** +> Correction (same day): `d426c67e` / `b005b483`, listed in the first version as unknown ids, were the +> tail ends of the D2 / D1 UUIDs. The counts above are already merged into those rows. + ## 3. Diagnosis 1. **Evidence inflation, not progress.** The agent seems to be optimizing for being @@ -163,4 +165,85 @@ Add these to the Sol goal: Counts come from grep over workplan files and may include archived or misformatted blocks. "Paperwork vs code" is inferred from commit subjects and file extensions, not from reading every diff. Some packet work may be legitimately required by canon review gates. Two -frequently cited ids could not be resolved to hub decisions. +frequently cited ids were mis-parsed UUID suffixes (corrected above). + +--- + +# Follow-up session — 2026-10-11 (same day, after the goal was paused) + +## Done + +1. **Uncommitted work:** 12 repos reviewed, committed and pushed (approval-engine, railiance-master, + railiance-platform, rapp-qonto, rapp-user-engine, reef-railiance, hall-of-helix, state-hub, + plenty-gobble, telegram-edge, mail-address-semantics, intelligence-radar). user-engine's stray + `.claude/settings.local.json.` was left uncommitted (local permissions). fix-consistency passes + everywhere except railiance-platform. There, 3 pre-existing C-07 errors remain: hub workplans + `railiance-wp-0024/0027/0029@retired-20260826` are not closed and have no file. Closing them needs + a hub write that is outside the sanctioned set. +2. **Founder decisions, two rounds** (`docs/decisions/2026-10-11-security-unblock-decisions.md`): + - D2: blanket ArgoCD go; + - D3: build-mode trust root, P3 = response-wrapped delivery; + - D1: standing attended-window rule; + - standing build-mode change rule, now canon `canon/standards/build-mode-change-authorization_v0.1.md`; + - D10 MFA accepted in principle; + - D4 + D5 accept + conditional. +3. **Hub/repo decision drift:** 31 hub decisions were still `open` although their repo logs already + recorded them as resolved/accepted. They were synced by `scripts/sync_resolved_decisions.py`. + **Open hub decisions went from 61 to 22.** Most of what looked like founder backlog was sync drift. +4. **Tasks:** 26 requalified with `scripts/requalify_tasks.py`. This included **mislabeled human + gates** (RPF-WP-0035-T02/T03 waited on other agents' tasks but carried `needs_human: true`). + 10 off-critical-path workplans were demoted to residual/backlog: NK-WP-0011, -0027, -0031, -0035, + -0040, RPF-WP-0015, WARDEN-WP-0034, -0040, FLEX-WP-0031, KG-WP-0005. To revert, flip `flavor`/`status` back. +5. **Deterministic flow:** `scripts/security_flow_report.py` shows the estate at a glance. At close: + **READY 26, UNBLOCKED 2, ATTENDED 14, STALLED 6.** +6. **Plans:** CUST-WP-0079 (scheduling, index de-agentification, re-engagement) and policy-nexus + PNEX-WP-0006 (publish the guardrail as a machine-readable artifact). +7. **Attended-window checklist** for the founder: `docs/attended-window/2026-10-11-checklist.md`. + +## Remaining open decisions (22) + +None blocks the security critical path. The security-relevant one left is `e1868a8d`, an attended +act that is already on the checklist (A3). The rest belong to other lanes: Qonto/company canon, +org-refactor, Hall of Helix, Vergabe, Telegram, runbook-tutorials. They deserve their own batch session. + +## When to re-engage the coding agent + +**Now, with the renewed goal.** The READY lane (26 tasks) needs no founder input. The attended window +(about 2 h) can run in parallel and does not have to come first. Re-engage with at most 3 workers, +and replace the goal. Do not continue the old one: its framing ("consolidate everything, progress +autonomously") is what produced the evidence churn. + +## Renewed goal (paste into Sol) + +``` +Goal: Prove the NetKingdom security critical path end to end in build mode. + +Critical path, in order: + 1. ArgoCD owns production: run RPF-WP-0044 T03→T06→T07, RPF-WP-0048-T02, RPF-WP-0043-T04 + (D2 granted: each step needs only the previous step's automated proof). + 2. Identity → first SecurityCase: NK-WP-0048-T06 (oidc-browser-relying-party) through + ops-mason → ops-warden/ArgoCD, registering Forgejo as client (KEY-WP-0038-T02/T03), + with login, revocation and audit receipt. Then KEY-WP-0039-T02. + 3. Authorization: finish FLEX-WP-0036 (access-engine rename, side-by-side run). + 4. Secrets: implement response-wrapped issuer delivery with one-time unwrap (D3 P3=b), + aligned with SECRETS-WP-0013; prove it on one lane. + 5. Deterministic layer: CUST-WP-0079-T03/T05, PNEX-WP-0006. + +Rules: +- Source of work: `python3 ~/the-custodian/scripts/security_flow_report.py` READY and UNBLOCKED. + Do not read or revisit wait tasks yourself. +- Authority: the-custodian canon/standards/build-mode-change-authorization_v0.1.md. + Blue-lane changes (diff/dry-run, rollback, abort owner, receipt) need no founder go. + Red-lane: one package, added to the daily batch. Orange-lane: add to + docs/attended-window/ checklist; never ask per item. +- When a task's next step needs another owner or a human: set `wait` with qualifiers once + (depends_on for agent work, needs_human only for real founder acts) and move on. +- No commit may consist only of evidence, packets, indexes or projection refreshes. Evidence + accompanies a code or live-state change; indexes are generated by make/CI. +- Prefer writing a script or check that makes a class of tasks deterministic over doing the + tasks by hand. +- At most 3 concurrent workers, each pinned to one workplan whose next task is todo. +- Success = critical-path steps proven live and READY+UNBLOCKED shrinking. + Report daily: steps proven, tasks closed, new ATTENDED items. Not commit counts. +Stop when steps 1–4 are proven or nothing in READY/UNBLOCKED remains. +``` diff --git a/workplans/CUST-WP-0079-deterministic-security-flow.md b/workplans/CUST-WP-0079-deterministic-security-flow.md new file mode 100644 index 00000000..2741be37 --- /dev/null +++ b/workplans/CUST-WP-0079-deterministic-security-flow.md @@ -0,0 +1,113 @@ +--- +id: CUST-WP-0079 +type: workplan +title: "Deterministic security flow: standing authorizations, flow report, and agent re-engagement" +domain: infotech +repo: the-custodian +status: active +owner: claude-code +topic_slug: custodian +created: "2026-10-11" +updated: "2026-10-11" +flavor: implementation +depends_on: [] +--- + +Follow-up to `history/20261011-netkingdom-security-progress-assessment.md`. About 80 % of the +security estate's open tasks were `wait`, and agent time went into re-reading waits and producing +evidence packets. This plan replaces that loop with (1) standing founder authorizations, +(2) deterministic reports and sync, and (3) a narrow, re-scoped coding-agent goal. + +Critical path (everything else is residual until promoted): +identity (key-cape, user-engine) → authorization (access-engine + policy-nexus guardrails) → +secrets (secrets-engine over OpenBao, response-wrapped delivery) → SecurityCase execution +(ops-mason → ops-warden / ArgoCD), proven first on oidc-browser-relying-party (NK-WP-0048-T06, +KEY-WP-0038). + +## Founder decision batch and hub/repo decision sync + +```task +id: CUST-WP-0079-T01 +status: done +priority: high +``` + +2026-10-11: D1, D2, D3 resolved, plus round 2 (standing build-mode change rule; D10 MFA remainder; +D4 + D5). Recorded in `docs/decisions/2026-10-11-security-unblock-decisions.md`. 31 open hub +decisions were already resolved in repo decision logs (gate-house, kings-guard, tenant-engine, +security-canon, repo-manager) and were synced. Open hub decisions went from 61 to 22. 26 tasks were +requalified, including fixes for tasks mislabeled as human gates. 10 workplans were demoted to +residual. + +## Deterministic tooling + +```task +id: CUST-WP-0079-T02 +status: done +priority: high +``` + +`scripts/security_flow_report.py` (READY / UNBLOCKED / ATTENDED / STALLED from workplan files), +`scripts/requalify_tasks.py` (apply task requalifications from a JSON plan), +`scripts/sync_resolved_decisions.py` (resolve hub decisions that repo logs already record as +resolved or accepted). + +## Schedule the flow report and decision sync + +```task +id: CUST-WP-0079-T03 +status: todo +priority: high +``` + +Run `sync_resolved_decisions.py --apply` and `security_flow_report.py --json` daily (activity-core +schedule, or a workstation timer until activity-core has the lane). Post a hub message to the +coding agent only when UNBLOCKED or READY changed, and to the founder only when ATTENDED is +non-empty. Agents must not poll wait tasks themselves. + +## Encode the standing change rule as a policy-nexus guardrail + +```task +id: CUST-WP-0079-T04 +status: wait +depends_on: [PNEX-WP-0006] +blocking_reason: "policy-nexus owns guardrail publication; handoff written as PNEX-WP-0006." +priority: high +``` + +Canon source written 2026-10-11: `canon/standards/build-mode-change-authorization_v0.1.md` +(founder-decided). Closes when PNEX-WP-0006 publishes it. + +## Stop agent-authored index and sync commits + +```task +id: CUST-WP-0079-T05 +status: todo +priority: medium +``` + +WORK-RECORDS.md, source inventories, publication indexes and "projection refresh" files must be +regenerated by a `make` target in a pre-commit hook or a Forgejo Action, not by agent commits. +Start with the security repos. Done when a week of git log shows no standalone index-only commits +from agents. + +## Attended window #1 + +```task +id: CUST-WP-0079-T06 +status: wait +needs_human: true +blocking_reason: "Founder runs docs/attended-window/2026-10-11-checklist.md (about 2 h)." +priority: high +``` + +## Re-engage the coding agent with the renewed goal + +```task +id: CUST-WP-0079-T07 +status: todo +priority: high +``` + +Replace the Sol goal with the renewed text in the assessment history file (section "Renewed +goal"). Re-engage now for the READY lane. It does not depend on T06.