Skip to content

queen(actors): ship the seven actor-runtime improvements of #1712, every new behaviour behind an off flag - #1730

Merged
gHashTag merged 30 commits into
queenfrom
actors-next
Oct 10, 2026
Merged

gHashTag merged 30 commits into
queenfrom
actors-next

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Ships the seven actor-runtime improvements of #1712 (ledger #1729) to queen, in one deploy instead of seven.

Every new behaviour is behind a flag that is off by default. The flags are listed below. With all of them unset, the runtime runs the code paths production runs today, plus three pure fixes:

# Improvement PR Flag Spec (t27)
base actors and reviewer cards re-vendored from t27 master b7aaf6b - #8137, #8212
1 telemetry and a decision log replayed in CI #1725 TRIOS_QUEEN_ACTORS_TELEMETRY=on #8285
2 turns that really stop #1720 TRIOS_QUEEN_TURN_STOP=on #8281
3 reviewer pool sized from the backlog #1716 TRIOS_QUEEN_REVIEWER_ADAPTIVE=1 #8275
4 long waits as Postgres rows #1722 TRIOS_QUEEN_WAITS=rows #8272, #8282
5 seeded simulation gate (CI job) #1726 - (tests only) #8292, #8306
6 PgLink fencing and incarnations #1724 no caller until TRIOS_ACTOR_NODE is wired #8278
7 keyed actors, links, call; bee dispatcher MVP #1723 TRIOS_QUEEN_DISPATCH=actors #8286

Each lane's benchmark (same seeded input, before vs after) is on gHashTag/t27#7851. The t27b lab's signed master receipt (b9d22d0f) passes every new queen spec, with 0 disagreements against the reference.

Migrations: queen_wait (lane 4) and the PgLink columns to_inc / incarnation (lane 6). Both are additive.

After merge: turn the flags on one at a time, by data:

  1. telemetry first;
  2. then waits, then turn stop;
  3. adaptive concurrency only once telemetry shows at least 5 free review lanes over 24 h.

Closes nothing by keyword: queen is not the default branch. The lane issues are closed by hand with the merge link.

🤖 Generated with Claude Code

