ops-warden/docs/adr/README.md
tegwick 35aff380a3
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
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

69 lines
3.6 KiB
Markdown

# ops-warden architecture decision records
This directory holds the rules **ops-warden owns** — the decisions this repo made,
is bound by, and is responsible for changing.
## Why these exist as ADRs rather than wiki prose
Until 2026-08-18 every rule in this list lived in wiki prose, a workplan, or a
comment at the top of `registry/routing/catalog.yaml`. All of them were being
followed. None of them was *addressable*: a reader outside ops-warden could not
cite one, could not tell whether it was current, and could not tell whether it
was ours to change or someone else's that we merely obey.
That distinction is the point of this directory. It matters in both directions:
- **A rule we own, mistaken for inherited canon, never gets fixed.** We wait for
an owner who does not exist.
- **Inherited canon, mistaken for ours, gets quietly bent.** We change something
we had no authority over, and the drift is invisible until it breaks a repo
that trusted the canonical version.
## Owned versus inherited
Every ADR here carries `owner:` in its frontmatter. It is the load-bearing field.
| `owner:` | Meaning | How it changes |
| --- | --- | --- |
| `ops-warden` | **Ours.** We decided it, we are bound by it, and we may change it | A new ADR that supersedes this one. Never an edit-in-place that rewrites a decision |
| anything else | **Inherited.** We follow it; we do not own it | Through that owner's process. We may dispute it — we may not amend it |
Everything currently in this directory is `owner: ops-warden`. Rules we follow but
do not own — NetKingdom canon, the IAM profile, the credential-management standard
— are *not* copied here. They are cited. Copying inherited canon into our own ADR
directory would recreate exactly the second-source-of-truth failure that
`ADR-0001` exists to prevent.
## Superseding one of these
A decision here changed the behaviour of other repos, so retracting it silently is
not available. Write a new ADR, set the old one's `status: superseded` and
`successor:`, and leave it in place. Superseded is a lifecycle state; deletion is
not. `policy-nexus` publishes the history, and a reader asking "what did this say
when we made that decision" must be able to find out.
## Relationship to `.claude/rules/`
`.claude/rules/*.md` are **agent-facing operational instructions**. They tell an
agent what to do in a session. They are derived from these ADRs and should cite
them rather than restate the reasoning. If the two disagree, the ADR is right and
the rule file is a defect.
## Publication
These are publishable through `policy-nexus` at `policy.coulomb.social`, which
requires `title`, `status` and `owner` on every document and renders Owner as a
column in its index. The ownership knowledge therefore survives publication
rather than being a local convention that evaporates at the repo boundary.
`policy-nexus` publishes; it never writes back. The file in this directory is the
source of truth. If the site and this directory disagree, this directory is right
and the publication is a defect.
| ADR | Rule | Binds |
| --- | --- | --- |
| `ADR-0001` | The routing catalog is a pointer layer, never a second copy of an owner's procedure | ops-warden, and every repo contributing a catalog entry |
| `ADR-0002` | ops-warden is a transparent conduit, never a secret broker | ops-warden |
| `ADR-0003` | Cover gaps, but never silently own them | ops-warden |
| `ADR-0004` | High-risk lanes refuse raw value streaming to agent sessions | ops-warden, and any agent runtime calling `warden access` |
| `ADR-0005` | Implement one lane narrowly, route everything else | ops-warden |