Delivery cost and closed gates: the server answers what it already knows, and the cost gate runs - #467
Merged
Merged
Conversation
…he cost gate Delivery corrections over the 12-activity work-package walk the delivery-cost benchmark walks. Total delivery falls from 1,780,292 characters to 1,296,139 — 484,153 fewer, 27.2% — and get_activity from 987,370 to 518,185. The server holds the variable bag and ships two reference gate evaluators, and nothing under src/tools imported either: every gated step was treated as undecidable and kept lazy, 89 of work-package's 174 technique steps and 12 of meta's 23. A gate now answers true, false, or nothing at all, and a step joins the eager bundle on a true — every variable it compares already bound, none of them produced inside this activity. An unbound read and an unparseable expression answer nothing rather than false, so no step can lose its delivery path to an authoring defect. Block deduplication was gated behind one session-scoped boolean answering two questions at once. Whether content already reached this context needs the ledger and a context that retains what it was sent. Whether it already appears in the response being assembled needs neither: the earlier copy travels in the same payload, so that pass now runs in every mode. Composition merges each ancestor group's rules into every technique it covers, so a response bundling ten techniques of one group carried those rules ten times. The invariant blocks — the worker technique bundle, its rules, the inherited activity rules — hold three distinct values across all 20 activities of the two workflows. A scope the server has already delivered an activity to is that same context arriving again, since the orchestrator holds one agent_id for as long as a worker carries its batch, so its own ledger describes what it holds whatever mode the session declares. Forcing full delivery re-delivers them, and resuming with a fresh context mode drops that scope's ledger entries. Resource ids extracted from a technique body are qualified against the workflow the technique file was found in. A bare link in a meta technique names a resource under meta/resources whoever binds it; qualified against the activity's workflow instead it resolved to nothing, and the step executed without its template. A resume compares the workflow version it loads against the one recorded. Defaults were seeded only at creation, so a declaration added since was absent from the bag and a gate on it read unbound; the resume seeds what the bag lacks, leaves written values alone, and re-stamps the version. A lazy technique fetch resolves a step id against the session pointer, which any context in the session can move, and had nothing to compare against the dispatch it was made for. It takes an optional activity_id and errors on a mismatch naming both ids. next_activity reports where the exiting worker stands when given its agent_id and window — read at the boundary, so the reading counts the lazy fetches that activity made rather than predating them. Four instruments price this system and the one that prices a WALK ran in no job, no guard registry and no test, because delivery cost is a property of a walk rather than of a file. Verify now runs it on every pull request at the 1% default against a baseline recorded on the pinned corpus commit, so a definition change that adds delivery is priced at merge: confirm the increase, re-record the fixture in the same commit, and say in its description what the corpus gained. Two records carried an authority nothing checked. The binding triage's 69 verdicts are judgements about definitions as they stood at a corpus commit it records; the guard reports how far the corpus has moved since — 178 commits — without failing on it, since a verdict usually survives edits elsewhere and a stale entry is already reported by name. The session census answers which runs a definition edit reaches mid-flight and was reachable from no npm script; it is now sessions:census. The delivery cost line reports the worker-bundle size and the steps each gate answer left lazy, and the eager tally opens at what the worker bundle costs — measured at 35,204 characters, about half a typical activity delivery. Corpus pointer moves to 34cd542 with the walk snapshots, corpus stamp and site data re-recorded against it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…a pointer The corpus pointer takes the four definition fixes, with the walk snapshots, corpus stamp, site data and delivery-cost baseline re-recorded against it. The work-package dispatch of the analysis workflow brings the shared meta operation's caller-supplied session index with it, which the triage register already carries a verdict for under two sibling workflows. The batch bound policy comment restated what docs/dispatch_model.md already says, so it points there instead. The measurements in that section are re-taken: the benchmark's three activities now cost 159,093 characters batched against a 280,000-character budget, 57% of it, so the activity cap binds where the budget used to. Revising either value still needs the context establishment a byte count cannot see. The step-gate test on the client activity loop asserted an exact step list, which made any trailing step a failure. It now checks the hazard that list was standing in for: a step after the loop that writes the pointer re-primes a spent walk. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ation-remediation # Conflicts: # tests/e2e/__snapshots__/corpus-sha.json # workflows
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An evaluation of the meta and work-package workflows found 52 ways they cost more to run than their content requires. Its central observation was that almost every saving already had working machinery in the repository, built and tested, wired to nothing. This branch connects the largest of those, and closes the definition gates that could never open.
One 12-activity work-package walk cost 1,780,292 characters of definition delivery this morning. It now costs 1,296,760 — 483,532 fewer, 27.2%, roughly 121,000 tokens a walk. The activity payloads fell 47.5%, and the walk issues two fewer technique fetches.
The full measured delta, taken with the delivery-cost benchmark against the same walk, the same policy and the same corpus:
get_activitycharactersget_techniquecallsFor scale, the frozen July reference recorded 1,355,532 characters on the same walk, so delivery is now below where it stood 32 days ago despite the corpus having grown throughout.
What happened today, and why nothing reported it
The server declined to answer questions it could answer. It holds the whole variable bag, and it ships two working evaluators for the gate expressions the definitions use. Nothing in the tool layer imported either one. So the delivery layer treated every gated step as undecidable and refused to bundle it — 89 of work-package's 174 technique steps and 12 of meta's 23 — even where the gate turned on a mode variable bound in the first activity and never touched again. A worker fetched each of those separately, one round trip apiece.
One boolean answered two unrelated questions. Every byte-saving path sat behind a single session-scoped flag. That flag was asked both "has this content already reached this context" — which needs a ledger and a context that keeps what it was sent — and "does this content already appear in the response I am assembling right now", which needs neither, because the earlier copy travels in the same payload as the marker pointing at it. Composition merges each ancestor group's rules into every technique that group covers, so a response bundling ten techniques of one group carried those rules ten times, and the flag being off meant it kept doing so.
A worker was re-sent what it was holding. The worker technique bundle, its rules, and the workflow rules every activity inherits are the same content on every activity of a walk — three distinct values across all twenty activities of the two workflows. The orchestrator keeps one agent identity for as long as a worker carries its batch, so a second delivery under that identity is the same context arriving again. The server had that evidence in its own ledger and did not use it, because the session declared its workers disposable.
The instrument that prices a walk ran nowhere. Delivery cost is a property of a walk rather than of a file, so no guard can reach it. The benchmark that measures it was declared in the package manifest and appeared in no job, no guard registry and no test. Run against its own reference it failed at +31.3%, with 82% of the increase in the two calls whose content is the definitions themselves.
Three records carried an authority nothing checked. A resume compared four kinds of drift and never the workflow version, so a session resumed after a definition edit ran today's protocol against a bag seeded under last week's declarations — and the success signal and the failure signal were the same value. The binding triage's 69 human verdicts record the corpus commit they were made about, in a field nothing compared. The script that answers how many runs a definition edit reaches mid-flight was reachable from no command.
Four gates could not open. In meta, the flag deciding whether to revise the session metrics defaults to false and its only writer also sets it false, so the revision never ran — and three separate files describe the trace and usage artifacts as drafts that revision rewrites. In work-package, the issue-type enum declares five categories, the branch-prefix table mapped four, left two of those four to be chosen between two prefixes with no rule, and named none for an epic; the prefix itself was an unanchored reference no declared input resolved, so an epic-typed work package reached branch composition and the agent invented a value two runs would disagree about. The complex-problem path into the analysis workflow was an action step with an empty action list, so it could not act. And the workflow-design audit technique — the one example the repository would hold up as how to run a guard from a protocol — instructed a flag the binding guard has never had, and ran two guards without a corpus root, so an authoring run reviewing a worktree measured the server checkout instead and reported a clean pass on definitions it never read.
The fix
Answer the gate. A gate now evaluates to true, false, or nothing at all. It has an answer for the whole activity when every variable it compares is already bound and no step of that activity produces one of them; the producer scan the delivery already runs for provenance supplies the second half. A step joins the eager bundle on a true. An unbound read and an expression that does not parse answer nothing rather than false, so no step can lose its delivery path to an authoring defect, and a false answer keeps a body the run will not execute off the wire. Whatever the executing agent evaluates when it reaches the step is still what decides execution.
Split the boolean. The response-local pass runs in every delivery mode, because a marker pointing into the same response is readable by a context holding nothing from before. Two steps bound to the same technique in one activity collapse the same way. The ledger half still requires a context that retains what it was sent.
Trust the identity. A scope the server has already delivered an activity to is referred back to the invariant blocks it holds, whatever mode the session declares. Forcing full delivery re-delivers them, and resuming with a fresh context mode drops that scope's ledger entries — the caller stating its context is new is now recorded in state rather than special-cased in the delivery path.
Run the gate. Verify runs the delivery-cost benchmark on every pull request, at the 1% default, against a baseline recorded on the pinned corpus commit. A definition change that adds delivery fails there. That is the gate working: confirm the increase, re-record the fixture in the same commit, and say in its description what the corpus gained for the characters.
Give the records a reader. A resume compares the workflow version it loads against the one recorded, seeds the declarations the bag lacks, leaves written values alone, and re-stamps. The binding guard reports how far the corpus has moved since its verdicts were made — 178 commits — without failing on it, since a verdict usually survives edits elsewhere and a stale entry is already reported by name. The census is a command, and the landing procedure says to run it.
Close the gates. The meta orchestrator records reaching the end of its client activity loop. Each of the five issue categories maps to one branch prefix the repository already uses, reason stated per row, and the prefix is a step-local the composition step reads. The complex-problem path declares its trigger and binds the child-workflow dispatch, following the sibling activity that already dispatches the same child. The audit technique names arguments that exist.
Two smaller corrections ride along. A lazy technique fetch resolves a step identifier against the session pointer, which any context in the session can move; it takes an optional activity identifier and errors on a mismatch naming both. And the activity boundary now reports where the exiting worker stands, counting the lazy fetches that activity made — the reading a continue-or-respawn decision wants, where the one taken at the activity's open predates them.
Why now was the cheap moment
The definition edits are one landing rather than four. The ceremony around a corpus change is fixed per landing — a submodule commit, a pointer bump, six committed walk snapshots, a corpus stamp, regenerated site data and a re-recorded delivery baseline — so the marginal cost of the fourth edit inside one landing is near zero and the cost of the fourth landing is the whole ceremony again.
Re-measuring the batch dial was two benchmark runs, and it turned out to matter more after the delivery work than before. Three activities of the analysis run cost 232,954 characters delivered separately and 159,093 batched, because a batch's second and later activities collapse the invariant blocks and the shared contract their techniques inherit. Against a 280,000-character budget that is 57%, so the activity cap now binds where the budget used to, and reaching the budget takes roughly seven activities of that weight. The defaults are unchanged: revising either still needs the context establishment a byte count cannot see, and that is what the recorded refusal counts and per-activity usage rows are for. The measurement is written down so the next revision starts from current numbers.
Scope of change
Server: the gate answer as its own small module, the delivery paths in the two tool files, the technique loader threading the workflow a technique was found in, the resume path, and one continuous-integration step. Around 350 lines, no new tool, no new trust boundary.
Corpus: four definition files across meta, work-package and workflow-design.
Also re-recorded, because the corpus pointer moved and the definitions changed: the six walk snapshots, the corpus stamp, the generated site data, and the delivery-cost baseline. The batch policy comment in the server config restated what the dispatch model document already said, so it points there instead and that document carries the re-taken measurements.
Acceptance criteria
Non-goals
This branch takes 18 of the report's 52 findings — the whole immediate tier, most of the server-side delivery tier, and four definition gates. It deliberately leaves the rest, and the largest remaining items are worth naming because they are where the remaining value sits:
Also unaddressed, and stated because it bounds what this branch can claim: eleven of the report's twelve mechanisation candidates save less than the only instrument that can measure them resolves. The one exception — implementing the status policy as an operation returning a diff — is not in this branch.
Investigation detail
Evaluation report and per-dimension analysis
🤖 Generated with Claude Code