feat(WP-0011): warden route lookup CLI over the pointer catalog

Add a read-only `warden route` command group (list/show/find) that reads
registry/routing/catalog.yaml and tells a worker which subsystem owns a need
and which wiki/canon doc to follow. ops-warden still executes exactly one lane
(SSH); routed entries return a pointer and never call any subsystem.

- src/warden/routing/: models.py + catalog.py loader; enforces the
  no-double-source rule (non-SSH entries with steps/cert_command fail validation),
  dup-id and schema checks.
- route list (active-only unless --all, --tag), route show (SSH appends steps +
  cert pattern; routed ends with "next action on <owner> — see <wiki_ref>"),
  route find (keyword ranking, --json).
- tests/test_routing.py: load/validation, find ranking, CLI JSON shapes, plus a
  drift guard (every wiki_ref anchor resolves; every entry has a reviewed date).
- Docs: wiki/AccessRouting.md CLI section, README quick reference, SCOPE A3 -> A4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 21:03:24 +02:00
parent 407cd2e1f4
commit ac2efa1262
10 changed files with 690 additions and 32 deletions

View File

@@ -57,15 +57,48 @@ the owner's runbook. See the no-double-source rule in
---
## Routing lookup CLI (`warden route`)
Agents and operators query the pointer catalog directly instead of re-deriving
routing from wiki prose. The command group is **read-only** — it never calls
OpenBao, flex-auth, key-cape, or any other subsystem, and never returns secret
material.
```bash
warden route list [--json] [--all] [--tag <keyword>] # active-only unless --all
warden route show <id> [--json] # owner + pointers; SSH adds steps
warden route find "<free text need>" [--json] [--all] # rank by keyword overlap
```
Agent-oriented examples:
```bash
# "I need an API key" — find the owner, get a pointer, act there yourself
warden route find "openrouter api key" --json
warden route show openbao-api-key --json
# → {"warden_executes": false, "next_action": "next action on `railiance-platform` — see `wiki/CredentialRouting.md#routing-table`"}
# The one lane ops-warden executes: SSH. `show` appends the authored steps + cert pattern.
warden route show ssh-cert-host-access --json
# → {"warden_executes": true, "cert_command": "warden sign <actor> --pubkey <path>", "steps": [...]}
```
`show` on a routed (non-SSH) need always ends with **"next action on
`<owner_repo>` — see `<wiki_ref>`"** and never implies ops-warden performed
anything. Draft scenarios (owner path not yet shipped) are hidden unless `--all`.
---
## Audience notes
- **Human operators** read this page and `CredentialRouting.md` to choose the
right subsystem, then follow that subsystem's own docs.
- **Agents / CI** will read the machine-readable routing catalog
(`registry/routing/catalog.yaml`, surfaced via `warden route` — WARDEN-WP-0011)
so routing does not have to be re-derived from wiki prose each session.
- **Agents / CI** read the machine-readable routing catalog
(`registry/routing/catalog.yaml`) via `warden route` (above) so routing does
not have to be re-derived from wiki prose each session.
- **Same truth, two shapes:** humans read the wiki; agents read the catalog. The
catalog references wiki sections by anchor so the two cannot drift apart.
catalog references wiki sections by anchor so the two cannot drift apart — a
test (`tests/test_routing.py`) fails CI if any `wiki_ref` anchor stops resolving.
---