MASON-WP-0008: generate the construction-plan existing-structure survey

scripts/plan-survey.py runs under the ops-mason-build grant and prints a
pasteable section 2: relevant secrets/auth/policy/role listings with counts,
policy stanzas covering the target for name-matched policies, KV metadata
existence, matching ops-warden catalog entries, timestamp, BAO_ADDR, token
display_name and a draft yes/no/partial answer. Metadata only: an allowlist
refuses kv get, */data/* and role-id/secret-id before any process starts; a
non-grant token is refused and the token is never printed. Denied queries
degrade to 'not permitted by ops-mason-build'. Tests use a fake bao runner.

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
This commit is contained in:
tegwick 2026-10-05 13:22:26 +02:00
parent 81ca48b563
commit 9f67565ea3
5 changed files with 867 additions and 0 deletions

View file

@ -60,6 +60,37 @@ anything new:
minting a new one, because the scoping already covered the new
consumer.)
Generate the section rather than gathering it by hand (MASON-WP-0008). The
founder mints the scoped grant; the agent then runs the survey with it:
```bash
./scripts/bao-session.sh grant <task> # founder: ops-mason-build, 45m, claude-<task>
./scripts/plan-survey.py \
--kv-path platform/workloads/<consumer>/<name> \
--policy workload-kv-read-<consumer>-<name> \
--approle <role> [--k8s-role <role>] \
--consumer <consumer-repo> [--keyword <word> ...] \
[--catalog ~/ops-warden/registry/routing/catalog.yaml]
```
It prints a Markdown block headed `## 2. Existing-structure survey`: the
relevant lines and counts of `bao secrets list`, `bao auth list`,
`bao policy list` and `bao list auth/<mount>/role` (approle and kubernetes
mounts), `bao policy read` stanzas covering the target for name-matched
policies only, KV metadata existence for the target and its siblings,
matching ops-warden catalog entries, a UTC timestamp, `BAO_ADDR`, the token
`display_name`, and a draft yes/no/partial answer with reasons. Edit the
draft answer into a decision; it is generated evidence, not a review.
The survey refuses to run without a grant, refuses a token whose policies
are anything but `ops-mason-build` (plus `default`), and never prints the
token. Every bao call passes an allowlist that rejects `kv get` and any
`*/data/*` path before a process starts. A query the grant does not permit
is reported as `not permitted by ops-mason-build` and listed under
"incomplete" rather than read as an empty answer. Policies with names that
do not match the demand are not read, so a broadly named policy covering
the path is not detected; the output says so.
### 3. Proposed changes
A list, each item tagged `create` / `modify` / `tear-down`, each with a