A full work-package review walk (PR #1877, planning folder 2026-07-28-review-midnight-node-pr-1877) was measured end to end: 921 tool calls, 33 dispatches, 4,130,657 subagent tokens, 3h 51m agent time. Splitting its 21 activity entries by dispatch count gives the governing result:
| Group |
Activities |
Tool calls |
Tokens |
tok/call |
| Single-dispatch |
11 |
369 |
1,141,290 |
3,093 |
| Multi-dispatch (resumed) |
10 |
552 |
2,989,367 |
5,416 |
Cost tracks dispatch count, not call count — ratio 1.75×. Applying that delta across the 552 multi-dispatch calls implies ~1,282,000 tokens, 31% of the run, is re-dispatch overhead. That corroborates by an independent route the run's own attribution of ~1,020,000 tokens (24.7%) to its 12 resumed dispatches.
It is emphatically not long-context thrash inside a single worker. codebase-comprehension ran 88 calls in one dispatch at 2,543 tok/call — the cheapest in the run. submit-for-review ran 65 calls across three dispatches at 7,621 — the dearest. Long activities are cheap; re-dispatched activities are expensive.
What causes the re-dispatches: checkpoints firing mid-activity. The run resolved 10 checkpoints and paid 12 resumes; per its own trace, the resumes were "checkpoint continuations, and one recovery from an organisation spend limit" — so ~10 of 12 are checkpoint-driven, at roughly 116K tokens each. Of the 8 client checkpoints that fired, mapped against their step position in the definitions:
| Checkpoint |
Activity |
Step position |
Steps after |
local-validation-permission |
11-validate |
0 of 11 |
10 |
file-index-table |
10-post-impl-review |
3 of 18 |
14 |
unsigned-commits-prompt |
12-strategic-review |
2 of 14 |
11 |
review-summary-approval |
13-submit-for-review |
5 of 32 |
26 |
research-convergence#pass-1 |
04-research |
5 of 20 (loop body) |
14 |
retrospective-confirm |
14-complete |
7 of 11 |
3 |
ticket-completeness |
02-design-philosophy |
9 of 11 |
1 |
review-findings |
12-strategic-review |
13 of 14 (last) |
0 |
Seven of eight fired mid-activity. Only review-findings sat at the boundary, where a yield is free.
This issue tracks two PRs. The server change is a hard prerequisite for the corpus change, so they cannot be reviewed in either order.
PR 1 — server (main)
1.1 Scope the delivery ledger to a worker context — the ~25–31% item
Two rules look like they contradict each other:
workers-need-full-delivery: "Dispatched workers are fresh contexts with no prior deliveries… never instruct a worker to pass bundle: "reference": an unchanged-reference points at content the new worker has never received."
resume-is-optimisation: "Harness-level resume preserves the context window."
The rule is not the defect — the ledger is. deliveredHash reads state.deliveredContent[state.agentId][key] (src/utils/delivery.ts:44), and agentId is the session's agent id, shared by every worker dispatched against that session. Reference delivery on a worker session would therefore hand worker B unchanged-markers for content worker A received. workers-need-full-delivery is a correct guard over a ledger that cannot distinguish worker contexts. It can only relax once the ledger can.
1.2 Add the per-call reference opt-in to get_technique and get_resource
get_activity already has one: bundle: "reference" works independently of session mode (src/tools/workflow-tools.ts:674). Techniques and resources do not — they gate on state.contextMode === 'persistent' alone (src/tools/resource-tools.ts:738, :764, :847), with only full: true to force the other way. Without this, a resumed worker cannot dedup the 86 technique and 30 resource deliveries this run paid for, and 1.1 delivers only part of its value.
1.3 Ledger the invisible third — the instrument for verifying 1.1 and 1.2
You cannot confirm 1.1 worked without this, and three gaps are measurable in the run's own session.json:
1.4 Guard: a checkpoint may not be an activity's first step
Guards live in the server tree (scripts/check-*.ts, registered via scripts/check-all.ts), so the mechanical half of the corpus fix in 2.2 belongs here.
PR 2 — corpus (workflows)
Merges after PR 1. Relaxing the delivery rule before the ledger is context-scoped would hand workers each other's unchanged-markers.
2.1 Relax workers-need-full-delivery to key on context identity
2.2 Delete checkpoint-at-entry in 11-validate
workflows/work-package/activities/11-validate.yaml opens with steps[0] = kind: checkpoint, id local-validation-permission. The worker is spawned, pays full delivery, immediately yields, and is resumed — the entire first dispatch exists only to ask a question. validate cost 92,793 tokens over 2 dispatches for 18 tool calls.
It is also the wrong owner: the checkpoint asks whether the local environment can run the validation suite and sets run_local_validation / mark_progress_na. That is an environment-capability question, i.e. a dispatch precondition, not worker work.
2.3 Submodule pointer and e2e re-baseline
Same obligation as #348 §1 — 2.1 edits meta techniques, which the e2e walks enumerate.
Deliberately out of scope
| Item |
Why excluded |
| Trace-token emission |
The run's trace_tokens resolved empty, so L7 produced nothing and error/validation-warning history is unavailable for the whole walk. But this needs diagnosis before it can be scoped: on server v2.1.0 a next_activity call returned {activity_id, name, session_index} with no _meta envelope at all, so there was no trace_token for an orchestrator to accumulate. Whether that is a bug or conditional-by-design is unknown — do not put an undiagnosed item in a PR scope. Worth its own issue. |
| Artifact handoff digests |
403 KB of planning artifacts across 21 files (57 KB assumptions log, 50 KB structural analysis, 40 KB research doc) are re-read on every cold start, ~7% of the run. Deliberately sequenced after re-measuring, because 1.1 changes the cold-start baseline this would be sized against. Overlaps 2026-07-17-slim-work-package-planning-artifacts and 2026-07-28-workflow-design-slim-down. |
| Repo-binding waste |
The abandoned first meta run (wrong repo binding) burned 81,762 tokens, 2%. Already addressed by #345 / #348 / #349 — verify rather than re-derive. |
| Packaged execution manifests |
The idea that opened this analysis: deliver each activity's resolved execution manifest to the planning folder to cut tool calls. Measured and dropped. ~157 of 921 calls are server protocol and the packageable subset is 54 — 5.9% of calls, ~0% of tokens, since a fresh worker needs the content in its context window regardless of transport, and the filesystem path forfeits reference delivery and #section slicing. 83% of calls are the agent's own domain work. Rationale in the planning folder. |
Splitting post-impl-review |
It is the run's heaviest activity (133 calls, 641,275 tokens, 42m) and "split the big one" is the obvious move. The data says it is wrong: single-dispatch activities are the cheapest per call, and splitting adds dispatches. Split only where the split lands on a mid-activity checkpoint — and note that is an alternative to 1.1, not a complement, since once a resume is cheap, keeping it beats paying a second cold start. |
Success criteria
Re-run a comparable work-package walk after both PRs merge and compare against this baseline:
- Multi-dispatch tok/call falls from 5,416 toward the single-dispatch 3,093 (a full close would recover ~1.28M tokens on a run of this size)
activity_usage event count equals actual dispatch count, not 11-of-33
- Delivery events carry byte counts, so the payload figures in the planning folder stop being estimates
- No corpus activity opens with a checkpoint
Context
A full
work-packagereview walk (PR #1877, planning folder2026-07-28-review-midnight-node-pr-1877) was measured end to end: 921 tool calls, 33 dispatches, 4,130,657 subagent tokens, 3h 51m agent time. Splitting its 21 activity entries by dispatch count gives the governing result:Cost tracks dispatch count, not call count — ratio 1.75×. Applying that delta across the 552 multi-dispatch calls implies ~1,282,000 tokens, 31% of the run, is re-dispatch overhead. That corroborates by an independent route the run's own attribution of ~1,020,000 tokens (24.7%) to its 12 resumed dispatches.
It is emphatically not long-context thrash inside a single worker.
codebase-comprehensionran 88 calls in one dispatch at 2,543 tok/call — the cheapest in the run.submit-for-reviewran 65 calls across three dispatches at 7,621 — the dearest. Long activities are cheap; re-dispatched activities are expensive.What causes the re-dispatches: checkpoints firing mid-activity. The run resolved 10 checkpoints and paid 12 resumes; per its own trace, the resumes were "checkpoint continuations, and one recovery from an organisation spend limit" — so ~10 of 12 are checkpoint-driven, at roughly 116K tokens each. Of the 8 client checkpoints that fired, mapped against their step position in the definitions:
local-validation-permission11-validatefile-index-table10-post-impl-reviewunsigned-commits-prompt12-strategic-reviewreview-summary-approval13-submit-for-reviewresearch-convergence#pass-104-researchretrospective-confirm14-completeticket-completeness02-design-philosophyreview-findings12-strategic-reviewSeven of eight fired mid-activity. Only
review-findingssat at the boundary, where a yield is free.This issue tracks two PRs. The server change is a hard prerequisite for the corpus change, so they cannot be reviewed in either order.
PR 1 — server (
main)1.1 Scope the delivery ledger to a worker context — the ~25–31% item
Two rules look like they contradict each other:
workers-need-full-delivery: "Dispatched workers are fresh contexts with no prior deliveries… never instruct a worker to passbundle: "reference": an unchanged-reference points at content the new worker has never received."resume-is-optimisation: "Harness-level resume preserves the context window."The rule is not the defect — the ledger is.
deliveredHashreadsstate.deliveredContent[state.agentId][key](src/utils/delivery.ts:44), andagentIdis the session's agent id, shared by every worker dispatched against that session. Reference delivery on a worker session would therefore hand worker B unchanged-markers for content worker A received.workers-need-full-deliveryis a correct guard over a ledger that cannot distinguish worker contexts. It can only relax once the ledger can.deliveredContenton that context id rather thanstate.agentId, preserving the existing shape for solo persistent walks.force-full-after-summarization(bundle: "full"/full: true) as the escape for a resume that did not preserve context.1.2 Add the per-call reference opt-in to
get_techniqueandget_resourceget_activityalready has one:bundle: "reference"works independently of session mode (src/tools/workflow-tools.ts:674). Techniques and resources do not — they gate onstate.contextMode === 'persistent'alone (src/tools/resource-tools.ts:738,:764,:847), with onlyfull: trueto force the other way. Without this, a resumed worker cannot dedup the 86 technique and 30 resource deliveries this run paid for, and 1.1 delivers only part of its value.get_techniqueandget_resource, mirroringget_activity'sbundleparametercontextMode === 'persistent'default path intact1.3 Ledger the invisible third — the instrument for verifying 1.1 and 1.2
You cannot confirm 1.1 worked without this, and three gaps are measurable in the run's own
session.json:activity_usagefired 11 times against 33 dispatches. No event type represents a resumed dispatch, an out-of-band dispatch, or an abandoned session, so cost accounting understated the run by a third. Emit a dispatch event carrying a fresh/resume discriminator.technique_bundled/technique_fetched/resource_fetcheddataholds onlytechniqueId/resourceId/stepId, so delivery cost is unmeasurable from the ledger — every payload figure in the planning folder is an estimate for exactly this reason. Add a char count.1.4 Guard: a checkpoint may not be an activity's first step
Guards live in the server tree (
scripts/check-*.ts, registered viascripts/check-all.ts), so the mechanical half of the corpus fix in 2.2 belongs here.steps[0].kind === "checkpoint", wired intocheck-allPR 2 — corpus (
workflows)Merges after PR 1. Relaxing the delivery rule before the ledger is context-scoped would hand workers each other's unchanged-markers.
2.1 Relax
workers-need-full-deliveryto key on context identityworkflow-engine::dispatch-activityandharness-compat::continue-agentcarry the worker-context id, and request reference delivery on the resume path onlyforce-full-after-summarizationas the escape at both call sites2.2 Delete checkpoint-at-entry in
11-validateworkflows/work-package/activities/11-validate.yamlopens withsteps[0]=kind: checkpoint, idlocal-validation-permission. The worker is spawned, pays full delivery, immediately yields, and is resumed — the entire first dispatch exists only to ask a question.validatecost 92,793 tokens over 2 dispatches for 18 tool calls.It is also the wrong owner: the checkpoint asks whether the local environment can run the validation suite and sets
run_local_validation/mark_progress_na. That is an environment-capability question, i.e. a dispatch precondition, not worker work.2.3 Submodule pointer and e2e re-baseline
Same obligation as #348 §1 — 2.1 edits
metatechniques, which the e2e walks enumerate.workflowssubmodule pointer in the server tree to the merged PR 2 commitnpm run baseline:stampand commit the refreshedtests/e2e/__snapshots__/corpus-sha.jsonandsnapshot.test.ts.snapin the same commitDeliberately out of scope
trace_tokensresolved empty, so L7 produced nothing and error/validation-warning history is unavailable for the whole walk. But this needs diagnosis before it can be scoped: on server v2.1.0 anext_activitycall returned{activity_id, name, session_index}with no_metaenvelope at all, so there was notrace_tokenfor an orchestrator to accumulate. Whether that is a bug or conditional-by-design is unknown — do not put an undiagnosed item in a PR scope. Worth its own issue.2026-07-17-slim-work-package-planning-artifactsand2026-07-28-workflow-design-slim-down.#sectionslicing. 83% of calls are the agent's own domain work. Rationale in the planning folder.post-impl-reviewSuccess criteria
Re-run a comparable
work-packagewalk after both PRs merge and compare against this baseline:activity_usageevent count equals actual dispatch count, not 11-of-33Context
.engineering/artifacts/planning/2026-07-30-packaged-execution-manifests/—README.md,attestation-options.md,run-analysis-pr1877.md,optimisations.mdmidnight-agent-eng/.engineering/artifacts/planning/2026-07-28-review-midnight-node-pr-1877/(14-token-usage.md,14-session-trace.md,session.json)2026-07-16-token-usage-reductions(technique bundling already at a 74% hit rate — this run confirms 62 bundled against 24 fetched)main, corpus feat(meta): derive the host-repo binding from git instead of workspace prose #345 →workflows)