dispatch-ticket

Hand one ready ticket to one Builder in its own worktree.

One Ticket, Seven Checkpoints A workflow diagram generated by Archify. 01 / Thomas 02 / Builder Review ladder — one round Claim · assignee written + read back · Thomas Claim assignee written + read back Brief · dispatch into pane, at Base · Thomas Brief dispatch into pane, at Base Merge · Ledger line, assignee cleared · Thomas Merge Ledger line, assignee cleared Implement · commits on ticket branch · Builder Implement commits on ticket branch Code-review · Standards + Spec, one pass · Builder › Review ladder — one round Code-review Standards + Spec, one pass Simplify · simplify(increment): commit · Builder › Review ladder — one round Simplify simplify(increment): commit Cross-vendor arm · arm(ticket): receipt · Builder › Review ladder — one round Cross-vendor arm arm(ticket): receipt handback Legend User UI Agent logic Policy
Explore ↗opens in a new tab

What it does

dispatch-ticket is the sequence Thomas runs every time a ticket goes from “claimable” to “a Builder is actually working on it”: claim it on the tracker, cut a branch and worktree, open a Herdr tab and pane, print the resolved dispatch, hand over the brief, then arm a watcher before moving on. Nine steps, always in that order. A step nobody checks is a step that gets skipped silently, and this harness runs several of these sequences in parallel, so silently here means a Builder idle in a pane nobody is watching.

What is different about it is where the boundary sits: the claim happens before the worktree exists. A ticket gets assigned on the tracker first, so two Thomas sessions picking off the same frontier see each other’s claims instead of racing to create the same branch. The problem behind this rule was two sessions sharing one checkout and silently losing commits to a concurrent git switch. One worktree per session is the fix, and that isolation covers every command that writes to disk, not only git.

When Thomas reaches for it

What is in front of you Reach for
A ticket on the frontier with an empty assignee dispatch-ticket (claim, then worktree)
The dispatch itself, once claimed dispatch-ticket + the runtime-specific companion (dispatch-ticket-claude, -codex, -opencode)
A Shaper, QA or Rin needs a pane, not just a Builder Same skill, same mechanics; only the tab and pane label prefix changes
A pane went idle or blocked mid-turn WATCHING.md (companion reference, not a separate skill)
The Builder handed back and it is time to remove the worktree CLEANUP.md (companion reference)

Prerequisites

  • The workspace watchdog is running for this project. A dispatch with no watchdog is a hard stop, not a warning (exit 1, not an echo).
  • The harness payload is committed, not just allow-listed past .gitignore. A worktree only contains tracked content, so an untracked .agents/roles/builder.md means the Builder starts with no contract at all.
  • .agents/orchestrator.md has a real row (runtime, model, effort) for the role being dispatched. A row reading <set-me> is undecided, and undecided is a stop at dispatch time.
  • Read the contract for the dispatched role first (builder.md for a Builder), since this skill only carries the mechanics, not what the role is supposed to do with them.

What it leaves behind

What happened Where it lands
The claim The tracker’s assignee field: builder/<ticket-id>
The dispatch itself .astraler/state/dispatch-record.json, keyed by ticket id: branch, worktree, workspace, tab, pane, runtime, write-set
The worktree and branch <repo-root>/.claude/worktrees/<branch-slug>, gitignored, removed at cleanup
The brief Sent as the first line, a plugin-qualified slash command (/mattpocock-skills:implement <ticket>)
The Builder’s own work Commits on the ticket branch, pushed before handback

Known failures

Pulled from harness/.agents/memory/recurring-failure-modes.md. Everything below is marked promoted: fixed and already in the contract this page describes.

  • AST-016 / AST-027: two root sessions sharing one checkout silently lost commits to a concurrent git switch. Fixed: one worktree per session, no exceptions.
  • AST-036: a harness allow-listed but not committed is invisible inside every Builder worktree. Fixed: a commit check before the first dispatch.
  • AST-032 / AST-037: a multi-line brief pastes into the composer without submitting, and the pane reports idle while it sits unsent. Fixed: an explicit Enter after the paste, plus requiring the watcher to observe working before believing the turn began.
  • AST-097: TERMINAL:done means the turn ended, not that the work finished; a Builder parked on background work reads as done. Fixed: check OS processes and the runtime status line before concluding it finished.
  • AST-124: the per-turn watcher covers one turn and exits; nothing re-arms it, and the re-arm is the step skipped right after a long task. Fixed: every new turn gets a new watcher.
  • AST-092: a Builder that stops before committing leaves work that only exists on disk; git worktree remove deletes it silently. Fixed: “commit, push, then return” as three separate actions.

It’s working if

  • The watchdog was confirmed running before the first dispatch of the session, not assumed.
  • .astraler/state/dispatch-record.json has an entry for every live ticket, with a write-set.
  • Every submitted brief has a watcher armed against it within the same action, not as a separate step done afterwards.
  • A pane’s tab and pane labels match the role dispatched (builder:<id> versus spec:<id>, qa:<id>, rin:<id>), because a wrong prefix is invisible to the watchdog.
  • Cleanup only removes a worktree after git status --short is empty and check-simplify-markers.sh is green.

Where it fits

The frontier query (in thomas.md) decides which ticket is next → dispatch-ticket claims it and puts a builder role into a pane → the Builder runs its own closed loop (implement → review → simplify → /skills/codex-arm) and hands back → dispatch-ticket’s CLEANUP.md retires the worktree once the artifact is verified → a milestone gate goes through /skills/review-with-rin before merge. thomas and builder are the two role contracts this skill sits between.

Back to the skill catalog →