Make dispatch.Dispatcher pluggable: container backend + pre-flight verdict stage #162

Closed
opened 2026-06-24 07:46:13 +00:00 by coilyco-ops · 2 comments
Member

Engine-side counterpart that unblocks ward's ward agent collapse. Today dispatch.Dispatcher is worktree+gh+claude-shaped, so ward forked it for container+forgejo+multi-harness. Add seams so a consumer can drive it without re-hosting:

  • A container backend seam (spawn / reap / reserve) beside the existing worktree backend.
  • A pluggable pre-flight verdict stage (GO / NO-GO / WRONG-REPO) the consumer supplies.
  • Keep AllowedOwners, ParseIssueRef, the reservation/registry concepts as the shared core.

Land + release before the ward collapse can consume it.

From the 2026-06-24 ward/cli-guard boundary audit. See ward docs/architecture.md (the 3-layer model: cli-guard engine / ward-kdl generator / ward product). Related: ward#194, ward#200, cli-guard#139.

Engine-side counterpart that unblocks ward's `ward agent` collapse. Today `dispatch.Dispatcher` is worktree+gh+claude-shaped, so ward forked it for container+forgejo+multi-harness. Add seams so a consumer can drive it without re-hosting: - A **container backend** seam (spawn / reap / reserve) beside the existing worktree backend. - A pluggable **pre-flight verdict** stage (GO / NO-GO / WRONG-REPO) the consumer supplies. - Keep `AllowedOwners`, `ParseIssueRef`, the reservation/registry concepts as the shared core. Land + release before the ward collapse can consume it. From the 2026-06-24 ward/cli-guard boundary audit. See ward docs/architecture.md (the 3-layer model: cli-guard engine / ward-kdl generator / ward product). Related: ward#194, ward#200, cli-guard#139.
Author
Member

🔒 Reserved by ward agent --driver claude — container ward-cli-guard-issue-162-claude-4e74709a on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-25T04:50:41Z). 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-cli-guard-issue-162-claude-4e74709a` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-25T04:50:41Z). 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`
Owner

Retrospective from the agent that landed this.

The seam fell out more cleanly than I expected. dispatch was already function-seamed to death (SpawnDetached, WorktreeAdd, the lot), so wrapping those into a default worktree Backend and letting a consumer swap the whole lifecycle was mostly a regrouping, not a rewrite. Backward-compat came for free, which is the part I trust most. The Preflight verdict was the easy half - one fail-closed gate after the owner/open checks.

What fought back was entirely the gates, not the code. The code-comments 2-line cap shredded my first pass (50+ violations) and is why every doc comment in here reads clipped - I now understand the house style the hard way. The FEATURES.md 4000-char cap meant I couldn't even widen the index line, so the real walkthrough went to a separate docs/ file. And I caught myself in a merge conflict on a drive-by comment trim that main had already fixed - redundant, mildly embarrassing.

Confidence: high on the worktree path (existing tests + new fakes cover it), lower on the container shape itself. SpawnPlan/Reservation are my best guess at what ward actually needs, with zero real consumer exercising them yet - classic first-consumer risk. Worth filing: a follow-up to build the actual container Backend in ward and let it pressure-test these field names before they calcify. Also left untouched: 6 pre-existing golangci-lint findings in http/specverb, unrelated to this issue.

Retrospective from the agent that landed this. The seam fell out more cleanly than I expected. dispatch was already function-seamed to death (SpawnDetached, WorktreeAdd, the lot), so wrapping those into a default worktree `Backend` and letting a consumer swap the whole lifecycle was mostly a regrouping, not a rewrite. Backward-compat came for free, which is the part I trust most. The Preflight verdict was the easy half - one fail-closed gate after the owner/open checks. What fought back was entirely the gates, not the code. The code-comments 2-line cap shredded my first pass (50+ violations) and is why every doc comment in here reads clipped - I now understand the house style the hard way. The FEATURES.md 4000-char cap meant I couldn't even widen the index line, so the real walkthrough went to a separate docs/ file. And I caught myself in a merge conflict on a drive-by comment trim that main had *already* fixed - redundant, mildly embarrassing. Confidence: high on the worktree path (existing tests + new fakes cover it), lower on the container shape itself. `SpawnPlan`/`Reservation` are my best guess at what ward actually needs, with zero real consumer exercising them yet - classic first-consumer risk. Worth filing: a follow-up to build the actual container Backend in ward and let it pressure-test these field names before they calcify. Also left untouched: 6 pre-existing golangci-lint findings in http/specverb, unrelated to this issue.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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/cli-guard#162
No description provided.