ops-mason/workplans/MASON-WP-0001-foundation.md
codex 3fd1258d11 fix(workplans): declare type: workplan on records the hub already holds
These files carried no type field at all. Selection is by 'type: workplan', so
they were invisible to every projection while the hub held a record for each —
and a forge-derived reset read those correct records as no longer deriving and
queued them for retirement.

Only the type line is added.

Refs STATE-WP-0083-T05

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-26 20:56:05 +02:00

9.2 KiB

id type title status state_hub_workstream_id
MASON-WP-0001 workplan Foundation: the four-phase construction process, exercised on a real demand finished fa60e81b-19f6-4ad5-a584-f049cdec1bdb

First workplan for ops-mason. Stands up the four phases described in INTENT.md — construction plan, review/optimize, executive summary, build — and exercises the whole pipeline on one real, already-waiting piece of demand: the rein-openweights OpenBao AppRole (glas-harness/workplans/GLAS-WP-0002-T02, currently blocked on exactly the mechanic this repo exists to formalize). That task is not busywork invented for this workplan — it's real backlog this pipeline unblocks the moment phase 4 lands.

Task: Construction-plan format

Design the artifact phase 1 produces: demand description (consumer, credential type, scope requested), an existing-structure survey (what bao policy list/bao auth list/bao secrets list/ops-warden's registry/routing/catalog.yaml already cover, and whether any of it already satisfies the demand), and the proposed changes (create/modify/ tear-down, each with a stated reuse-vs-new rationale). Document in docs/construction-plan-format.md. Plain, versioned markdown/YAML — not a database — so a plan can be reviewed in a diff and stored next to the workplan that requested it.

Done (2026-07-27). docs/construction-plan-format.md: one file per plan at plans/<id>.md, YAML frontmatter (status: draft -> reviewed -> approved -> built -> catalogued, the phase-4 hard gate), six body sections (demand, existing-structure survey, proposed changes, phase-2 review notes, phase-3 executive summary, phase-4 build result) — one document threaded through all four phases, not four separate artifacts. Proven against a real demand, not a synthetic one: plans/rein-openweights-openrouter-approle.md, phases 1-2 filled in — including a genuine finding in the existing-structure survey (an existing openrouter-llm-connect catalog lane that could theoretically be reused, and an explicit, reasoned decision not to reuse it, scoped narrowly instead). Phases 3-4 wait on MASON-WP-0001-T03/T04/T05.

id: MASON-WP-0001-T01
status: done
priority: high
state_hub_task_id: "6b25e7ca-52a0-41c2-b5a0-b5e46c824264"

Task: Review/optimize pass

A self-check phase 2 runs over a draft plan before it's shown to anyone: flag likely-redundant new policies/roles against what already exists, naming/TTL/scoping convention drift against established lanes (e.g. the agent-harness-binky-mail shape: token_ttl=15m, token_max_ttl=30m, bounded token_num_uses), and note any compaction opportunity (two existing lanes that could merge). This can start as a checklist a human/agent runs manually against a draft plan — doesn't need to be automated tooling on day one.

Done (2026-07-27). docs/review-optimize-checklist.md: six checks (naming, TTL/scoping, redundancy, compaction, ease of use for the consumer, posture) — manual for now, automating a checker deferred until there's a second worked example to generalize from. Applied for real to plans/rein-openweights-openrouter-approle.md §4 — including a genuinely useful finding (credentials.py already expects exactly this plan's path/delivery shape, zero code changes needed to consume it) and one explicit posture assumption flagged rather than left silent (secret_id_ttl=0, carried from agent-harness-binky-mail, surfaced again in the executive summary for the approval decision to confirm).

id: MASON-WP-0001-T02
status: done
priority: high
state_hub_task_id: "58a446fb-78d0-42b4-b10a-1119266b1016"

Task: Executive-summary format

Design the phase 3 artifact: a short, decidable rendering of a reviewed plan — who/what gets access to what, for how long, blast radius if the credential leaks, and what it costs to reverse. This is the only mandatory human checkpoint (INTENT.md design principle 3/4) — it must be readable without knowing bao syntax. Document in docs/executive-summary-format.md, with the rein-openweights AppRole plan (task T05) as the worked example.

Done (2026-07-27). docs/executive-summary-format.md: six fixed fields (one-line ask, who/what gets access, to what, for how long, blast radius, cost to reverse) plus an explicit approve/reject/revise decision — no bao syntax, no restating sections 1-4, no editorializing beyond the plan's own reuse-vs-new conclusion. Rendered for real into plans/rein-openweights-openrouter-approle.md §5 — ready for an actual decision, not a mockup.

