The done-guard (d16a3f5) landed after 0.25.0 was already tagged and published on95ac710, with the catalog ref pinned to it (catalog 01161f0). Moving a published tag would swap content under a name consumers may already have fetched, so the guard gets its own release instead. Version bumped in all seven places: plugin.json, package.json, the README badge, and the coord-send / board / route / dispatch skill frontmatters. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P4LMWBQGmufmBU6UdvJZ2E
8.4 KiB
| name | description | version |
|---|---|---|
| dispatch | Turn "start a session in repo X, on order Y, at cost Z" into a complete, verified startup command — the prompt written to a file, the model and effort derived from the rubric, and the output form chosen by whether the target repo already has a terminal pane. Use whenever work is being handed to a session in another repo, or to this repo's own next session: "dispatch a session in repo X", "start a session there with this order", "give me the startup command for repo Y", "hand this work to <repo>", "write the plan file for that session", "open a tab for X with this task", "how do I launch the next session on this". Also triggers on Norwegian phrasings: "dispatch en økt i repo X", "start en økt der med denne ordren", "gi meg oppstartskommandoen for Y", "send arbeidet til <repo>", "skriv planfila for den økten", "åpne en tab for X med denne oppgaven", "hvordan starter jeg neste økt på dette". Trigger even when no tool is named — producing a runnable startup command for another session IS this skill. Not for choosing WHICH repo deserves the next session (that is `board`), not for scoring model and effort alone (that is `route`), and not for sending a message to another repo (that is `coord-send`). | 0.26.0 |
dispatch — hand a session a task it can actually start on
A dispatch is one line the operator pastes and one file that line reads. Both
halves are easy to get wrong in ways that look right: a command with no prompt
in it, a plan file the driver silently discards, a --no-go that does not stop
what everyone assumed it stopped. All three were measured on 2026-08-16 — four
separate misfires in one day, by two different repos — and this skill exists so
they are not re-derived a fifth time.
You produce the command. You never run it. Starting a session in another repo spends the operator's quota and takes an action inside a repo this session does not own. Hand back the finished command and stop.
The engine
BOARD="${CLAUDE_PLUGIN_ROOT}/scripts/board.sh"
"$BOARD" --dispatch --repo <name> \
--prompt-file <absolute path> \
--target-pane <yes|no> \
--path <known|partial|undetermined> \
--verification <strong|weak|none> \
--reversibility <cheap|costly|one-way> \
--scope <local|multi-file|cross-cutting> \
--rationale "why these four scores"
It writes nothing and prints one block. Exit 2 means it refused — read stderr and fix the call; every refusal is a case where a command would have been wrong rather than merely imperfect.
It is board.sh and not a script of its own because the block format
(tab=/repo=/dir=/command=/paste=) has exactly one generator. Two
emitters of one file format is the drift defect this repo's CLAUDE.md warns
about.
The four steps, in order
1. Write the prompt file
The order goes in a file, in plain prose, and the file is what the session actually receives:
mkdir -p "$HOME/.claude/dispatch"
PF="$HOME/.claude/dispatch/<repo>-$(date -u +%Y%m%dT%H%M%SZ).prompt"
Runtime scratch, not repo content — but it must survive until the operator
pastes the line, so never write it to a directory that gets cleaned between
sessions. The path must be absolute and shell-clean (letters, digits, /, .,
_, -); --dispatch refuses anything else, because the path is expanded
inside the command while the contents are not.
Write the whole order: the concrete task, which discipline applies (Iron Law, TDD, which file the test goes in), and what must not be triggered. A prompt that says only "continue" forces the receiving session to guess its task out of STATE.md, which is the thing handing over a prompt is supposed to prevent.
Norwegian prose, æøå, quotes, $ and backticks are all fine in the file. That
is measured, not assumed: "$(cat file)" hands the bytes to the session as one
argv element with no re-evaluation. The ASCII rule applies to shell and hook
code, not to a prompt travelling through argv.
2. Measure whether the target already has a pane
morning --probe-panes | grep "<absolute dir of the target repo>"
A hit means --target-pane yes. Measure it; never assume it. This is the
one input --dispatch refuses to default, for the same reason route.sh
refuses to default --last-effort: it is a fact about the world, and guessing
it produces a dispatch that verifies green and opens nothing.
Two facts about this measurement, both verified 2026-08-16 against the installed
morning:
--probe-panesworks from a Claude session, without a tty. It cannot identify the anchor pane, but theDIRcolumn — the part you need — is there.- A session dispatching its own next session is always
--target-pane yes. That is not a special case for one repo; it is what self-dispatch is, and it is where all four of the day's misfires landed.
3. Score the four traits and call --dispatch
Scoring is judgement and it is yours; the model, effort and advisor flag are a
lookup and are route.sh's. Score the task the dispatched session will do,
using the route skill's trait table.
--dispatch deliberately takes no --model/--effort. --advisor opus is a
property of the rubric row — two rows share a model/effort pair while
differing on it, and the CLI accepts a wrong advisor silently — so a dispatch
that took the model directly would have no honest source for that flag. If the
right call is a Fable row, the rubric cannot produce it: write that command by
hand, and say in the handover that it is a recorded override, running without an
advisor.
4. Verify, then hand it over
--target-pane no (plan-file form). Write the whole output to a file and
dry-run it:
"$BOARD" --dispatch ... > "$HOME/.claude/dispatch/<repo>-<ts>.plan"
morning --plan-file "$HOME/.claude/dispatch/<repo>-<ts>.plan" --dry-run
Expect opening: 1 of 1. Then hand back:
morning --plan-file <path to the plan file> --no-go
Know what that dry-run does not prove. It proves the block parses and yields
a command. It does not answer the pane question: run from a Claude session
there is no tty, so morning reports window: unknown ... assuming an empty window and plan_drop_open never fires. A gate built on the dry-run would pass
the self-dispatch case every single time — the one case it would exist to catch.
Step 2 is the measurement; this is a parse check.
--target-pane yes (paste-only form). There is no plan file, deliberately:
morning's plan_drop_open (morning:1788) drops a block whose repo already has
a pane. Hand back the paste= line, and say it goes in the existing tab after
/exit. Never prefix it with cd — one repo per terminal tab, and the
operator is already standing in that one. morning --relaunch bypasses the
filter but opens a second tab beside the existing one, which is rarely wanted.
Three things that must reach the operator
Say these in the handover, not only in the plan file. Each was a real correction, not a hypothetical:
- The command carries the prompt in argv.
claude --model X --effort Yon its own is not a dispatch; it is a session waiting for someone to tell it what to do. Delivered bare twice on 2026-08-16, corrected by the operator with "gi meg alltid komplette oppstartskommandoer for nye sesjoner". --no-godoes not make the session wait. It suppresses only the follow-up Go message —morning:806is exact: "--no-go says nothing is typed once the startup command is in". The startup command, prompt and all, is typed regardless, so the dispatched session starts working on its own. An operator decision was once taken on the opposite premise and had to be corrected before the run.- Which form you produced, and why. "Plan file, because
<repo>has no pane" or "paste line, because<repo>already has one and a plan block for it would be dropped". The form is a consequence of a measurement, and the operator should be able to see the measurement.
Where a dispatch is not enough
The prompt file is scratch: it carries the order to one session and nothing
records it afterwards. When the receiving repo needs a durable record of the
order — something its next session will still see after this one is gone — send
it a coord-send message as well. The dispatch starts the session; the mailbox
is what makes the order survive it.