gHashTag and others added 22 commits October 9, 2026 23:54
…21a0b39c, every fn exported (Refs #1712)

The vendored actors card predated the file owner (t27#8137) and the reviewer
card predated reviewer_concurrency (t27#8212). Both rebuilt by the PIN recipe,
twice, one hash each; every fn of each card is exported so the seven
improvements on actors-next need no further rebuild to call them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anes - reviewer_sizing.t27, behind TRIOS_QUEEN_REVIEWER_ADAPTIVE (Closes #1715)

Part of #1712, item 3. With TRIOS_QUEEN_REVIEWER_ADAPTIVE=1 the actor
reviewer's fixed REVIEWER_CONCURRENCY workers become a pool the intake
sizes by gHashTag/t27 specs/queen/reviewer_sizing.t27 (t27#8273):

- reviewer domain (rest_for_one): intake, then a dynamic supervisor
  (queen-actors-dynamic.ts, one_for_one, actors.t27 start_answer /
  on_child_exit / children_after_exit) over transient workers;
- every wake reads the lanes and memory (reviewCapacity in queen-tick.ts:
  the review sweep's own lane arithmetic, each key capped by
  key_free_lanes - z.ai two a key, measured - plus cgroup memory);
- after every message: pool_target (reviewer_concurrency over the pool's
  lanes, memory and busy + queued rows), start while start_answer allows,
  stop an idle worker when worker_retires says so, hand out
  review_slots_within(target, busy, queued) rows.

Default off: without the flag the tree, the code path and the original
benchmark table are unchanged (diffed byte for byte).

Tests: queen-review-adaptive.test.ts (14): PIN, the embedded
reviewer_concurrency equals reviewer.wasm's, backlog 0 / 3 / 200, never past
5 lanes, unmeasured memory, idle stop after POOL_IDLE_STOP_SECONDS and regrow,
a crashed worker restarts in place, the fixed path still 4, and the
production lane count on z.ai and on another provider.

Benchmark: queen-actors-bench.test.ts gains a second table, fixed 4 against
adaptive on the same seeded draws, with a lane model (a review asks for its
lane 30% in; none free -> `wait`, spaced by withWaitBackoff).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…(Refs #1715)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rency

feat(queen): the reviewer's worker pool follows its backlog and its lanes - reviewer_sizing.t27, behind TRIOS_QUEEN_REVIEWER_ADAPTIVE (Closes #1715)
… actor, the release job's CI wait parks on a row (waits.t27), behind TRIOS_QUEEN_WAITS=rows (Closes #1717)

Part of #1712, item 4. Measured 2026-10-09: the swarm's first release
(job #3, t27c 0.5.2) spent about 90 of 92 minutes at release-workflow. The
job was already a row, but every round asked its WAIT step again: one GitHub
read and one job-log entry per round, 180 of each for one 90-minute wait.

- Card queen/waits.wasm + queen-waits-card.gen.js from gHashTag/t27
  specs/queen/waits.t27 (t27#8272, t27#8282), byte-identical, every fn
  exported, PIN lines and a PIN test.
- pg-migrate: queen_wait (owner, key, state, wake_at, expires_at, due_at,
  checks, epoch, resolution, detail), unique (owner, key), partial index on
  due_at for waiting rows.
- queen-waits.ts: createWait (idempotent per owner and key), resolveWaitByKey
  (resolution_lands, NOTIFY as a hint), cancelWaitsOf, claimDue (SKIP LOCKED,
  epoch_after_claim, claim pushes due_at CLAIM_TTL ahead), endClaimed and
  rearmClaimed (lock the row, write_lands, state_after, transition_allowed),
  githubRunResolver (one read of the run by id), and the scheduler actor:
  beat on its control lane (beat_after_seconds), every bus event and every
  NOTIFY a hint (pass_on_hint), a pass with nothing due opens no transaction.
  stop() writes nothing to any row.
- queen-jobs.ts: with waits on and a scheduler running here, release-workflow
  parks on a row keyed by the run id (step_parks, job_wait_seconds), the
  round skips a parked job (round_visits_job), the row's end answers the step
  (step_outcome), a cancelled job cancels its rows. Off: unchanged.
- queen-tick.ts starts the scheduler when TRIOS_QUEEN_WAITS=rows; a wake asks
  for a round. routes/queen-waits.ts: GET/POST /queen/waits and
  POST /queen/waits/resolve, guarded, 503 while off.

Tests: tests/api/queen-waits.test.ts 13/13; tests/pglive/queen-waits-live
7/7 against PostgreSQL 16 (restart, stale epoch, a scheduler past its claim,
two schedulers x 400 rows each woken once, the release job parked and woken,
cancel, NOTIFY); queen-jobs-live 9/9 and pg-migrate-live unchanged. api
suite: the same 9 failures as actors-next (1598 pass vs 1585, +13 new).
Benchmark: tests/pglive/queen-waits-bench.test.ts (numbers in the PR).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
t27#8282 merged as aeb0397f9; the master blob of specs/queen/waits.t27 is 27f3d63, the one vendored here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(queen): long waits as rows in Postgres - queen_wait, a scheduler actor, the release job's CI wait parks on a row (waits.t27), behind TRIOS_QUEEN_WAITS=rows (Closes #1717)
…it calls, process groups killed whole (Closes #1713)

Part of #1712, item 2. The rule is gHashTag/t27 specs/queen/turn_stop.t27
(t27#8274, PR t27#8281), vendored as turn_stop.wasm and
queen-turn-stop-card.gen.js, with lines in specs/PIN.

Behind TRIOS_QUEEN_TURN_STOP=on (createActorSystem option turnStop):
- each turn gets its pid's AbortSignal in `receive` and in its isolated work;
  when the pid dies (the turn timer or any exit), actors.t27 stop_signal
  X_SHUTDOWN aborts it, and after TURN_STOP_GRACE_MS the card's escalation
  kills the process group or records an abandon; holds_after_kill decides when
  a stopped turn gives back its row and lane;
- the reviewer's model call, its git commands (run) and its criterion
  commands (defaultExec) obey the signal; shared checkout writes and
  finalizers run to their end (step_on_abort); a stopped review writes no
  verdict and no cache and backs off no lane;
- the reviewer intake counts killed reviews that still hold a lane against
  the bound (in_flight), and its fixed workers sit under their own
  one_for_one supervisor, so one worker's kill no longer aborts its siblings.

A pure fix, on with or without the flag: process isolates lead their own
process group and are killed as a group, so no grandchild survives. The
comment in queen-actors-isolate.ts that claimed a thread stop ends the work
is corrected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(queen): a killed actor turn stops - AbortSignal into model and git calls, process groups killed whole (Closes #1713)
… the actor runtime; the bee dispatcher as keyed actors, MVP behind TRIOS_QUEEN_DISPATCH=actors (Closes #1719)

Part of #1712, item 7. Every decision is a card call.

- queen-actors-links.ts runs the parts of actors.t27 that had no runtime:
  links and trap_exit (links_after_link, attach_answer, on_exit_signal,
  death_reason), call with an alias, a monitor and a timeout, so a late
  reply is a dead letter (call_admit, chain_add, call_outcome, live_alias),
  demonitor with flush (down_left_after_demonitor), and the orderly stop:
  shutdown, then kill at the timeout, last started first (stop_signal,
  stop_rank).
- queen-actors.ts gets four hooks: onExit, unwatch, mailbox, busy. A
  double monitor is now two DOWNs (monitors_after_monitor). A DOWN carries
  its monitor's ref, not enumerable.
- queen-actors-keyed.ts: one actor per key per keyed.t27 (t27#8271):
  get or spawn, idle passivation, a cap with LRU eviction, the directory
  forgets only the incarnation that ended, a held send starts a stopping
  key again.
- queen-bee-actors.ts: the bee dispatcher as keyed actors. One admission
  actor holds the lanes. One actor per issue holds its state (bee_key_next),
  its claim (claim_step, the pid as holder) and its bee's end
  (dispatch_exit.t27 exit_reason, restart_decision). A bee actor's turn is
  killed at TURN_MAX_SECONDS, and its issue holds until the bee has stopped
  (holds_after_kill).
- queen-bee-actors-round.ts + a hook in runRound: with
  TRIOS_QUEEN_DISPATCH=actors the round hands its candidates to the actors.
  Unset (the default), nothing changes.
- New cards: keyed (t27#8286) and dispatch_exit (t27#8043), every fn
  exported, two builds one hash, PIN lines and a PIN test.
- Benchmark (tests/api/queen-bee-actors-bench.test.ts) on one seeded
  input: loop, the loop with a 60 min cap, actors-round and actors-event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le it runs (Refs #1719)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…me now gives every turn (Refs #1719)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(queen): links, call, demonitor, orderly stop and keyed actors; the bee dispatcher as keyed actors, MVP behind a flag, with its benchmark (Closes #1719)
…ons, a fenced lease on its own thread, mail acknowledged after it is handled (Closes #1714)

Each defect from reading queen-actors-pg.ts / queen-actors.ts was reproduced
by a failing test first, on the memory net or against a real PostgreSQL.
The rules are the new card specs/queen/netlink.t27 (gHashTag/t27#8276, PR
gHashTag/t27#8278), vendored byte-identical, with netlink.wasm and
queen-netlink-card.gen.js:

- A start claims the next incarnation. A linked node's pids carry it
  (inc_next_gen), so a restart never reuses a pid. Mail for another
  incarnation is expired, never delivered.
- Every write (renewal, send, acknowledgement, expiry) is fenced in SQL by
  the incarnation and the lease, mirroring write_admitted. A live test holds
  the SQL to the card at 30 boundary points.
- The lease is renewed by a worker thread with its own connection, while
  the loop turns (beat_renews). A held loop no longer looks dead.
- A node fences itself on must_fence: actors stopped quietly, nothing sent
  or started, never back.
- Mail is read, handled, then acknowledged, with dedupe by row id
  (mail_action). Peers are judged by peer_change/peer_up: down is final.
- A node-down ends only what waited on that incarnation (lost_with).

The chaos script tests/pglive/queen-actors-netlink-chaos.test.ts runs the
same input before and after.

Part of #1712.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(queen): PgLink made safe before its first caller - node incarnations, a fenced lease on its own thread, mail acknowledged after it is handled (Closes #1714)
… telemetry.t27, GET /queen/actors/metrics (Closes #1718)

Part of #1712 (item 1). gHashTag/t27#8284 (PR t27#8285) adds
specs/queen/telemetry.t27; it is vendored here byte-identical with its
wasm (every fn exported, two builds one hash) and gen-js constants.

- queen-actors.ts: options.telemetry (off when unset) feeds counts per
  actor kind (ActorSpec.kind, else its name) from send, step, kill, exit
  and the supervisor: sent, dead letters, drops for a full mailbox,
  control turns, turns, crashes, kills, restarts, give-ups; turn time
  for every turn and mailbox time for sampled letters in the card's
  doubling buckets. Every hook is guarded by `tel !== undefined` and
  never schedules.
- queen-actors-telemetry.ts (new): threshold events from the card -
  mailbox depth raises at depth_on_at and clears at depth_off_at, long
  turn and long wait at half the bound the kill timer uses, restart
  storm one restart before giving up; top N by mailbox depth (depth,
  never contents); rings of events and sampled message records; a
  "Queen actors measured" line every SUMMARY_EVERY_SECONDS with each
  kind's turns, busy share, p50/p95, deepest mailbox, dead letters,
  kills and restarts; replayDecisions.
- queen-card-wasm.ts: a tap. Per card fn and window the tap asks `kept`
  until it says no, then stops asking until the window turns; records
  hold card, fn, args, result, kind, UTC ms and n. The kind follows a
  turn across its awaits (AsyncLocalStorage); the supervisor's decisions
  carry its name.
- queen-actors-dynamic.ts (the adaptive pool's supervisor, #1715): the
  same restart, give-up and storm reports as the fixed supervisor.
- GET /queen/actors/metrics and /queen/actors/decisions (new route).
- queen-review-actors.ts: workers count as kind reviewer-worker;
  TRIOS_QUEEN_ACTORS_TELEMETRY=on turns telemetry on (default off), and
  the decision log then holds the actors, reviewer and reviewer_sizing
  cards' calls.

Tests (tests/api/queen-actors-telemetry.test.ts): PIN and exports; a
filling mailbox raises once, drops past the cap and clears once; long
turn, kill and crash; a restart storm and its end; the summary line;
the endpoint; with slices off (a slice reads real microseconds) the seeded bench input starts the same
reviews at the same times with telemetry off and on; every decision of
the seeded reviewer run replays to the same result on fresh instances of
the pinned cards, and a corrupted, empty, foreign or unsampled log does
not pass; the cost per message on the ring benchmark's input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(queen): actor telemetry per kind and a replayable decision log - telemetry.t27, GET /queen/actors/metrics (Closes #1718)
…eeded reviewer run writes one t27 module per card, one assert per distinct call (Closes #1727)

Test glue, no runtime change. With QUEEN_DECISION_SPEC_OUT=<t27 checkout>,
the seeded reviewer run (seed 7852) of queen-actors-telemetry.test.ts writes
specs/queen/replay/<card>_decisions.t27 there: one assert fn(args) == result
per distinct (card, fn, args) of the decision log, typed by the card's own
signatures (a u32 or u64 read back signed is written unsigned, a bool as a
bool). A call answered two ways, or a value no literal of its type can hold,
is refused.

At 71b4564: 73436 records, 1825 distinct (actors 472, reviewer 25,
telemetry 1328), 0 conflicts, 0 unwritable; four generations byte-identical.
The modules land in gHashTag/t27#8313, where t27c test-report passes all
1825 asserts on the reference path.

Part of #1712.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(queen): the decision log as a three-way conformance spec (Closes #1727)
…n, as a CI gate - simulation.t27 (Closes #1721)

Each of the simulation card's 16 seeds plays 10 000 steps of the real actor
runtime (createActorSystem on three nodes over createMemoryNet, the reviewer
actors, a pool of remote children) with the card's fault mix, and runs
twice; the per-step log hashes must agree, no invariant may break, and the
seeds together must reach the card's rare states. A failure prints the
seed, the step, the minimal log tail and the replay command.

The gate found a runtime defect on its first runs: a process stopped
between taking its message and running the turn still ran it. queen-actors
now runs a turn only for a live process.

New workflow Actor simulation for actors-next; server-sim in Tests for queen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on every second seed, the fenced PgLink over the simulated store, restarts inside the TTL, stale pids (Refs #1721)

The card (t27#8305) now names the seeds that run with turns that really
stop and the two seeds that also run on the store model; the store model
answers the fenced link's statements (claim, renew, read, acknowledge,
expire, send), and a row it sees acknowledged must have reached a runtime or
be expired by the card. One job in four goes to a remembered pid. Each
supervisor's restarts are counted by the exit that caused the decision, so
two supervisors with one maximum are told apart. The world forwards the
turn's abort signal, and its review honours it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(queen): the actor runtime under a seeded deterministic simulation, as a CI gate - simulation.t27 (Closes #1721)
@t27-bees

t27-bees Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Summary by t27-bees

Checked by the t27 compiler

t27c parse, parse-complete and typecheck on each changed .t27 file at 952fb6c. Nothing was generated, built or run. A pass means the file is well formed, not that it is right.

  • trios/agent-server/specs/queen/actors.t27: parses and typechecks.
  • trios/agent-server/specs/queen/dispatch_exit.t27: parses and typechecks.
  • trios/agent-server/specs/queen/keyed.t27: parses and typechecks.
  • trios/agent-server/specs/queen/netlink.t27: parses and typechecks.
  • trios/agent-server/specs/queen/reviewer.t27: parses and typechecks.
  • trios/agent-server/specs/queen/reviewer_sizing.t27: parses and typechecks.
  • trios/agent-server/specs/queen/simulation.t27: parses and typechecks.
  • trios/agent-server/specs/queen/telemetry.t27: parses and typechecks.
  • trios/agent-server/specs/queen/turn_stop.t27: parses and typechecks.
  • trios/agent-server/specs/queen/waits.t27: parses and typechecks.

Read by the model

This PR ships seven actor-runtime improvements from #1712 behind feature flags (all off by default), plus three pure fixes: process-group kills for isolates, a corrected comment, and preventing turns from running after their process stops. New migrations add queen_wait table and PgLink to_inc/incarnation columns.

Worth a look

  • trios/agent-server/apps/server/src/api/services/queen-actors-isolate.ts (+48/-14): Process isolates now killed as a whole process group (feat(queen): a killed actor turn stops - AbortSignal into model and git calls, process groups killed whole (Closes #1713) #1720). If the group includes unintended child processes (e.g., from test harnesses or sidecars), they will be terminated together—verify the process-group boundary in CI and staging.
  • trios/agent-server/apps/server/src/api/services/queen-turn-stop.ts (new, +157): Implements "turns that really stop." The flag TRIOS_QUEEN_TURN_STOP=on gates this; ensure the stop signal propagates before any in-flight async work resumes, otherwise a turn could observe stale state after stop.
  • trios/agent-server/apps/server/src/api/services/queen-waits.ts (new, +879) & queen-actors-pg.ts (+498/-77): Lane 4 moves long waits to Postgres rows (TRIOS_QUEEN_WAITS=rows). The additive queen_wait migration must run before the flag is enabled; if the flag is flipped early, wait scheduling will fail on missing table.
  • trios/agent-server/apps/server/src/api/services/queen-actors-pg.ts (+498/-77) & queen-actors-pg-beat.ts (new, +108): Lane 6 adds PgLink fencing and incarnations (to_inc, incarnation columns). No caller yet (requires TRIOS_ACTOR_NODE), but the columns exist—ensure the migration is idempotent and doesn't lock the table long on large clusters.
  • trios/agent-server/apps/server/src/api/services/queen-reviewer.ts (+34/-3) & queen-reviewer-sizing-card.gen.ts (new): Adaptive reviewer pool (TRIOS_QUEEN_REVIEWER_ADAPTIVE=1) sizes from backlog. The description requires telemetry to show ≥5 free lanes over 24h before enabling; if enabled prematurely, the pool could oscillate or starve other work.

Read: 117 files, +20127 -1261, a summary only: the diff is larger than 4000 changed lines, so it was not read line by line. Head 952fb6c. Model: openai-compatible/nvidia/nemotron-3-ultra-550b-a55b. Commands: @t27-bees review | summary | help | pause | resume. Free for every repository.

gHashTag added a commit to gHashTag/trinity that referenced this pull request Oct 9, 2026
…ages (Refs #1582)

Lane 5 of gHashTag/trios#1712 landed (gHashTag/trios#1726 into actors-next, spec
gHashTag/t27#8292 and #8306; numbers on gHashTag/t27#7851). The post's pending section now
gives them: 18 cases of 10,000 steps, each run twice, in 33.5 s on CI with 0 divergences;
four defects put back into the source and caught from a seed; and the real runtime bug the
gate found first (a turn run for a process that had already exited, fixed with a
regression test). The gate's limits (no keyed actors or adaptive pool in its world, no
nightly run) replace "numbers not posted yet" in the open questions and the limits list.
The production merge, gHashTag/trios#1730, is named as open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gHashTag

gHashTag commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

I checked each of the five points against the code at a053d3e. None of them needs a change.

  1. queen-actors-isolate.ts: the process-group kill. processWork( has no caller in src/, only tests and fixtures. With the flags off, production starts no process isolate, so the group kill cannot touch a production process. The kill itself is tested: 10 process turns each leave a grandchild, 0 survive (feat(queen): a killed actor turn stops - AbortSignal into model and git calls, process groups killed whole (Closes #1713) #1720).

  2. queen-actors-pg.ts. createPgLink has no caller in src/. TRIOS_ACTOR_NODE is not wired, so none of the PgLink paths, old or new, run in production.

  3. queen-actors.ts: new hot-path behaviour guarded? Yes:

  4. pg-migrate.ts. Every statement is additive and idempotent:

    • CREATE TABLE IF NOT EXISTS queen_wait and its CREATE ... INDEX IF NOT EXISTS;
    • ALTER TABLE ... ADD COLUMN IF NOT EXISTS ... NOT NULL DEFAULT 0 on queen_actor_node and queen_actor_mail.

    Since Postgres 11, a constant default makes this metadata-only, with no rewrite. Both tables are unused in production today, because PgLink has no caller.

  5. queen-dispatch.ts. The +19 lines read stepMayStart() and stepSignal() from queen-turn-stop.ts. Outside a turn context they return true and undefined, and a turn context exists only with turnStop (see 3). With the flag off, commands run exactly as before.

Also checked the full api suite at the same host load:

  • queen: 1584 pass / 10 fail.
  • This branch: 1684 pass / 11 fail.
  • The one extra failure is the 5 s timing test "CPU turns in threads run side by side". Run alone it passes 3/3 (threads 282-325 ms, loop held ≤ 18 ms).

…es out of Biome (Closes #1732)

20 of 21 card constant modules regenerated with `t27c gen-ts` from the spec
each names (vendored in trios, or on t27 master for domains and jobs); every
exported name and value is identical to the old gen-js output, as const and
satisfies aside. review_valve stays .gen.js: its master spec has moved on.
tsc now sees the constants' types, so the TS7016 / TS2305 / TS2459 errors on
imports of ./queen-*.gen go away (19 of them predate #1730).

biome.json excludes every generated queen-*.gen.js / .gen.ts by pattern
instead of a list that each new card had to join. The two complexity hits
(PgLink drainOnce, keyed send) carry a biome-ignore with the reason, as
snapshot.ts and grep.ts do.

Tests: 46 api test files that import a converted card, 790 pass; the two
failures are the load-sensitive 200 000-turn flood test and a sparse-checkout
tools/ file, both also on the base.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ci(queen): card constants generated with t27c gen-ts, generated modules out of Biome (Closes #1732)
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

✅ Tests passed — 3090/3154

Suite Passed Failed Skipped
✅ agent 87/87 0 0
✅ build 9/9 0 0
✅ cdp-protocol 5/5 0 0
✅ eval 93/93 0 0
✅ server-agent 280/280 0 0
✅ server-api 1825/1888 0 63
✅ server-browser 6/6 0 0
✅ server-integration 10/11 0 1
✅ server-lib 279/279 0 0
✅ server-pglive 135/135 0 0
✅ server-root 68/68 0 0
✅ server-sim 4/4 0 0
✅ server-skills 31/31 0 0
✅ server-tools 244/244 0 0
✅ shared 14/14 0 0

View workflow run

gHashTag and others added 2 commits October 10, 2026 05:59
…line covered or justified; a sampled letter no longer hides from demonitor's flush or a call's timeout (Closes #1731)

Measured with bun test --coverage over every test that reaches the actor
modules (api, sim, and pglive against Postgres 16). Before: 15 modules,
function coverage 0-98%, line coverage 9-100%. After: every line covered
but three, each unreachable by construction, plus four functions that are
justified; the list is in the PR. A marker pass that runs each function's
first statement found the functions Bun's line report cannot see.

New test files only, plus one fix. The coverage work found a real bug: with
telemetry on, a sampled letter waits in its mailbox wrapped with its
arrival time. demonitor(flush) and a call's timeout matched letters by
`kind`, so they missed a sampled DOWN or reply. The red test came first
(tests/api/queen-actors-queued-letters.test.ts: 3 of 7 red, all with
telemetry on). The fix is `letterOf` in queen-actors.ts, used in the two
readers in queen-actors-links.ts.

Part of #1712; ledger item 9 (see #1729).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(queen): actor runtime coverage measured and raised, every line covered or justified; a sampled letter no longer hides from demonitor's flush or a call's timeout
gHashTag and others added 2 commits October 10, 2026 19:15
…e needs-you (Refs #1712)

Lane 1 mounted /queen/actors (telemetry counts and the logged card
decisions: pids, kinds, card names and arguments) bare, while its comment
said it was operator information like /queen/needs-you. The route-guard
audit in tests/api/routes/route-guard.test.ts caught it on the ship PR
#1730. It now sits in its own sub-app behind requireTrustedAppOrigin().
The audit's pins are re-measured: 62 mounts (+/queen/actors, +/queen/waits),
20 guarded sub-apps, 39 /queen mounts with 13 wrapper-guarded; unguarded
stays the ten allowlisted shells.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(queen): /queen/actors is guarded by the trusted-origin check, like needs-you
…ake timers, and a logger mock no longer restores itself (Closes #1738)

On ubuntu CI (Bun 1.3.6) the tests on jest.useFakeTimers() timed out. Their
finally never ran, and the fake clock leaked into every later file. The
4 ms "no pid" in queen-turn-stop is that leak: its wait has a 10 s deadline
on performance.now(), so the clock it read was advanced by a test body that
resumed later.

- startBeeDispatcher(deps, clock = realClock).
- restartBeeActorsOn(clock), for tests only, for the round's singleton.
- startReviewerActors(..., clock = realClock).
- The round and reviewer tests walk a VirtualClock.
- The beat is nodeBeat(start, post, now = monoNow). The live test calls it on
  a clock it holds, so the send time and the start it is compared with come
  from one clock.
- task-queue-service.test.ts copies the real pg and logger modules before it
  mocks them. Before, its restore put the mock back, and the bench's
  setLevel failed as two unnamed errors. This one reproduces on macOS too.

Production is unchanged: every new parameter defaults to the real clock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(queen): actor tests walk a handed clock, not jest fake timers; a logger mock no longer restores itself
@gHashTag
gHashTag merged commit 56c5df7 into queen Oct 10, 2026
18 of 20 checks passed
gHashTag added a commit to gHashTag/trinity that referenced this pull request Oct 10, 2026
…rywhere, seven measured changes to the Queen runtime (Closes #1582) (#1583)

* blog: actors beat the loop on recovery, not everywhere -- seven measured changes to the Queen runtime (Closes #1582)

A post on the Queen actor runtime work of 2026-10-09: the competitor study, the seven
improvements of gHashTag/trios#1712 with the numbers posted on gHashTag/t27#7851, and what
the actor decision card would cost on the bench FPGA (yosys synthesis only). English and
Russian bodies; simulated and measured numbers are labelled as their sources label them.

- bodies/actors-beat-the-loop-on-recovery-not-everywhere.ts, its index.ts entry and the
  posts.ts import and map line.
- public/term/t27c-queen-netlink-fence/: a new recording, made with the exported functions
  of scripts/t27c-mutation-casts.mjs. t27c test-report passes netlink.t27 9 of 9; moving
  the self-fence from 15 s to the 20 s lease fails exactly
  a_node_stops_before_any_peer_can_see_it_down; git restores the spec. Listed first in
  public/term/index.html.
- The post carries the recording as a terminal block in body and ruBody
  (specs/policy/post_widget.t27).

No og-art triptych: every image provider refused (Kie "Credits insufficient", FAL and
Replicate locked), so none is drawn and none is faked; see gHashTag/ghashtag.github.io#45.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: three Russian phrasings in the actors post read naturally (Refs #1582)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: the simulation gate's numbers in the actors post, in both languages (Refs #1582)

Lane 5 of gHashTag/trios#1712 landed (gHashTag/trios#1726 into actors-next, spec
gHashTag/t27#8292 and #8306; numbers on gHashTag/t27#7851). The post's pending section now
gives them: 18 cases of 10,000 steps, each run twice, in 33.5 s on CI with 0 divergences;
four defects put back into the source and caught from a seed; and the real runtime bug the
gate found first (a turn run for a process that had already exited, fixed with a
regression test). The gate's limits (no keyed actors or adaptive pool in its world, no
nightly run) replace "numbers not posted yet" in the open questions and the limits list.
The production merge, gHashTag/trios#1730, is named as open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: say plainly that the gate found the last defect in its table (Refs #1582)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: the actors post says the batch merged into production behind off flags, and gives the quiet-host telemetry cost (Refs #1582)

trios#1730 merged actors-next into the production branch on 2026-10-10 at
13:38Z, so "nothing runs in production; #1730 is open" was no longer true.
The telemetry paragraph now carries the quiet-host A/B from t27#7851
(+3.3% CPU per message, median of 21 rounds) and the base-cost rise from
3.7 to 4.5 us that the same run found, tracked in trios#1743.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: the actors post gives the cost profile's answer - 1.55 us a message on the next batch, and telemetry at the edge of its target (Refs #1582)

trios#1746 found the 4.5 us predates the seven lanes: a card looked up again
on every call by a long key (44% of the time) and slot_of asked three times
a message. The post said lanes 2, 6 and 7 were the likely cause; the profile
says they were not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: resolve the index.ts conflict the main merge left committed, and fix an unescaped quote in the actors post (Refs #1582)

The merge of main in 3de6fae committed index.ts with its conflict markers:
the merge output was cut short and the file was never checked for markers.
This keeps both new posts, ours first, then two-keys-one-verdict from main.
The actors entry's receipts mark trios#1730 MERGED and add #1754 and #1746.
Its open questions now say what is true today: everything is in production
behind off flags, and the telemetry figures are measured, no longer estimated.

The body had "telemetry's" inside a single-quoted string, which broke the
string. Both files and posts.ts now pass `bun build --no-bundle`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot added a commit to gHashTag/trinity that referenced this pull request Oct 10, 2026
feat(website): blog post -- actors beat the loop on recovery, not everywhere, seven measured changes to the Queen runtime (Closes #1582) (#1583)

* blog: actors beat the loop on recovery, not everywhere -- seven measured changes to the Queen runtime (Closes #1582)

A post on the Queen actor runtime work of 2026-10-09: the competitor study, the seven
improvements of gHashTag/trios#1712 with the numbers posted on gHashTag/t27#7851, and what
the actor decision card would cost on the bench FPGA (yosys synthesis only). English and
Russian bodies; simulated and measured numbers are labelled as their sources label them.

- bodies/actors-beat-the-loop-on-recovery-not-everywhere.ts, its index.ts entry and the
  posts.ts import and map line.
- public/term/t27c-queen-netlink-fence/: a new recording, made with the exported functions
  of scripts/t27c-mutation-casts.mjs. t27c test-report passes netlink.t27 9 of 9; moving
  the self-fence from 15 s to the 20 s lease fails exactly
  a_node_stops_before_any_peer_can_see_it_down; git restores the spec. Listed first in
  public/term/index.html.
- The post carries the recording as a terminal block in body and ruBody
  (specs/policy/post_widget.t27).

No og-art triptych: every image provider refused (Kie "Credits insufficient", FAL and
Replicate locked), so none is drawn and none is faked; see gHashTag/ghashtag.github.io#45.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: three Russian phrasings in the actors post read naturally (Refs #1582)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: the simulation gate's numbers in the actors post, in both languages (Refs #1582)

Lane 5 of gHashTag/trios#1712 landed (gHashTag/trios#1726 into actors-next, spec
gHashTag/t27#8292 and #8306; numbers on gHashTag/t27#7851). The post's pending section now
gives them: 18 cases of 10,000 steps, each run twice, in 33.5 s on CI with 0 divergences;
four defects put back into the source and caught from a seed; and the real runtime bug the
gate found first (a turn run for a process that had already exited, fixed with a
regression test). The gate's limits (no keyed actors or adaptive pool in its world, no
nightly run) replace "numbers not posted yet" in the open questions and the limits list.
The production merge, gHashTag/trios#1730, is named as open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: say plainly that the gate found the last defect in its table (Refs #1582)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: the actors post says the batch merged into production behind off flags, and gives the quiet-host telemetry cost (Refs #1582)

trios#1730 merged actors-next into the production branch on 2026-10-10 at
13:38Z, so "nothing runs in production; #1730 is open" was no longer true.
The telemetry paragraph now carries the quiet-host A/B from t27#7851
(+3.3% CPU per message, median of 21 rounds) and the base-cost rise from
3.7 to 4.5 us that the same run found, tracked in trios#1743.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: the actors post gives the cost profile's answer - 1.55 us a message on the next batch, and telemetry at the edge of its target (Refs #1582)

trios#1746 found the 4.5 us predates the seven lanes: a card looked up again
on every call by a long key (44% of the time) and slot_of asked three times
a message. The post said lanes 2, 6 and 7 were the likely cause; the profile
says they were not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* blog: resolve the index.ts conflict the main merge left committed, and fix an unescaped quote in the actors post (Refs #1582)

The merge of main in 3de6fae committed index.ts with its conflict markers:
the merge output was cut short and the file was never checked for markers.
This keeps both new posts, ours first, then two-keys-one-verdict from main.
The actors entry's receipts mark trios#1730 MERGED and add #1754 and #1746.
Its open questions now say what is true today: everything is in production
behind off flags, and the telemetry figures are measured, no longer estimated.

The body had "telemetry's" inside a single-quoted string, which broke the
string. Both files and posts.ts now pass `bun build --no-bundle`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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