v0.27.0 — the builder stops guessing and starts looking #445
mmeyerlein
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
The builder was a prefetch plus one model call. It is now a bounded, typed tool loop — with four eyes, one refine ear and no hand.
builder@1.1.0: the intake looks before it drafts. No cell in the template draws an edge onto/colony/mutations, and that is still a property of the files rather than a sentence in this text. What changed is that the composer can now ask before it writes:librarian_searchandcatalogue_lookupread the builder's own corpus in-colony, over ordinary routing.graph_readandregistry_readgo to/colony/graphand/colony/registry. Each of the four answers a refusal this system already produces: a missing contract, an island, a template chosen by its name rather than by what it does.dispatchfans out by tool name;weaveis the round table that fans in, rebuilds the thread and fires the next round;transcriptis the store underneath it;libandeyestranslate the two families into tool results;unknownanswers an unknown tool name with an ordinarytool_resultinstead of a dead letter.transcript: one row per turn of one build, withroleone of five —user,assistantandtoolare the loop itself,receiptis a refusal handed back by the submitter, andmanifestis the binding row written when a digest is minted.firedis the compare-and-set guard that grants exactly one weave path permission to cross the re-entry edge.acceptsroutein_receipt: a refusal the submitter took at the door travels back to the composer that drew the draft, and naming theerror_codeis the whole of the lane. The repair budget is separate from the round budget and is derived rather than carried — it counts thereceiptrows of the build's own slate, so nothing had to be added to the freshly releasedsubmitcontract to make it work.Contract movement is
accepts-only.emitsandports: []are unchanged; a caller can do something it was never promised, which is a second digit.An opaque
tagechoes back from the graph and registry reads.GET /colony/graphandGET /colony/registry— and the same queries at the message door — accept atagand return it unchanged. It filters nothing, and is therefore truncated to 64 characters rather than refused, the same treatment the/colony/ledgertagalready had. The reason it was needed: a reply from/colonybegins a fresh trace, so without an echoed token a caller with several reads in flight cannot tell the answers apart./colony/registryis drawable by a mutation. It becomes the third such read beside/colony/graphand/colony/ledger. This was not a convenience: an edge from insidemeclaw-osonto/colony/registrywas refused asscope_out_of_bounds, which mademeclaw-osuninstantiable altogether. The line itself is unmoved —/colony/mutations,/colony/traceand/colony/dead_lettersstay outside. The registry answer is colony bookkeeping over a colony's own cells, never message content, and strictly less than/colony/graphalready hands out.The scenario suite drives the loop without a model. The stub is scriptable: a per-case list of answers, the
tool_callswire shape, and afinish_reasonper round. Two new cases exercise what the loop is for — an eye correcting an island before delivery, and a refusal repaired once and named on the second attempt — on a scaffold with real nodes forgraph_readto find.Fixed
toolmessage answering no call, and the provider rejected the whole request with HTTP 400 — which cost the loop its repair round. It now travels as the plainuserturn a result outside a tool round is allowed to be. In the same place: a receipt arrives on a foreign chain without context and can only be filed under iteration 0, so the rebuild now sortsreceiptrows to the end of the thread.rounds_donemeasures whatiterdoes not.iterkeeps its meaning, but it is stamped with the value it finds, so it counts "looked twice", not "looked". The number now travels beside it, stamped on the two routes that really close a round.codecell's child task sentreplybeforeidle. A serial stream therefore got a different slot for its next job and woke a second interpreter. Not a flake — the sends are swapped.What this release does not claim
The acceptance quota is missed, and it is reported as missed. Measured twice with n=4 against one model, before and after the follow-up fixes: "the composition lives" 0/4 both times, "it is what was ordered" 0/4 both times. What holds is "no silent death" 4/4 — every run said how it ended, a draft with a digest and a named refusal or a named
error, never an empty manifest and never silence — and "the loop looked" 4/4 once the figure measured it. The bottleneck is manifest quality, above all the choice of template; the loop itself runs, is bounded and never goes quiet.Three further limits are named in the changelog rather than hidden: a caller's own coordinates can lose a race against a
/colonyeye's fresh trace; the corrected receipt turn is pinned by three tests but was never exercised against a live provider, because no measured run reached a repair round; and one prompt-related refusal class moved in the wrong direction inside its own measurement noise, which is stated as a risk rather than as a finding.Full detail in CHANGELOG.md. The workspace suite stands at 5681 tests.
All reactions