fix(ward-kdl): move forgejo tiers to the literal cmd/ward-kdl/ward-kdl-{read,write,admin}/ subdir layout #262

Closed
opened 2026-06-24 06:54:30 +00:00 by coilyco-ops · 6 comments
Member

Goal

ward#240 (commit 6116789b) shipped the forgejo read/write/admin tiers but deviated from the specified layout: it created a new sibling dir cmd/ward-kdl-forgejo/ with all three guardfiles flat under one shared admin-tier lock. Restructure to the literal intended layout — per-tier subdirectories under cmd/ward-kdl/:

cmd/ward-kdl/ward-kdl-read/
cmd/ward-kdl/ward-kdl-write/
cmd/ward-kdl/ward-kdl-admin/

Each subdir is self-contained: its tier guardfile, its own forgejo.swagger.lock.json (own lock namespace — this is what removes the filename collision the original commit worked around with a shared lock), its generated main.go, and its reference doc. Go's cmd/<binary>/ convention; the binaries stay ward-kdl-read / ward-kdl-write / ward-kdl-admin.

What to change

  • Create cmd/ward-kdl/ward-kdl-{read,write,admin}/, each holding its tier guardfile (name it conventionally inside the subdir) + its own lock.
  • Preserve the tier semantics unchanged — only the layout moves:
    • read = can get "*" + can list "*"
    • write = inherit read + can create "*" + can edit "*"
    • admin = inherit write + can delete "*"
      Update the inherit references to the new relative subdir paths (write → ../ward-kdl-read/..., admin → ../ward-kdl-write/...). Re-declare each tier's restrict owner matches coily* as before (restrict is child-local under inherit).
  • Remove cmd/ward-kdl-forgejo/ entirely.
  • Build wiring: rework Makefile build-ward-kdl-forgejo-tiers to lock+build each tier from its own subdir (each tier locks its own slice now — no shared-lock gymnastics). Update .gitignore and the pyproject.toml documentation-layout / code-comments excludes to the new paths.
  • Docs: move the three reference docs to match (docs/ward-kdl.forgejo.{tier}.guardfile.md or per the new naming), update docs/FEATURES.md and docs/ward-kdl-surface.md references.

Acceptance

  1. cmd/ward-kdl/ward-kdl-{read,write,admin}/ exist, each self-contained; cmd/ward-kdl-forgejo/ is gone.
  2. make build-ward-kdl builds all three tier binaries from the new layout; gen/skew clean.
  3. Tier grants identical to 6116789b (read ⊂ write ⊂ admin via inherit + wildcard); a withheld verb is absent at compile time (read has no create/edit/delete leaf, write no delete leaf).
  4. Docs + excludes updated to the new paths. Conventional commit, closes this issue via the full Forgejo URL, push to canonical main.

ward#240 (the original, commit 6116789b), cli-guard#159 (wildcard), cli-guard#160 (inherit).

## Goal ward#240 (commit `6116789b`) shipped the forgejo read/write/admin tiers but **deviated from the specified layout**: it created a new sibling dir `cmd/ward-kdl-forgejo/` with all three guardfiles flat under one shared admin-tier lock. Restructure to the literal intended layout — **per-tier subdirectories under `cmd/ward-kdl/`**: ``` cmd/ward-kdl/ward-kdl-read/ cmd/ward-kdl/ward-kdl-write/ cmd/ward-kdl/ward-kdl-admin/ ``` Each subdir is self-contained: its tier guardfile, **its own `forgejo.swagger.lock.json`** (own lock namespace — this is what removes the filename collision the original commit worked around with a shared lock), its generated `main.go`, and its reference doc. Go's `cmd/<binary>/` convention; the binaries stay `ward-kdl-read` / `ward-kdl-write` / `ward-kdl-admin`. ## What to change - **Create** `cmd/ward-kdl/ward-kdl-{read,write,admin}/`, each holding its tier guardfile (name it conventionally inside the subdir) + its own lock. - **Preserve the tier semantics unchanged** — only the layout moves: - read = `can get "*"` + `can list "*"` - write = `inherit` read + `can create "*"` + `can edit "*"` - admin = `inherit` write + `can delete "*"` Update the `inherit` references to the new relative subdir paths (write → `../ward-kdl-read/...`, admin → `../ward-kdl-write/...`). Re-declare each tier's `restrict owner matches coily*` as before (restrict is child-local under inherit). - **Remove** `cmd/ward-kdl-forgejo/` entirely. - **Build wiring:** rework `Makefile` `build-ward-kdl-forgejo-tiers` to lock+build each tier from its own subdir (each tier locks its own slice now — no shared-lock gymnastics). Update `.gitignore` and the `pyproject.toml` documentation-layout / code-comments excludes to the new paths. - **Docs:** move the three reference docs to match (`docs/ward-kdl.forgejo.{tier}.guardfile.md` or per the new naming), update `docs/FEATURES.md` and `docs/ward-kdl-surface.md` references. ## Acceptance 1. `cmd/ward-kdl/ward-kdl-{read,write,admin}/` exist, each self-contained; `cmd/ward-kdl-forgejo/` is gone. 2. `make build-ward-kdl` builds all three tier binaries from the new layout; `gen`/`skew` clean. 3. Tier grants identical to `6116789b` (read ⊂ write ⊂ admin via inherit + wildcard); a withheld verb is absent at compile time (read has no create/edit/delete leaf, write no delete leaf). 4. Docs + excludes updated to the new paths. Conventional commit, closes this issue via the full Forgejo URL, push to canonical main. ## Related ward#240 (the original, commit `6116789b`), cli-guard#159 (wildcard), cli-guard#160 (inherit).
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-262-claude-4c301db7 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T06:54:33Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-262-claude-4c301db7` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T06:54:33Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-262-claude-c72e32d7 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T07:09:01Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-262-claude-c72e32d7` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T07:09:01Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-262-claude-78a3f026 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T07:13:52Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-262-claude-78a3f026` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T07:13:52Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-262-claude-e8e4a748 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T07:37:30Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-262-claude-e8e4a748` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T07:37:30Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-262-claude-33d802e6 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T08:15:33Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-262-claude-33d802e6` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T08:15:33Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-262-claude-052c7a23 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T08:25:07Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-262-claude-052c7a23` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T08:25:07Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#262
No description provided.