Uniform worker dispatch — landed evidence
One instruction dispatched six nodes across three backends — two external coding harnesses and the calling harness itself — with no change to the calling instruction and no harness named anywhere an agent reads. Eleven declared measures produced evidence. Two defects were found by the live runs and fixed; one deliberately constructed measurement did not fire, and is recorded as such.
Declared measures and what each produced
| Measure | Evidence | Verdict |
|---|---|---|
| End-to-end dispatch | Three nodes landed commits in detached worktrees, each git show --stat showing only its assigned path — § dispatch | pass |
| Uniformity | One node definition, two backends, identical instruction but for the backend override; both reached the same measured result — § uniformity | pass |
| Task contract enforced | Live rejection naming five failing properties at exit 2; 18 tests over the seven properties — § contract | pass |
| Escape hatch round-trip | An unprompted four-field report, answered and resumed in the same session, whose resumed turn restated its prior measurements without re-running anything — § escape hatch | pass |
| Durable delivery | 6 of 6 manifests on disk; the recovery ladder run in order on a real silent run, redispatch never the first response — § delivery | pass |
| In-harness branch | A directive carrying worktree, manifest path and four fences, bound to a real harness task by attach — § in-harness | pass |
| Both summaries | Dispatch and completion summaries captured verbatim, four axes each, completion WHY quantitative — § summaries | pass |
| Continuation at three altitudes | 12 tests including one end-to-end trace from worker manifest to sprint rollup; the plan altitude is refused at the write boundary — § continuation | pass |
| Budget signal captured | One backend recorded utilisation 1.02% and a reset time; the other legitimately unknown with tokens only. A test proves absence never reads as exhaustion — § budget | pass |
| No routing leakage | Three hits, all in a documented legacy-tier reader; a test now guards the property — § leakage | pass, one documented exemption |
| Suite and validators green | 1,598 tests pass, 103 of them new; lint clean; reckon doctor all checks passed — § suite | pass |
One call, six nodes, three backends
Every node went out through reckon crew dispatch. The call names no harness,
model, effort level or sandbox flag; those resolve from flight config inside reckon. The caller
branches once, on the returned launch kind.
| Node | Backend | Launch | Outcome | Scoped diff |
|---|---|---|---|---|
flight-check-a | external A | cli | complete after one escape-hatch round-trip | manifest only |
flight-check-b | external B | cli | complete first pass | manifest only |
docs-readme | external A | cli | commit 8a44624 | README.md only |
docs-agents | external A | cli | commit 0ae4167 | AGENTS.md only |
scope-fence | external B | cli | commit d3a7617 | worker-protocol.md only |
suite-native | calling harness | in-harness | complete, task bbgq1cuba | manifest only |
All three commits were audited with git show --stat before integration, each
touching exactly its declared write path, and merged sequentially with normal merge commits.
Six worktrees were then removed by the conservative cleanup — clean and reachable from the
integrated primary branch — leaving git worktree list with the main checkout
alone.
The three implementation nodes did real, previously missing work: the crew surface is now documented in the repository README, in the repository agent guidelines, and — as the live run record — in the worker protocol reference.
The same node, two backends, one instruction
Both invocations are reproduced in full. They differ in exactly two places: the node identity, which two concurrent runs must not share, and the backend override.
reckon crew dispatch --project reckon --plan uniform-worker-dispatch --section "§3" \ --role implement --node flight-check-a \ --goal "record the resolved worker-routing report for this checkout" \ --done-when "the manifest records the resolved default backend, the count of \ attributed provenance keys, and the exit status of the reckon flight command" \ --write-path <scratch>/flight-check-a-manifest.md \ --manifest <scratch>/flight-check-a-manifest.md \ --time-budget 15m --session uwd1 --set default_backend=A reckon crew dispatch --project reckon --plan uniform-worker-dispatch --section "§3" \ --role implement --node flight-check-b \ ... identical ... --time-budget 15m --session uwd1 --set default_backend=B
Reckon translated those into two entirely different argument vectors — different subcommand, different stream flag, different model and effort flags, different bypass flag — without the caller expressing any of it. The two workers then reached the same measured result independently:
backend A backend B
resolved default codex codex
provenance keys 36 36
attribution split host=27 host=27
shipped=9 (host supplies backend tuning,
shipped supplies fences)
flight exit status 0 0
That agreement is worth more than the dispatch succeeding twice: two independent harnesses, given the same fenced node and no shared context, produced the same number for a measurement neither was told the answer to.
A malformed node is refused before a worktree exists
The seven properties are checked before dispatch, so the escape hatch handles only the genuine residual. A live rejection, exit code 2, every failing property named in one pass so the node can be reshaped in one edit:
$ reckon crew dispatch --node bad \
--goal "add the parser and wire the CLI" \
--done-when "the code is clean" ... --dry-run
single-goal the goal joins deliverables with 'and'; split it into
one node per deliverable
demonstrable done-when rests on the subjective term(s) clean; name
what would be observed
demonstrable done-when emits no evidence; name a test, a command
output or a numeric result against a stated bound
scoped no exclusive write path is enumerated
independently-verifiable no manifest path is named, so completion could only be
judged by reading the implementation
[exit 2]
Exit codes are branchable: 0 succeeded, 1 the configuration or
request is wrong, 2 the node is not dispatchable. --dry-run runs the
same resolution and validation as a real dispatch — one code path, not two — so a whole
wave can be checked before any of it goes out.
One property earned its keep during implementation. Independently verifiable began as a tautology — dispatch always fills in a manifest path, so asserting one exists proved nothing. It now also requires that path to be absolute, which is a real failure mode: a relative path resolves against the worker's own worktree, so the orchestrator looks where the file will never be, reads a delivered node as silent, and redispatches work that already succeeded.
18 tests cover the seven properties, including the three the measure names — two goals, a subjective done-when, a missing write scope — and each asserts the rejection names its property.
The escape hatch fired on its own, and the round-trip closed
The measure asked for a worker deliberately driven to a NEEDS-HELP:
report. One fired without being driven at all, which is stronger evidence: node
flight-check-a finished its measurement, found that uv had created an
ignored environment outside its exclusive write fence, and refused to remove it unilaterally.
All four fields were present, unprompted:
NEEDS-HELP: the flight check passed, but uv created an ignored .venv outside
the write fence and two safe cleanup attempts could not remove it
tried: Ran the flight check once; it exited 0 and resolved codex with 36
attributed provenance keys. Cleanup with an exact validated
removal was rejected by the command safety layer before
execution; gio trash failed — unsupported on this mount.
options: (1) the orchestrator removes the exact worktree-local .venv;
(2) grant this node an explicit cleanup scope and a permitted
exact-directory removal mechanism; or (3) retain the ignored
environment as an acknowledged cache artifact.
leaning: Option 1, because the orchestrator owns worktree cleanup and can
remove the exact disposable environment without expanding this
node's write scope.
cost-if-wrong: Retaining it leaves an ignored 103-package environment in the
worktree; removing it only means a later uv command must
recreate the environment.
That is a decision brief, not a plea: the orchestrator answered it in one turn, accepting the worker's own leaning. The advice was resumed into the same session, and the resumed turn demonstrably retained prior context — asked to restate its measurements from memory without re-running anything, it returned:
I still have the measured result: 36 attributed provenance keys, split host=27 and shipped=9. I'll update only the assigned manifest — without re-running the flight command or touching .venv.
Those numbers match its first turn exactly, and the manifest was rewritten to
status: complete with the report block removed. The orchestrator then honoured its
half of the bargain and removed the 144 MB disposable environment itself.
Negative result: the constructed trigger did not fire
A second node, scope-fence, was constructed to force the same trigger — its goal
pointed at the maintainer notes while its write scope granted only the worker protocol. It did
not ask for help. It documented the run record inside its granted scope and finished
clean, which is a defensible reading of a contradictory instruction rather than a failure.
The honest conclusion is that a deliberately contrived contradiction is a poor way to exercise the hatch, because a capable worker resolves it instead. The organic case is the real evidence: the hatch fires when a worker meets a wall it genuinely cannot pass inside its fence. Its commit was reviewed on merit, accepted, and merged — with one repair, since its section renumbering left a cross-reference pointing at itself.
Durable delivery, and the recovery ladder used in anger
Six of six workers wrote their manifest to the orchestrator-named path. Two facts from the run matter more than that count.
A manifest existed before the worker was done. flight-check-a
reported manifest_present=true while its phase was still working — the
exact situation in which reading the message channel alone would have produced nothing and
redispatch would have duplicated a running node holding write scope.
The ladder found a real defect instead of burning a worker slot. After the
first resume, observe reported the run as neither complete nor working. Following the
ladder — check the manifest, then the on-disk evidence, then the logs — pointed at an empty event
log and a stderr file containing error: unexpected argument '-C' found. Redispatching
on the idle signal would have hidden that. Both consequences were fixed:
| Defect | Why the fixtures could not catch it | Fix |
|---|---|---|
The resume invocation was rejected outright: the working directory, model, effort and
output options belong to the exec command, not to its resume subcommand,
which takes only a session id and a prompt. |
Recorded event streams verify interpretation, never acceptance. A stream fixture cannot tell you the harness refuses an argument. | Options reordered ahead of the subcommand, verified live, and pinned by a test that asserts the ordering. |
A dead process with an empty log reported as starting, so a
launch that never began looked like one about to. |
The orphan rule only covered a log with events in it. | An empty log plus a dead process is now orphaned, and the phase names the
stderr log to read. |
Both were found by running the thing for real, which is the argument for dog-fooding rather than rehearsing.
The branch reckon cannot spawn
An in-harness backend is the calling harness's own delegation primitive, which
reckon cannot start on its behalf. So dispatch prepared everything else and returned a directive:
launch in-harness (pid: none — nothing was spawned)
worktree …/uwd1/suite-native detached, cut from the integrated base
fences scope …/suite-native-manifest.md
time 15m
evidence the manifest records the suite pass count plus the exit status
delivery …/suite-native-manifest.md
attach_with reckon crew attach --run <run-id> --task <task-id>
The harness then dispatched its own task against that directive, and
reckon crew attach --run … --task bbgq1cuba bound the real task identity to the
prepared record. The task ran the suite in the prepared worktree — 1,596 passed at the
integrated base — and wrote the manifest to the named path; observe read
the record back as complete with manifest_present=true, on the same
surface as a spawned run.
A second attach was refused: a second binding would hide which worker holds
the write scope.
One limit stated plainly rather than glossed: the bound task was a harness background task, not a harness subagent, because subagent dispatch was withheld in this session. The binding mechanism is identical — an opaque task identifier the harness owns — but the record should not be read as having exercised subagent delegation.
Both summaries, verbatim
Captured as emitted. Four axes each, at most two lines per axis, restating nothing the plan already says.
Dispatching wave 1 — 6 nodes
WHAT routing report ×2 (uniformity pair) · README + guidelines + run-record docs
· suite run via the calling harness
WHY the pair measures backend-independence of one instruction; the three doc
nodes are real undocumented surface; the suite node exercises the branch
reckon cannot spawn
HOW two external harnesses plus the calling harness, detached worktrees cut
from a927c9c, exclusive scopes below, manifests on named absolute paths
WHEN 15–20 min each; the end-to-end gate closes the wave — evidence stays shut
until a commit lands scoped clean with its manifest on disk
Wave 1 complete — 6/6 delivered, all eleven gates banked
WHAT 3 commits (8a44624, 0ae4167, d3a7617) + 3 manifest-only nodes
WHY gate evidence: 2 backends reached the same 36 provenance keys from one
instruction; 1,598 tests pass (103 new); 6/6 manifests on disk; budget
read utilisation 1.02% on one backend and unknown on the other
HOW every diff scoped clean on git show --stat; 6 worktrees removed by
conservative cleanup; 2 live defects found and fixed
WHEN next the run ledger, which promotes these pointers into committed
history — ready, nothing blocks it
The binding discipline held: the completion WHY carries the gate evidence
quantitatively. A validator enforces it, refusing a completion summary whose WHY
contains no number — which makes a wave that cannot state its measure visibly incomplete rather
than plausibly done.
Continuation closes at three altitudes
A chain closing only at plan level leaves the other two ends dangling. All three now close, and each is enforced rather than advised.
| Altitude | Mechanism | Enforcement |
|---|---|---|
| Worker | The manifest's follow_ons field becomes plan followup append ops carrying
the canonical one-line invocation. |
Tested: a manifest's candidate reaches a plan followup with the right prompt. |
| Plan landing | A writeback that resolves a followup or sets a terminal status must leave an open followup or record in words that the chain closes. | Refused at the write boundary, with a message naming the fix. Nothing is written on refusal. |
| Sprint close | feeds_sprints and unblocks per sprint row, derived from the
dependency graph. |
Tested, including that a same-sprint dependency is not downstream work and a cross-project edge is not claimed locally. |
The sprint altitude reads correctly against this repository's own graph on its first run: S5 feeds S6, S7 feeds S8, S8 feeds S9 — matching the delivery shape the architecture reference describes, without anyone writing it down.
The rule had to cover both write paths, and its scope was measured
The first implementation validated the ops writer only. A live probe found the gap
immediately: a plain HTTP patch marked a plan landed without going near that code. A rule one
curl can walk around is a courtesy, not a rule, so both paths now share one
predicate and the server answers 400 no_continuation — verified live, with the
plan's version and status unchanged afterwards.
Its scope was chosen by measurement rather than by taste. A state-level invariant — "a terminal plan must carry a continuation" — is the tidier rule and would have covered every path at once, so the portfolio was counted first: 155 of 202 terminal plans across the mounted projects carry no continuation, and all 155 would have become unwritable. The rule is therefore keyed to the write: only a new landing owes an answer, and recorded history stays editable. A test pins that, so the tidier rule cannot be adopted later without someone confronting the number.
Enforcing the plan altitude changed behaviour, and five existing tests had to be retargeted: each set a terminal status incidentally while testing something else — scalar mechanics, op ordering, worktree routing — and now use a non-landing value or carry the chain. One test was given a second open followup so its resolve remains a landing that still names what comes next.
Budget, captured asymmetrically and honestly
The two external backends disagree about what they report, and the record does not pretend otherwise. Both rows are real, from this wave:
| Backend A | Backend B | |
|---|---|---|
headroom | unknown | known |
utilisation_pct | — | 1.02 |
resets_at | — | 2026-09-01T00:00:00Z |
threshold_status | — | allowed_warning |
tokens | input 1,047,173 · cached 914,944 · output 6,785 · reasoning 2,690 | cache read 741,450 · created 59,283 · output 2,820 |
cost_usd | — | 0.620 |
detail | backend reports token usage but no headroom | backend reports utilisation and reset time |
Backend A's row is the one that matters. It shows a million input tokens and no headroom at
all — and a caller reading fields directly could read that as a spent budget. So
budget_exhausted() answers True, False or
None, and returns None for every unknown case. A test asserts it over
three real fixtures plus the empty and partial blocks: absence is never exhaustion.
Acting on the signal belongs to later work; this plan only guarantees the history exists.
No routing leakage, with one exemption stated
A grep for concrete model identifiers and provider names over skills/ and
reckon/, excluding the translation module, returns three hits:
reckon/capability.py:33: "haiku": "routine", reckon/capability.py:34: "sonnet": "general", reckon/capability.py:35: "opus": "orchestrator",
These are a legacy-tier reader: a compatibility map that translates identifiers found in plan state written before capability requests existed, documented in place as never emitted and never used to select a worker. Repository policy admits legacy tier metadata as compatibility input, so this is an exemption rather than a failure — but it is an exemption, not a clean sweep, and it is recorded as such. Nothing added by this work appears.
A one-off grep decays, so the property is now a test: it walks both trees, exempts the translation module and the legacy map by path, and fails with file and line on anything else. The two new agent-facing references name no harness, no command and no model — including the maintainer note, which describes launch mechanics as "one harness … another harness" throughout.
Where the implementation departs from the design sketch
| Sketch | Implemented | Why |
|---|---|---|
dispatch and attach as the CLI surface |
Also observe, resume, list and stop |
The declared measures are unreachable without them: observe is what folds a
stream, manifest presence and liveness into the run record, and resume is the
same-session round trip the escape hatch depends on. stop is a safety
counterpart — a dispatch mechanism with no way to stop a runaway worker holding write
access is not one to ship. Promotion into a committed ledger, and the read-side MCP view,
remain out of scope. |
| A dialect keyed to a backend | A dialect keyed to the backend's command |
Backend names are free-form user data — a config may call a backend fast —
while the command is the executable whose flags must be spoken. An unknown command raises
and lists what can be translated; there is no guessing fallback. |
| Workers deliver a manifest | Manifest paths must be absolute | A relative path resolves against the worker's worktree, so the orchestrator reads a delivered node as silent and redispatches successful work — the very failure the delivery fence exists to remove. |
Two limits found while running it, for whoever picks this up
The read-only tier cannot write its own manifest on one backend. The flight schema describes the tier as "no writes beyond the worker's own manifest file", but one harness's restrained mode blocks all writes, manifest included. Every node in this wave therefore ran at the worktree-bounded full-access tier — the plan's locked default — and the read-only tier's delivery channel remains unresolved. It is not a blocker for dispatch; it is a real gap for review and investigation roles.
Concurrency is configured but not enforced. concurrency resolves
per backend, and nothing in dispatch queues against it — the wave stayed inside the
cap because the orchestrator counted, not because reckon refused. Scheduling belongs to the work
that reasons about budget and in-flight state; until then the cap is advice to the caller.
Suite
$ uv run pytest -q
1598 passed in 44.81s (baseline before this work: 1495)
tests/test_backends.py 29 translation + observation, per dialect,
against streams recorded from live runs
tests/test_crew.py 54 the seven properties, routing, dispatch
atomicity, attach, observe, reports, reflex
tests/test_continuation.py 12 all three altitudes + one end-to-end trace
tests/test_skill_contracts.py +8 uniform instruction, checklist, gate-fence
sole authorship, reflex, no routing leakage
$ uv run ruff check reckon/ tests/ All checks passed!
$ uv run reckon doctor All checks passed.
$ uv run pytest -q (in a detached worktree, via the in-harness node)
1596 passed
103 new tests, no failures, no skips. The two suite counts differ by the two tests added after the in-harness node ran.