id: MASON-WP-0001-T03
status: done
priority: medium
state_hub_task_id: "e37debfd-8a00-4780-b036-9376c6a10557"

Task: Build executor

Phase 4: given an approved construction plan (explicit approval marker set after the executive summary was reviewed), execute it against OpenBao — policy write, AppRole creation, KV secret path creation (empty path/structure only — never a secret value, see INTENT.md), role_id/secret_id delivery to the consuming host, and a proposed pointer-only ops-warden catalog entry (warden_executes: false, no authored steps, status: draft — a normal commit/PR to the ops-warden repo, not a live API call). Ends by naming the exact paste_once_provision step the founder still needs to do (which path, which field) — it does not attempt to fill the value itself. Must refuse to run against an unapproved or missing-approval-marker plan — this is the one place a bug is a real security incident, not a bad UX. Start narrow: implement only the operations the first real plan (T05) needs, not a general OpenBao automation framework.

Done (2026-07-27). src/ops_mason/plan.py (frontmatter parser + is_approved()), src/ops_mason/executor.py (build_approle_kv_lane — policy write, AppRole create, role_id/secret_id delivery, never the KV path's value), src/ops_mason/audit.py (metadata-only JSONL build log). 12 tests, all mocked at the bao subprocess boundary (no live OpenBao access from this session — see GLAS-WP-0002-T02's original blocker). Explicitly verified: the refusal gate never even calls subprocess.run when the plan isn't fully approved (test_refusal_never_calls_bao); role_id/secret_id land as 0600 files and never appear in a log line or exception message; the policy HCL goes over stdin, never argv.

id: MASON-WP-0001-T04
status: done
priority: high
state_hub_task_id: "e949f4b7-5ef4-4e42-8a07-61b6c8040298"

Task: First real build — rein-openweights OpenBao AppRole

Run the whole pipeline for real: construction plan for Option B from glas-harness/workplans/GLAS-WP-0002-T02 (dedicated rein-openweights AppRole + KV secret path at reins/rein-openweights/openrouter, mirroring agent-harness-binky-mail's shape) → review/optimize → executive summary → founder approval → build (structure only). Build ends with the founder pasting the real OpenRouter key through ops-warden's paste_once_provision desk into the newly created path/field — that one paste is the only place the live value exists outside OpenBao. Once done, notify glas-harness/ rein-openweights so GLAS-WP-0002-T02's live OpenBao verification can proceed.

Done (2026-07-27), all four phases run for real. Founder logged in (bao login -method=oidc -path=netkingdom role=platform-admin — the initial bare -method=oidc 403'd against the wrong default mount path; netkingdom + an explicit role= was required, found via ops-warden's own catalog/wiki conventions). Executed build_approle_kv_lane for real:

  • Live-state discrepancy found and handled correctly, not silently: no reins/ KV mount existed (bao secrets list showed only platform//secret//tenants/) — a bigger action (new secrets engine) than the executive summary's blast-radius framing disclosed. Paused and got explicit founder confirmation before mounting, rather than substituting a different path or proceeding unilaterally.
  • Built: reins/ KV v2 mount, policy workload-kv-read-rein-openweights-openrouter, AppRole rein-openweights, role_id/secret_id delivered to ~/.local/rein-openweights/approle/ (0600).
  • Real bug caught and fixed, root cause and all: built with token_num_uses=0 (OpenBao's own default = unlimited) instead of the plan's own stated 8 — caught by comparing the live AppRole config against agent-harness-binky-mail's immediately after building, fixed live (bao write ... token_num_uses=8) and in code (AppRoleKVSpec.token_num_uses now has no default — must be passed explicitly, so this can't recur silently).
  • Catalog entry landed: ops-warden commit c0a50bc — and while writing it, corrected a real misreading in this repo's own INTENT.md of the no-double-source rule (pointer fields like auth_method/ fetch_command/rotation.steps are normal on non-SSH entries; only a bare top-level steps:+cert_command: pair is SSH-only) — verified against ops-warden's full 326-test suite, green.
  • Plan file status: built; catalog entry status: draft until the founder's paste-once-provision + GLAS-WP-0002-T02's live verification succeed.
id: MASON-WP-0001-T05
status: done
priority: high
state_hub_task_id: "01782608-aa5a-4f9b-a1fb-9a64f6d9c299"