Releases: a11ign/agent-org
Releases · a11ign/agent-org
Release list
v0.52.6
Patch Changes
- 7a3b850:
messaging/selftest.mjs --tickno longer exits 13 ("Detected unsettled top-level await") when it has work to do, so the check that follows a messaging release reportsPASS,REDorsentand notMESSAGING SELFTEST NOT RUN(a11ign/a11ign#3701). The entry ended inprocess.exitCode = await main(...), andmain->tickSelftest->realQueue()importswake.mjs, which importsselftest.mjs: the entry, still waiting on its ownawait, was a module in that cycle, so each waited for the other and Node drained the loop. The entry now sets the exit code in athen. Every test calledmainwith an injected queue, which skipsrealQueue(), the one call that closes the cycle;selftest.test.mjsnow runs the entry as a process (an isolatedHOME, a state file that says a run is already waiting, so nothing is queued) and asserts it does not exit 13, its last stdout line is JSON, and a refused flag still exits 2. WhattickSelftestdecides and writes is unchanged.
v0.52.5
Patch Changes
- c0a0b70: The
tick-costline names eachgh,gitandherdrcall by its SUBCOMMAND (src/lib/spawn-census.mjs,src/work-tick.mjs): a newsubcommandsobject, keyedgh pr list,gh api repos/a11ign/a11ign/issues/#/timeline,git rev-parse,herdr agent list, each withnandwallMs, the ten slowest by wall and the rest summed intootherso the total still adds up. A digits-only path segment is#and a query string is dropped, so an issue number does not make every call its own key. Until now the line saidghwas 66 calls and 50 s per tick and could not say which of them, so the gate'sghreads could not be cut in the order of the profile. A record with nosub(anode, or one written before this) is left out, not counted under an empty name. a11ign/a11ign#3566.
v0.52.4
Patch Changes
- a0d32cd:
trace-publishreads the rows closed in the last seven days from the REST issues list, not the search API (a11ign/a11ign#3695).recentClosedRowslistsrepos/<repo>/issues?state=closed&since=<ISO time>on thecorepool, which holds every issue closed since the time, and filters byclosed_atand by the absence ofpull_request, so the record issue (#928: commented on all day, closed in September) is updated inside the window and still not returned. It reads one counted call per 100 issues where the search read one, and a list not finished in 30 pages is refused rather than cut short.NO SEARCHintrace.test.mjsno longer names an exception: no source ofsrc/trace/reads the search API.
v0.52.3
Patch Changes
- ee97f5a: The chairman-messaging listener can now read
{{fleet.workers-up}},{{fleet.workers-down}}and{{gate.last-tick.age}}in aVerify:(a11ign/a11ign#3646).createWatchReadersbuilt its readers with neither the fleet-watch files nor the gate record, so those three placeholders refused ("this host named no fleet-watch state files") and a walk-through over a worker power-on never advanced.createWatchReaders(repo, now, files)now takes what the newhostFiles({ root, err })names:runs/fleet-watch-state.jsonandruns/fleet-captures-state.jsonunder the project's checkout, and the tick's completion record beside the wake ledger.listen.mjsandwatch.mjspass it. A host that cannot name the completion record costs{{gate.*}}alone, said on the journal.chairman:watchis unchanged: a fleet cannot be watched.
v0.52.2
Patch Changes
- 09a6acc:
wakes-per-rowreads the merged pull requests of its window from the REST pull-requests list (a11ign/a11ign#3692), through the readertracealready uses (listMergedPulls), not the search API throughgh api --paginate, which is 30 calls a minute per user, one call per page in one unpaced burst, and cut at 1,000 results without saying so.readMergedPullskeeps its signature and takes the reader as an optional third argument, so its cases run with no GitHub. A window the list cannot finish in its 30 pages is refused, and the refusal names--from(this tool's flag) where the reader's own message names--since.
v0.52.1
Patch Changes
- b757970:
trace -- --aggregateand--mapread the GitHub events of every row and pull request the window's wakes name (a11ign/a11ign#3688). The store held a record only for the rows a pull request MERGED IN THE WINDOW closed, so a repeat of an order about an open row, a row closed another way or in an earlier week, or a pull request that was not one of the week's merges had nothing to be judged by and readunexplained: 349 of the 599 repeats of the week of 2026-09-28 (measured 2026-10-05,trace -- --aggregate --since 2026-09-28).githubEventsOfNamedreads them after the merged reading, through the same budgetedgh(--calls, the pool floor, the pace), oldest naming first, so a stop leaves the NEWEST wakes' subjects unread, and returns what it did not reach by name. A subject the store already settles (a closed row, a merged or closed pull request) is not read again; an open one is read on every run, because its record grows and a stored reading of it can be stale (a stale reading would printunchangedfor a repeat that did follow a change, which is worse thanunexplained). A subject GitHub refuses is named in the footer with GitHub's words and the next is still read. A key that names no subject (ready-queue-empty,org-health) reads nothing and staysunexplained, correctly. The footer's GitHub line gainssubjects the wakes name, not yet read: Nand the subjects it could not read.
v0.52.0
Minor Changes
- 13d8a75: The organisation checks the chairman's path end to end after a messaging release (a11ign/a11ign#3540).
agent-org messaging:selftestsends ONE synthetic inbound through the realcreateInbound(...).handle(), the realconverse.forward, the real queue port and herdr's real roster, with a RECORDING provider (it imports no provider and calls nofetch, so nothing reaches his chat), an order text that says it is synthetic and asks the seat to take no action, and its own ledger (selftest-ledger.jsonl, never the chairman's, somessaging:measuredoes not count a check). It reads the line back and judges four stages, naming the first that failed:listen,queue,seat(typed in at once, or the queue entry left the queue within 10 minutes, a bound measured from 385 ticks) andback(the acknowledgement came through the recorder). An order that went toceoand not the liaison is a DEGRADED pass, never green. The work tick runs it once on the first tick after the checkout moves to a tag whose changes touch the messaging code, the queue or the roster's readers (selftestDue, a pure function of two tags and a file list), records the version only when it PASSED, retries a red after a 10-minute back-off, and queues a red or degraded report forceoonce and never for the chairman.converse.mjsexportsrealQueueso the self-test reuses the one queue loader.
v0.51.0
Minor Changes
- df2ead4:
trace -- --aggregateandtrace -- --mapno longer read GitHub through the search API (30 calls a minute per user, 1,000 results at most), andtrace -- <row-or-pr>finds a row's pull requests without it too. The merged pull requests of a window come from each repository's pull-requests list, newest update first, read until a page reaches a pull request last updated before the window (a list not finished in 30 pages is refused, naming--since, rather than cut short); the pull requests that close a row come from the row's own timeline. The first line a run prints, before its first call, now says what it may spend: at most--callsgh apicalls, all on the RESTcorepool (a reply from any other pool is refused), at least 250 ms apart, and a stop whenX-Ratelimit-Remainingfalls under 500. At that floor a run stops, says "STOPPED AT THE FLOOR" in its footer beside theX-Ratelimit-Remainingit saw at its first and last reply, and the weeks that depend on what it did not read are PARTIAL, exactly as when--callsis spent; with--json 1the line goes to stderr so stdout stays the JSON. Merged pull requests are taken in order of merge, so the rows a report lists (and the first eight of a "and N more" list) no longer depend on the order GitHub happened to return them. The weekly figures of a complete week are unchanged: measured on one store, the old and the new reader print the same 73 non-row-list lines of the complete week and the same current week, and differ only in which rows the truncated row lists show first.
v0.50.0
Minor Changes
- 19ba2dd: The trace pages are regenerated after each merge and at least hourly, into one directory a host act then serves privately over Tailscale (a11ign/a11ign#3515, the last slice of #3494).
src/trace/publish.mjsreads the head ofmainin every code repository the project declares (onegh api repos/<repo>/branches/maincall each) and regenerates only when one moved since its last stamped publication or the stamp is older than--max-age-minutes(default 60); a run that finds neither does nothing and exits 0. It writesmap.html(trace -- --mapover the last seven days,--calls 300), onerow-<n>.htmlswimlane per row closed most recently in the tracker repository (--recent, default 6, plus any--row <n>) and anindex.htmllinking them, into--out(default~/.cache/a11ign/trace-pages). Every page is rendered into a staging directory and checked to be non-empty before it replaces the served one; a page that fails to render or to write is listed on the index and makes the run exit non-zero WITHOUT writing the stamp, so the unit shows failed and the next tick retries, never a green run over an empty directory.host/trace-publish.timer.inruns it every ten minutes (OnBootSec=2min,OnUnitActiveSec=10min) andhost/trace-publish.service.inruns it as the workers account; both are installed and started byhost:install, which makes one run at install (a first publication, or nothing when no head moved). Nothing here opens a port: serving istailscale serve --bg <out>, run by the host's operator.
v0.49.2
Patch Changes
- ce3206c:
tracegives a turn stored beforetoolMsexisted its tool time, by moving the ingest state to version 3 (src/trace/ingest-state.mjs). A state of another version is already a cold start, so the first run after this release reads every transcript from byte 0 once, andappendToStoresupersedes each stored turn with the copy that carriestoolMs; until then a worker's old tool time printed asunexplained. Measured 2026-10-05 into a SCRATCH store (never the live one), over the transcripts changed since 2026-09-28 with no wake ledger, gh ledger or deferral log: 1,733 transcripts, 1,339,543,558 bytes read, 21.1 s wall-clock, 702 MB peak RSS, 63,225 events. That is inside the tick; the supersede appends only the turns whose copy differs. The state is trusted again from the run after. a11ign/a11ign#3680. - b7c2a42: The trace store's
openedrecord for a pull request now carriesdraft:truewhen it was OPENED as a draft,falsewhen it was opened ready,nullwhen this read cannot say (a11ign/a11ign#3670, follow-up of #3511). The pull object's owndraftis the state NOW, so a draft marked ready later readsfalsethere; the timeline's firstready_for_review(a draft) orconvert_to_draft(ready) event says what it was at the opening, and only a pull request with neither takes the pull object's value,nullwhen the object has none (neverfalsefor "not read"). The waterfall's verify phase reads it: with noready_for_reviewevent it prints "opened ready, no draft stage" only fordraft: false(queued or not), "still a draft" fortrue, says the ready mark is missing for a draft that was queued or merged without one, and keeps saying the store does not know fornull. Anopenedwritten before this change has nodraftand reads asnull; the store is not re-ingested.