Skip to content

Send once: a delivery stops repeating what it has already handed over, and says where the context stands - #441

Merged
m2ux merged 7 commits into
feat/delivery-cost-resolve-oncefrom
feat/delivery-cost-send-once
Aug 7, 2026
Merged

Send once: a delivery stops repeating what it has already handed over, and says where the context stands#441
m2ux merged 7 commits into
feat/delivery-cost-resolve-oncefrom
feat/delivery-cost-send-once

Conversation

@m2ux

@m2ux m2ux commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

Three defects with one theme: content the server has already handed over once. A single response
carried the same rule and contract blocks several times. Two calls asking for the same technique were
each answered in full. And the answer telling a worker whether it may take another activity was
emitted somewhere a worker does not reliably read.

Work items W7, W9 and the server half of W8 of the delivery-cost epic #404. Stacked on #440, which
this branch includes.

A shared block is sent once per response — W7

Every composed technique in a delivery carries the contract blocks and rules it inherits from its
container, so a response bundling five step techniques carried five copies of the same text — 16,453
characters byte-identical in the worst case the review measured. The pass that removes them ran only
where the caller had asked for reference delivery, which is exactly not the case a freshly spawned
worker is in, and that worker is the one whose budget is tightest.

The pass now runs on every delivery, with readLedger selecting what a marker may point at:

  • Reference delivery — a block this context received on an earlier call collapses, as before.
  • Full delivery — only a block an earlier entry of this same response already carries in full
    collapses. The bytes are always above the marker in the payload the marker arrives in, so a context
    holding nothing can still resolve it.

The response says so. Where a full delivery collapses anything, it carries a note pointing the reader
at the earliest step_techniques entry showing that block, rather than the reference-mode note about
content already in the reader's context.

Measured over npm run bench:batch's three-activity run of the main workflow: a fresh worker per
activity receives 213,476 characters where it received 225,617 — about 4,000 characters an
activity, roughly a thousand tokens a dispatch. The batched pass drops too (161,847 → 152,553),
because a batch's first activity is a full delivery as well.

A repeat fetch arrives as a marker — W9

A ledger entry means one thing: this scope received these bytes in full. So a second ask for the same
content is answered with a marker whatever delivery mode the call declares. One measured run re-sent
67,772 characters over 18 repeat fetches — 12 to 17 per cent of everything it fetched on demand — one
of them the same 15,126-character dispatch guidance twice inside 46 seconds, in one uninterrupted
worker run.

Two conditions keep this sound, and both are tested:

  • The caller must name its context. With agent_id omitted the scope falls back to the session's
    own identity, which sibling workers share — a marker would then reach a context that never received
    the bytes. Nothing collapses for an unnamed caller.
  • full: true still serves the whole body, which is the escape hatch for a context that
    summarized the content away.

The batch standing arrives where a worker reads it — W8

The field a worker reads to know it may take another activity was emitted in _meta.batch only. On
the 5 August run no context anywhere took a second activity and no refusal was recorded either —
nothing was refused because no continuation was ever attempted. A limit no worker can read is a limit
that cannot bind.

The standing now leads the response text as a batch: block — activities, max_activities,
delivered_chars, budget_chars, may_continue, and a sentence saying what to do with the answer —
as well as staying in _meta.batch. This is the same reason artifact_prefix is in the response
header: the text is the surface a worker is certain to read.

batchState now takes the pending delivery, so the standing a response carries counts the activity
and the characters that response is delivering, without composing the payload twice to find out. The
block and _meta report one figure, which a test asserts.

What this does not establish. That a run then actually forms needs a real session against a
server build carrying this change. The read to make afterwards: activity_dispatched events grouped
by agentId — a scope holding two or more activities is a run that formed — and any batch_refused
event, which now means a worker read the standing and asked anyway. The 5 August baseline is four
setup activities under four identities and twelve client activities under thirteen, with no refusal
anywhere.

Scope of change

  • src/utils/delivery.tsreadLedger, countCollapsedBlocks, and the module contract for what
    makes a marker readable.
  • src/tools/workflow-tools.ts — the dedup pass on every delivery, the full-mode note, the batch:
    block.
  • src/tools/resource-tools.ts — the repeat-fetch collapse and the two tool descriptions.
  • src/utils/batch.tsbatchState takes a pending delivery.
  • docs/dispatch_model.md — where the standing is reported.
  • tests/send-once.test.ts (new, 9 tests), tests/reference-delivery.test.ts (two tests restated).

