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
124 lines
4.4 KiB
Markdown
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`.
|