ops-mason/workplans/MASON-WP-0008-plan-survey.md
tegwick 398b9cf729 Record the live plan survey and the reviewed inbound-library AppRole plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1170398@bnt-lap001
Assistant-Session: 622cd705-cb31-4322-ba08-dd42e44fa583
2026-10-05 14:32:47 +02:00

124 lines
4.4 KiB
Markdown

---
id: MASON-WP-0008
type: workplan
title: "Generate the construction-plan existing-structure survey from live metadata"
domain: infotech
repo: ops-mason
status: finished
flavor: implementation
owner: claude
topic_slug: netkingdom
created: "2026-10-05"
updated: "2026-10-05"
state_hub_workstream_id: "6a562716-aea0-5b9f-a6b5-5bbe6c459467"
---
# MASON-WP-0008 — Generate the existing-structure survey
## Goal
Section 2 of a construction plan (`docs/construction-plan-format.md`) needs
actual OpenBao output: relevant policy, auth and secrets-engine entries, the
matching ops-warden routing catalog entries, and an explicit answer to "does an
existing lane already satisfy this demand?". Today the drafting agent gathers
this by hand. Make it reproducible with one command that runs under the
`ops-mason-build` grant.
Founder decision: ops-warden routes, ops-mason surveys. ops-warden gets a
pointer-only catalog entry (WARDEN-WP-0042), no survey code and no token.
## Boundaries
- Metadata only. No `kv get`, no `*/data/*` read, no role-id or secret-id read;
enforced by an allowlist in the script and asserted by tests.
- `policies/ops-mason-build.hcl` is not changed. A query the grant does not
permit is reported as `not permitted by ops-mason-build`, not widened.
- No live OpenBao call in this workplan's implementation; tests use a fake bao.
## Tasks
## Implement scripts/plan-survey.py
```task
id: MASON-WP-0008-T01
status: done
priority: high
state_hub_task_id: "17e0429a-25e6-5469-b1a5-2acdcde2fbf3"
```
Script in the `custody-inventory.py` idiom (stdlib plus PyYAML, grant token
from `~/.claude-bao-token`, `BAO_ADDR` default `http://127.0.0.1:18200`, loud
failure). Takes KV path, proposed policy, AppRole and/or Kubernetes role,
consumer and keywords. Runs `bao token lookup` (display_name and policies only;
refuses any token other than `ops-mason-build` plus `default`),
`bao secrets list`, `bao auth list`, `bao policy list`,
`bao list auth/<mount>/role` for approle and kubernetes mounts, `bao read` of
name-matched role configs, `bao policy read` for name-matched policies,
`bao kv metadata get` on the target and `bao kv list` on its parent. Greps the
ops-warden catalog (`--catalog`, default
`~/ops-warden/registry/routing/catalog.yaml`). Emits a pasteable section 2 with
counts, timestamp, `BAO_ADDR`, display_name and a draft yes/no/partial answer.
## Unit tests with a fake bao runner
```task
id: MASON-WP-0008-T02
status: done
priority: high
state_hub_task_id: "f11fd0a1-5e60-5b34-a173-6ca30f909cc1"
```
`tests/test_plan_survey.py`: yes/no/partial verdicts, denied capabilities
degrade and are listed as incomplete, no grant and non-grant tokens fail
loudly, the token never appears in output, every recorded call is
metadata-only, and the guard refuses `kv get`, `*/data/*`, role-id/secret-id
and write calls.
## Document the command
```task
id: MASON-WP-0008-T03
status: done
priority: medium
state_hub_task_id: "a273a5c5-5c4e-59df-bfb7-dc49eb63f80b"
```
`docs/construction-plan-format.md` § 2 (grant, then survey) and the OpenBao
Access section of `AGENTS.md`.
## Route to it from ops-warden
```task
id: MASON-WP-0008-T04
status: done
priority: medium
state_hub_task_id: "d229f8cf-9e85-5006-8393-0b24bd64d502"
```
Pointer-only catalog entry `openbao-structure-survey` in ops-warden
(WARDEN-WP-0042): owner ops-mason, `warden_executes: false`, points to the
grant, this script and the format doc.
## First live survey: inbound-library IMAP lane
```task
id: MASON-WP-0008-T05
status: done
priority: medium
state_hub_task_id: "c9a73b84-6b37-5d39-a2ab-9f8b68bd940a"
```
Run against the real store for `platform/workloads/inbound-library/imap`,
policy `workload-kv-read-inbound-library-imap`, AppRole `inbound-library`,
consumer `inbound-library`, and check that `bao list auth/<mount>/role`,
role reads and `bao policy read` behave as the policy file implies
(`auth/approle/role/*`, `auth/kubernetes/role/*`, `sys/policies/acl/*`).
Record any `not permitted by ops-mason-build` line as a founder decision,
not a policy edit.
Done 2026-10-05: the founder minted the grant (`token-claude-MASON-WP-0008-T05`,
ops-mason-build + default). The live run exited 0. The grant permitted every
query, so there is no capability gap: 10 mounts, 5 auth mounts, 76 policies,
13 AppRole and 25 Kubernetes roles, a policy read of the one name-matched
candidate, target metadata (`current_version=2`) and 40 catalog entries. The
output is pasted verbatim as section 2 of `plans/inbound-library-imap-approle.md`.