No schema change.

Two restated tests, and why

Two assertions in tests/reference-delivery.test.ts encoded the behaviour this branch changes, so
they now assert the new contract rather than being suppressed:

  • "repeats the full bundle on every call and never emits markers" — a full delivery still never
    references content from an earlier call, and every composed technique still arrives whole. What it
    no longer does is repeat a shared block within one response. The byte-identity assertion now
    compares the payload rather than the whole response, because the batch standing that leads it is
    live state and moves by design.
  • "leaves get_technique and get_resource in full delivery without the opt-in" — replaced by the two
    assertions that carry W9's contract: a named context asking twice gets a marker, an unnamed caller
    never does.

Verification

  • npx tsc --noEmit clean.
  • Full suite: 1,005 tests, all passing.
  • All 24 guards pass.
  • npm run bench:batch reports the figures quoted above.

Non-goals

  • The activity body, which is the one part of a delivery that still cannot collapse. That is W10 and
    it lands on top of this.
  • The eager bundle's budget behaviour. A marker costs nothing against the budget, so freed headroom is
    spent sending resource bodies the first delivery could not afford — that is the budget working.
  • Cheap-fetch guidance to agents, which is W3 and belongs to the corpus.

Investigation detail

engineering/artifacts/planning/2026-08-06-startup-cost-on-real-runs
— the repeat-fetch tables and the batching-formed-no-run finding.
engineering/artifacts/planning/2026-08-04-solid-affinity
— the duplicate-block measurement and why no relevance threshold was added.

m2ux added 3 commits August 6, 2026 12:02
A response repeats the contract and rules blocks its techniques share. Those
blocks now collapse to a marker from their second copy on, and the first copy
ships in full, so the bytes a marker stands for are always above it in the same
payload — readable by a freshly spawned worker holding no prior delivery.

dedupTechniqueBlocks takes readLedger: it consults this scope's earlier
deliveries only where the caller asked for reference delivery, and always
consults what this response has already staged.

Measured over the batch benchmark's three-activity run: a fresh worker per
activity receives 213,476 characters where it received 225,617, about 4,000
characters an activity.
A ledger entry says a scope received a payload in full, so a second ask for the
same bytes is answered with a marker whatever delivery mode the call declares —
the content is in the asking context already.

Two conditions keep it sound. The caller must name its context: with agent_id
omitted the scope falls back to the session's own identity, which sibling
workers share, so a marker could reach a context that never received the bytes.
And full: true still serves the whole body, for a context that summarized the
content away.

One measured run re-sent 67,772 characters over 18 repeat fetches, one of them
the same 15,126-character dispatch guidance twice inside 46 seconds.
A worker decides whether to ask for another activity from may_continue, so the
answer rides in the response text as a leading batch: block as well as in
_meta.batch — the same reason artifact_prefix is in the header.

batchState takes a pending delivery, so the standing a response carries counts
the activity and characters that response is delivering without composing the
payload twice. That keeps the block and _meta reporting one figure.

The payload still repeats byte for byte across two identical calls; the standing
is live state and moves, which the reference-delivery test now measures over the
payload rather than the whole response.
m2ux added 2 commits August 6, 2026 13:26
…a marker

What to do with may_continue is owned by the worker role technique every activity
bundle carries, so the block carries the reading and not a third copy of the
instruction. That takes it from 262 characters to 112 on every delivery, which
matters on an activity light enough to have no repeated blocks to collapse.

The resolution model described one ground for a marker, reference delivery, and
asserted twice that a fresh or default session always receives full bodies. There
are three grounds now, two of them needing no opt-in because the bytes
demonstrably reached the asking context, and the doc sets out which call each one
governs.
m2ux added 2 commits August 6, 2026 18:08
Naming a context is evidence of one context only where the name belongs to one.
dispatch_child defaults agent_id to "worker", which is the session's own
identity, so two sibling workers can each pass it without either having received
what the other did.

That scope keeps its earlier behaviour: it collapses on a declared reference
opt-in, which is a claim about one context, and not on the name alone. A solo
walk legitimately owns the identity and declares context_mode: "persistent", so
it collapses on that ground.
@m2ux
m2ux merged commit 5d69aab into feat/delivery-cost-resolve-once Aug 7, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant