fix(cli): bundle registry into wheel so installed warden works outside the repo

issue-core flagged the installed `warden` lacked the `route` subcommand. Two causes:

1. uv reused a cached wheel (version stayed 0.1.0) so the installed warden.cli was
   stale. Documented the cache-clean + --reinstall fix in ADHOC-2026-06-27.
2. Even rebuilt, route/access/policy were unusable outside a checkout because the
   routing catalog + posture descriptors live in registry/ at repo root, outside the
   package. Bundle registry/ into the wheel (hatch force-include -> warden/_registry)
   and add a packaged-data fallback in find_catalog_path / find_posture_path after the
   repo walk, so source runs still prefer the repo's registry/ (single source of truth).

Verified `warden route list` / `warden policy list` work from /tmp. 200 tests, lint clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-27 19:40:14 +02:00
parent 475db3c122
commit 0b3486af9e
4 changed files with 54 additions and 0 deletions

View File

@@ -20,6 +20,13 @@ ops-ssh-wrapper = "warden.scripts.ops_ssh_wrapper:main"
[tool.hatch.build.targets.wheel]
packages = ["src/warden"]
# Bundle the routing catalog + posture descriptors inside the package so the
# installed CLI (`warden route` / `access` / `policy`) works from any cwd, not only
# from a checkout. Source runs still prefer the repo's registry/ (single source of
# truth); the bundled copy is the fallback resolved by find_catalog_path/find_posture_path.
[tool.hatch.build.targets.wheel.force-include]
"registry" = "warden/_registry"
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]

View File

@@ -111,6 +111,10 @@ def find_posture_path(start: Optional[Path] = None) -> Path:
candidate = parent / rel
if candidate.exists():
return candidate
# Fallback: registry bundled into the installed wheel (warden/_registry/...).
bundled = Path(__file__).resolve().parent / "_registry" / "policy" / "security-posture.yaml"
if bundled.exists():
return bundled
raise PostureError(f"Posture descriptors not found ({rel}).")

View File

@@ -98,6 +98,10 @@ def find_catalog_path(start: Optional[Path] = None) -> Path:
candidate = parent / rel
if candidate.exists():
return candidate
# Fallback: registry bundled into the installed wheel (warden/_registry/...).
bundled = Path(__file__).resolve().parent.parent / "_registry" / "routing" / "catalog.yaml"
if bundled.exists():
return bundled
raise CatalogError(
f"Routing catalog not found ({rel}). Set WARDEN_ROUTING_CATALOG to override."
)

View File

@@ -0,0 +1,39 @@
---
id: ADHOC-2026-06-27
type: workplan
title: "Ad Hoc Tasks — 2026-06-27"
domain: infotech
repo: ops-warden
status: finished
owner: claude
topic_slug: custodian
created: "2026-06-27"
updated: "2026-06-27"
---
# Ad Hoc Tasks — 2026-06-27
Low-risk opportunistic fixes completed directly during the consolidation session.
### T01 — Fix stale `warden` CLI install + make it usable outside the repo
```task
id: ADHOC-2026-06-27-T01
status: done
priority: medium
```
issue-core reported (msg `70bcf238`) that the `warden` CLI on `~/.local/bin` lacked
the `route` subcommand, forcing a `uv run warden` fallback.
- [x] Root cause: `uv tool install` had reused a **cached wheel** (version stayed
`0.1.0`), so the installed `warden.cli` predated the `route`/`access`/`policy`
subcommands. `uv cache clean ops-warden` + `uv tool install . --reinstall` fixed it.
- [x] Deeper cause: even rebuilt, `warden route`/`policy` failed outside a checkout
because the catalog + posture descriptors live in `registry/` at repo root,
outside the package. Bundled `registry/` into the wheel via hatch
`force-include``warden/_registry`, and added a packaged-data fallback in
`find_catalog_path` / `find_posture_path` (after the repo walk, so source runs
still prefer the repo's `registry/` as the single source of truth).
- [x] Verified `warden route list` / `warden policy list` work from `/tmp`; 200 tests
pass, lint clean.