Files
ops-warden/workplans/WARDEN-WP-0011-routing-guide-cli.md
tegwick ac2efa1262 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>
2026-06-18 21:07:13 +02:00

157 lines
4.9 KiB
Markdown

---
id: WARDEN-WP-0011
type: workplan
title: "Routing Lookup CLI"
domain: custodian
repo: ops-warden
status: done
owner: codex
topic_slug: custodian
planning_priority: high
planning_order: 11
created: "2026-06-18"
updated: "2026-06-18"
state_hub_workstream_id: "0a520f8e-01b4-48f1-9af3-2f3f69fd0672"
---
# WARDEN-WP-0011 — Routing Lookup CLI
**Scope:** A `warden route` command group that reads the pointer catalog and tells
a worker which subsystem owns a need, what the prerequisites are, and which
wiki/canon doc to follow **on that system**. ops-warden does not call OpenBao,
flex-auth, or key-cape on the worker's behalf.
**Out of scope:** HTTP API; live probes against any subsystem; secret generation or
retrieval; a separate health/precondition command (see "Dropped" below); replacing
subsystem CLIs.
**Depends on:** WARDEN-WP-0010 T3 (catalog schema + seed).
**Unlocks:** Agents run `warden route show <id> --json` instead of re-deriving
routing from wiki prose each session.
---
## Target CLI
```text
warden route list [--json] [--tag <tag>]
warden route show <id> [--json]
warden route find <query> [--json] # keyword match against need_keywords
```
`list`/`find` show only `status: active` entries by default (`--all` includes draft).
### Behaviour
| Command | Does | Does not |
| --- | --- | --- |
| `list` / `show` | Return owner, wiki/canon pointers, `warden_executes`, anti-patterns | Return secret material |
| `find` | Rank scenarios by keyword overlap | Invoke any external API |
When `warden_executes: true` (SSH), `show` appends the catalog's authored `steps`
and the `warden sign` / `cert_command` pattern, plus a local precondition hint
("actor in inventory? backend configured? run `warden status`"). For all other
scenarios `show` ends with **"next action on `<owner_repo>` — see `<wiki_ref>`"**
and never implies warden performed anything.
### Dropped: separate `check` command
The earlier draft had `warden coach check`. Cut. For SSH, `warden status` already
covers local preconditions; duplicating it invites scope creep toward probing
foreign subsystems. SSH precondition hints live inside `show` instead.
---
## Tasks
### T1 — Catalog loader and models
```task
id: WARDEN-WP-0011-T01
status: done
priority: high
state_hub_task_id: "55b8422c-ad3c-4084-9e00-acaa4c360906"
```
- [x] Add `src/warden/routing/` package: `models.py`, `catalog.py`.
- [x] Load and validate `registry/routing/catalog.yaml`.
- [x] Enforce the no-double-source rule: non-SSH entries with a `steps` block are a
validation error. Clear errors for missing file, schema violations, dup `id`.
### T2 — `warden route list` and `show`
```task
id: WARDEN-WP-0011-T02
status: done
priority: high
state_hub_task_id: "60b679c5-79bd-4186-b5a6-ac576931f06c"
```
- [x] Register `route` Typer sub-app on the main CLI.
- [x] `list` — Rich table + `--json` array of summaries; active-only unless `--all`.
- [x] `show` — owner, prerequisites, pointers (`wiki_ref`, `canon_ref`),
`warden_executes`, anti-patterns; SSH entries also append `steps` + cert pattern.
- [x] Exit 1 with a `find` hint when `show` id is unknown.
### T3 — `warden route find`
```task
id: WARDEN-WP-0011-T03
status: done
priority: high
state_hub_task_id: "d307701f-0117-44f0-80fd-ca6f7ae06f42"
```
- [x] Tokenize query; match against `need_keywords`, `title`, `id`.
- [x] Rank, show top matches (default 5); `--json` for agents.
- [x] Fixtures: "issue core api key", "ssh tunnel", "openrouter key".
### T4 — Tests
```task
id: WARDEN-WP-0011-T04
status: done
priority: high
state_hub_task_id: "00a76e0f-8ab6-4f9a-ac6a-00eae633342c"
```
- [x] `tests/test_routing.py` — catalog load, no-double-source validation rejects a
non-SSH `steps` block, find ranking, show JSON shape, SSH `show` includes cert
pattern.
- [x] No integration test requires a live subsystem.
### T5 — Doc consistency + drift guard
```task
id: WARDEN-WP-0011-T05
status: done
priority: high
state_hub_task_id: "bf848375-eca7-4116-bb1d-fb7df6395c70"
```
- [x] CI/test: every `wiki_ref` anchor resolves to an existing in-repo wiki section;
every entry has a `reviewed` date.
- [x] `wiki/AccessRouting.md` — CLI section with agent-oriented examples.
- [x] README — `warden route --help` quick reference.
- [x] Bump SCOPE availability note A3 → A4 on ship.
---
## Acceptance
- `uv run warden route find "issue core api key"` returns the draft scenario only
with `--all`, and never a generated key.
- `uv run warden route show ssh-cert-host-access --json` includes
`warden_executes: true` and the cert_command pattern.
- A non-SSH catalog entry carrying a `steps` block fails `test_routing.py`.
- `uv run pytest tests/test_routing.py` passes with no live-subsystem dependency.
---
## See also
- `WARDEN-WP-0010` — charter and catalog schema
- `WARDEN-WP-0012` — expanded per-scenario playbooks
- `history/2026-06-17-intent-scope-assessment.md` — prior `warden guide` proposal (P4)