ops-warden/.claude/rules/architecture.md

61 lines
3 KiB
Markdown
Raw Normal View History

2026-05-18 16:55:47 +02:00
## Architecture
Lift ops-warden's binding rules into owned ADRs Five rules that governed this repo lived in wiki prose, a workplan, and a comment at the top of catalog.yaml. All were followed; none was addressable. A reader outside ops-warden could not cite one, could not tell whether it was current, and — the point of this change — could not tell whether it was ours to change or someone else's that we merely obey. ADR-0001 The routing catalog is a pointer layer, never a second copy ADR-0002 ops-warden is a transparent conduit, never a secret broker ADR-0003 Cover gaps, but never silently own them ADR-0004 High-risk lanes refuse raw value streaming to agent sessions ADR-0005 Implement one lane narrowly, route everything else Each carries owner: ops-warden, which is the load-bearing field. It says we follow the rule AND we are responsible for changing it — by superseding ADR, never an in-place edit. The failure this prevents runs both ways: a rule we own mistaken for inherited canon never gets fixed, because we wait for an owner who does not exist; inherited canon mistaken for ours gets quietly bent, and the drift is invisible until it breaks a repo that trusted the canonical version. Rules we follow but do not own — NetKingdom canon, the IAM profile, the credential-management standard, the-custodian's ADR-001 workplan convention — are cited, never copied into docs/adr/. Copying them would recreate exactly the second-source-of-truth failure ADR-0001 exists to prevent. architecture.md also now flags the three-digit/four-digit ADR-001 vs ADR-0001 collision, which is itself an ours-versus-inherited confusion waiting to happen. Publication verified rather than assumed: all five render through policy-nexus tools/render.py, and owner reaches the reader in three places — the page eyebrow (render.py:346), the index Owner column (build_site.py:123,137), and the publication manifest. build_site.py:179 makes title/status/owner required, so ownership cannot be dropped on the way out. policy-nexus publishes and never writes back; docs/adr/ stays the source of truth. Documentation adapted: SCOPE.md gains a Governing rules section and an orientation entry; .claude/rules/architecture.md replaced its stub with the ADR index, the owned-versus-inherited rule, and ADR-over-wiki precedence; finding-routing.md's ADR-gap section closed; catalog.yaml's no-double-source header now cites ADR-0001 rather than the originating workplan. uv run pytest -q → 338 passed, 4 deselected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 13:35:13 +02:00
### Our rules are ADRs — `docs/adr/`
The decisions that govern this repo live in `docs/adr/` as addressable records,
not in wiki prose. Read `docs/adr/README.md` first; it explains the one
distinction that matters here.
| ADR | Rule |
| --- | --- |
| `ADR-0001` | The routing catalog is a pointer layer, never a second copy of an owner's procedure |
| `ADR-0002` | ops-warden is a transparent conduit, never a secret broker |
| `ADR-0003` | Cover gaps, but never silently own them |
| `ADR-0004` | High-risk lanes refuse raw value streaming to agent sessions |
| `ADR-0005` | Implement one lane narrowly, route everything else |
| `ADR-0006` | Enforcement is zone-scoped, never a global flag |
| `ADR-0007` | Build-stage permissiveness stops at credential disclosure; every lane carries an explicit `risk` grade |
| `ADR-0008` | A lane's risk grade covers every field its path discloses, not just the field it is named after |
Assent to the NetKingdom security layer model (WARDEN-IN-0001) gate-house asked ops-warden to assent to three boundary items ratified in GH-DEC-2026-001. All three are assented in ADR-0010. Staff: accepted. Grepping section 5 as it invites turned up a real non-conformance — src/warden/vault.py is a direct OpenBao client performing a write, and so is `warden desk`'s `bao kv put`. Section 5's only escape hatch is read-only diagnostics, which does not cover a signing write, so both are declared in INTENT.md as an engine gap with intended owner secrets-engine and the blocker "no engine exposes an SSH-CA surface" — ADR-0003 turned inward rather than an exemption argued for. taint.py is metadata-only and declared under the read-only allowance; `warden access` proxies run under the caller's identity and supply no authority of their own. Doctrine versus runbook: accepted. NetKingdom Security Literacy becomes a lane routing runbook that references gate-house doctrine instead of restating it. It had also become a prose second source for registry/routing/catalog.yaml, which ADR-0001 already rules against. Lane versus rule: assented unconditionally, and the access-engine veto is not exercised. One request on sequencing only — a window where both names resolve. gate-house added to the routing tables in INTENT.md and SCOPE.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ Assistant: claude-code Assistant-Model: opus Assistant-Process: 4014535@bnt-lap001 Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-28 21:47:44 +02:00
| `ADR-0009` | Adopt security-zones v0.1 as a consumer; membership is compiled, never inferred |
| `ADR-0010` | ops-warden is Staff: it owns access lanes, never access rules; doctrine belongs to gate-house |
Lift ops-warden's binding rules into owned ADRs Five rules that governed this repo lived in wiki prose, a workplan, and a comment at the top of catalog.yaml. All were followed; none was addressable. A reader outside ops-warden could not cite one, could not tell whether it was current, and — the point of this change — could not tell whether it was ours to change or someone else's that we merely obey. ADR-0001 The routing catalog is a pointer layer, never a second copy ADR-0002 ops-warden is a transparent conduit, never a secret broker ADR-0003 Cover gaps, but never silently own them ADR-0004 High-risk lanes refuse raw value streaming to agent sessions ADR-0005 Implement one lane narrowly, route everything else Each carries owner: ops-warden, which is the load-bearing field. It says we follow the rule AND we are responsible for changing it — by superseding ADR, never an in-place edit. The failure this prevents runs both ways: a rule we own mistaken for inherited canon never gets fixed, because we wait for an owner who does not exist; inherited canon mistaken for ours gets quietly bent, and the drift is invisible until it breaks a repo that trusted the canonical version. Rules we follow but do not own — NetKingdom canon, the IAM profile, the credential-management standard, the-custodian's ADR-001 workplan convention — are cited, never copied into docs/adr/. Copying them would recreate exactly the second-source-of-truth failure ADR-0001 exists to prevent. architecture.md also now flags the three-digit/four-digit ADR-001 vs ADR-0001 collision, which is itself an ours-versus-inherited confusion waiting to happen. Publication verified rather than assumed: all five render through policy-nexus tools/render.py, and owner reaches the reader in three places — the page eyebrow (render.py:346), the index Owner column (build_site.py:123,137), and the publication manifest. build_site.py:179 makes title/status/owner required, so ownership cannot be dropped on the way out. policy-nexus publishes and never writes back; docs/adr/ stays the source of truth. Documentation adapted: SCOPE.md gains a Governing rules section and an orientation entry; .claude/rules/architecture.md replaced its stub with the ADR index, the owned-versus-inherited rule, and ADR-over-wiki precedence; finding-routing.md's ADR-gap section closed; catalog.yaml's no-double-source header now cites ADR-0001 rather than the originating workplan. uv run pytest -q → 338 passed, 4 deselected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 13:35:13 +02:00
### Owned versus inherited — check `owner:` before changing anything
Every ADR carries `owner:` in its frontmatter, and it decides what you are allowed
to do with the rule:
- **`owner: ops-warden`** — ours. We are bound by it *and* we may change it. Changing
one means writing a superseding ADR, not editing the decision in place.
- **any other owner** — inherited. We follow it; we do not own it. Dispute it through
that owner's process; never amend it here.
Everything in `docs/adr/` today is `owner: ops-warden`. Rules we merely follow —
NetKingdom canon, the IAM profile, the credential-management standard — are cited,
never copied in. Copying them would recreate the second-source-of-truth failure
`ADR-0001` exists to prevent.
**Naming collision, worth knowing.** `ADR-001` (three digits) in
`workplan-convention.md` and `session-protocol.md` is **the-custodian's** ADR
establishing the workplan convention across the whole estate. It is inherited and
not ours to change. Our records are four-digit — `ADR-0001``ADR-0005` — and live
in this repo. When writing, say "the-custodian's ADR-001" if that is what you mean.
### Precedence
If a wiki page, playbook, or `.claude/rules/` file disagrees with an ADR, **the ADR
is right and the other file is a defect** — fix it rather than working around it.
The rule files are agent-facing operational instructions derived from these
decisions; they should cite an ADR rather than restate its reasoning.
### Publication
These ADRs are publishable through `policy-nexus` at `policy.coulomb.social`, which
requires `title`, `status` and `owner`, renders owner in the page header and in the
index, and records source repo, path and revision digest in its manifest. Ownership
survives the repo boundary. `policy-nexus` publishes and never writes back: the file
here is the source of truth.
2026-05-18 16:55:47 +02:00
## Quick Reference
`~/state-hub/mcp_server/TOOLS.md` — MCP tool reference