Repository navigation
feat(loop): publish the loop instruments, and retire escalations whose cause was fixed - #111
Merged
Merged
Conversation
These have existed only on one laptop. `git status` on the supervisor branch showed every one of them as untracked, which is the same defect this loop keeps finding in the swarm it supervises: work that exists and cannot be seen. 63 bee branches and 1321 files once sat in a container with 2 pushed. Twenty-one files, no dependencies, no network in the calibration run: heal.mjs eleven steps in a fixed order; four act, seven read loop.mjs state, the age-based lock, the append-only ledger, the dashboard reap lease free the volume, then the path fences push-work close-done make finished work visible, then clear it from the pool stale-escalations retire an escalation whose stated cause no longer reproduces clocks fields two defect classes that each cost an outage, checked every round fp-check coverage the checkers, run against material the WORLD calls good verdict-audit what the swarm claims, against what it actually pushed judge-packet assemble the unauditable for a judge; assembles, never judges brief-gate author refuse an unworkable brief; file from a measured deficit snapshot trend the readings, and whether a series has enough points to slope selftest 43 cases, every one proving the negative first Three rules are written into them and into the README: A checker never shown FAILING has not been tested. Six false accusations shipped in one night while synthetic fixtures agreed with the checkers that wrote them. Unreadable is not clean. A step that cannot reach its evidence reports ??, never ok - which is the only reason the first stale-escalation run did not retire six escalations on a probe that had failed to compile. A clock may only release what a clock can settle. Runtime is gitignored: state.json, ledger.jsonl, the lock, packets/, state/ and the rendered dashboards are produced by a run and mean nothing off the machine that produced them. No credential appears in any file; every database reference is process.env.DATABASE_URL, read inside the container.
The swarm sat at zero bees of four while the tick refused with "nothing to choose" against 22 candidates and reported `claimed: 11`. stateOfDispatch had no case for 'failed'. It fell through to the bottom and returned 'awaitingReview', which QueenDelegationPolicy.claimOnIssue counts as a LIVE claim. So a dispatch set to 'failed' - the state the policy's own comment calls the one that most obviously means 'do this again' - held its issue instead of releasing it. The function could already PRODUCE that state two lines below, for a send-back that outlived its idle floor, and did not recognise what it produced. Measured 2026-09-04: five dispatches were set to 'failed' to return their issues to the pool (browseros-ai#1133, browseros-ai#1175, browseros-ai#1216, browseros-ai#1240, browseros-ai#1311). All five stayed in 'claimed' across four consecutive rounds. Every worker slot idle, fourteen real deficits the author could not file against because each already had an issue - one of the held ones. Work existed and was locked by the row recording its release. 'cancelled' is included for the same reason: it is a dead state and the registry treats it as free. Six new assertions in send-back-lease.test.ts, including the three that must NOT be swept up by it (accept, sendBack, and an unfinished dispatch), and one proving the case ignores the lease entirely - a failure is a failure at zero idle and above the ceiling, because nothing about it waits for a clock. 173 pass, 0 fail across the queen suite.
❌ Tests failed — 5/1582 failed
Failed tests
|
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.
Two things, and the second is why the first stopped being optional.
An escalation raised by a defect that was fixed four hours later
browseros-ai#1216, browseros-ai#1240 and browseros-ai#1244 sat 91 hours waiting on a person, each with the reason "the task has no acceptance criteria, so there is nothing to judge it against."
All three visibly state four. browseros-ai#1216 has an English
## Success Criteriasection ending in agrepthat must exit 0. browseros-ai#1240 and browseros-ai#1244 use## Готово, когда.The cause was
QueenSpecQuality.criteriaHeadingsknowing four headings and none of theirs. It was fixed the same day inedbc05e11, whose title is "fix: the bees were judged against criteria nobody ever gave them" and whose own comment says a perfectly written spec yielded zero criteria. Compile today's parser, feed it today's bodies:Every dispatch since 2026-09-01 records
stated. The threenonerows in the entire table are exactly the three escalations. Nothing ever re-examined them.This is not the wait valve wearing a new hat
sendBackandwaitare released by a clock because their input can never change. An escalation names a cause, and a cause is a claim about the world that can be measured again. This re-measures. Three of the six escalations are "returned twice already, criteria still unmet" — a fact about a conversation, not about the issue text — and it leaves every one of them alone, at any age.Two gates, and the near miss that built the second
The first working run called browseros-ai#1244 stale and would have returned it to the pool. Its recorded reason is indeed void. But its body carries a section headed
## Почему жду слова— why I am waiting for your word — explaining that the change rewrites the main window's tabs and that the bee will not do that silently while the operator sleeps.The escalation was right for a reason the review never recorded. Retiring it on the recorded reason would have overruled a deliberate request with a database column — precisely the failure this tool exists to stop. A body that asks for a person is never auto-released, whatever the review recorded. Released 2, not 3.
It calls the shipping Swift parser, rebuilt whenever the source is newer than the binary. A JavaScript copy would agree until someone edited one, which is this repository's most repeated defect.
The instruments themselves
git statusshowed all twenty-one as untracked. They have existed on one laptop — the same defect this loop keeps finding in the swarm it supervises: work that exists and cannot be seen.heal.mjsloop.mjsreapleasepush-workclose-donestale-escalationsclocksfieldsfp-checkcoverageverdict-auditjudge-packetbrief-gateauthorsnapshottrendselftestA disagreement the new cases exposed
lockHolder()returned any lock file whatever its age, whileacquire()was already entitled to reclaim one past the 45-minute window. Soheal.mjscould name a run that finished 45 minutes earlier as the reason it stood down. Worse, the lock test — on finding that disagreement — took the live lock and kept it, rewriting the holder toselftest. A check that damages the thing it checks is worse than no check. Both fixed.Verification
node selftest.mjs→ 43 passed, 0 failed, no networknode heal.mjs→ all eleven steps ok;20 known-good inputs, 0 falsely accused;43 claims supported by the diff, none unsupportedprocess.env.DATABASE_URL, read inside the containerstate.json,ledger.jsonl, the lock,packets/,state/, rendered dashboards