researcher: row 80 round 2 packet, mechanical rebase onto row 93 (#1574)

Base da6f1166, r1 patch applied clean with --index, +/- and context lines identical.
Bus suite 127/127, mutants 15 of 15 killed.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
2026-10-13 10:55:33 -05:00
co-authored by Claude Sonnet 5.5
parent b3d43db3a3
commit 199984f29c
24 changed files with 1795 additions and 0 deletions
@@ -0,0 +1,74 @@
# Row 80 (#1574) round 2: mechanical rebase onto row 93
Owner: Researcher. Reviewer: Filbert (approved round 1, comment 28188, on manifest base 57a2ddc5).
Row 93 landed as 4da68152 and changed `packages/bus/src/broker.mjs` and `packages/bus/README.md`,
two of the three candidate paths, so the round 1 manifest hashes no longer match. Decision 127: a
new round. This round changes no code, test, README sentence or mutant.
## Base and method
- Base `da6f1166d63f8047f8b59c9742815c63982f8ae9` (`base.txt`), a fresh detached worktree
(`/mnt/storage/scratch/researcher/q80-r2`).
- `git apply --check --index r1/build.patch` then `git apply --index r1/build.patch`: clean, no
fuzz, no hand merge.
- `build.patch` is `git diff --cached da6f1166` of the same three paths.
- `candidate-manifest.sha256`: the same three paths, repo-relative, verifies with `sha256sum -c`
from the worktree root.
| path | round 1 (base 57a2ddc5) | round 2 (base da6f1166) |
|---|---|---|
| `packages/bus/README.md` | 02fae293... | 675dbeca... |
| `packages/bus/src/broker.mjs` | f685af1c... | 3a9de6f0... |
| `packages/bus/tests/agents.test.mjs` | 076137bc... | 076137bc... (same) |
## r1-to-r2 diff of the patch
The `+` and `-` lines of the two patches (file headers excluded) are 117 each and identical (`diff`
of the two filtered line lists is empty). Every context line is identical too. The two patch files
differ only in the `index` lines and in the hunk start lines:
| file | hunk | r1 start | r2 start | shift |
|---|---|---|---|---|
| `README.md` | 1 | 108 | 129 | +21 |
| `README.md` | 2 | 127 | 150 | +23 |
| `README.md` | 3 | 149 | 172 | +23 |
| `README.md` | 4 | 159 | 182 | +23 |
| `broker.mjs` | 1 (the `STRANDED` constant) | 43 | 43 | 0 |
| `broker.mjs` | 2 (stranded query, `.map`) | 1039 | 1213 | +174 |
| `agents.test.mjs` | 1 | 55 | 55 | 0 |
| `agents.test.mjs` | 2 | 157 | 157 | 0 |
`agents.test.mjs` is byte-identical to round 1. Row 93 added about 174 lines of its own above the
stranded query in `broker.mjs` and 21 to 23 lines above my README hunks; none of it overlaps mine.
## Mutants
`mutants.py` is byte-identical to round 1 (`cmp`). All 15 anchors match exactly once in the r2
`broker.mjs`. The line numbers in the mutant table's labels are round 1's (the runner matches text,
not lines); on this base the stranded query is at 1222 instead of 1048, M12 at 1227, M13 at 1106 and
M15 at 1226. The "expected killer" test lines are unchanged because the test file is.
## Runs
Run on 2026-10-13 (15:54Z onward), in the slot Sage gave for this round, after a cwd-scoped busy
check that read 0. The manifest was verified before the runs and after them (all three paths OK).
Logs are under `out/`.
- Bus suite, `node --test 'tests/*.test.mjs'` in `packages/bus`, run in its own session with the
group killed afterwards, `DOCKER_HOST=unix:///nonexistent.sock` (`out/bus.log`): 127 tests,
127 pass, 0 fail, 0 cancelled, 0 skipped, no `✖`. Round 1 had 120; the extra seven are row 93's
tests on this base, not this candidate.
- `mutants.py <r2 worktree> r2` (`out/mutants-run.log`, `out/summary.txt`, one log per mutant):
baseline green, **15 of 15 killed**, exit 0. Manifest clean after the last restore. No process had
a cwd in the worktree afterwards.
- The test lines that fail for each mutant are the same as round 1's (`out/M*.log` against
`r1/out/M*.log`, the `agents.test.mjs:NNN` sets compared per mutant, equal for all of M01 to M11
and M13 to M15). M12 is flagged "error marker in log" by the runner exactly as in round 1: it
removes `stranded` from the claim row. The key-list assertion at `agents.test.mjs:58` fails, and
the stranded tests throw `TypeError: Cannot read properties of undefined` (reading `length` and
`map`), which is the marker. That is a real kill, not a crash of the runner.
- Not run here: the other bus-adjacent suites and the `scripts/test-*.sh`. Only `packages/bus` paths
changed against the approved round 1 content, and none of the diff beyond hunk offsets is new.
Sage's landing gate reruns them in any case.
- The worktree is kept for the review (`/mnt/storage/scratch/researcher/q80-r2`, three paths staged,
no `node_modules` link needed by the bus suite).
@@ -0,0 +1 @@
da6f1166d63f8047f8b59c9742815c63982f8ae9
@@ -0,0 +1,176 @@
diff --git a/packages/bus/README.md b/packages/bus/README.md
index 793694bae..8f5eec4aa 100644
--- a/packages/bus/README.md
+++ b/packages/bus/README.md
@@ -129,7 +129,9 @@ committed. Callers must inspect its evidence before deciding what to do; they
must not resend automatically. `message.receive` records delivery when the
broker hands the batch to the connection, not when the harness acts on it.
A lost response leaves an uncertain delivery, never automatic replay to a new
-holder. `message.read` is an explicit acknowledgement. `trail(messageId)` lets
+holder. A holder that releases a role without reading what it received leaves
+those messages stranded: no later holder receives or reads them, and `agents`
+lists them under `stranded` (Agent state, below). `message.read` is an explicit acknowledgement. `trail(messageId)` lets
an operator inspect content and delivery evidence after an uncertain result.
| Verb | Arguments and result |
@@ -150,7 +152,7 @@ an operator inspect content and delivery evidence after an uncertain result.
| `launch.revoke`, `launch.restore` | No args; outside-agent human CLI only. |
| `inbox` | No args; plain JSON projection scoped to capability's business. |
| `tasks` | Optional args, scoped to capability's business (row 89, #1583). None: every row of the tasks projection (below). `{task_ref}` alone: that one row, or `task-not-found`. Any of `{done,assignee,label,requirement,limit,after}`: `{tasks,total,next}`, the short form (below). An unknown arg or bad value refuses `invalid-request`. |
-| `agents` | No args; each held role's latest claim row in the capability's business. Human and reader sessions also get `state`, `working` and `inputNeeded` (Agent state, below); a role session gets the claim rows only. |
+| `agents` | No args; each held role's latest claim row in the capability's business. Human and reader sessions also get `state`, `working`, `inputNeeded` and `stranded` (Agent state, below); a role session gets the claim rows only. |
| `trail` | `{subject}`: task ref, decision UUID or message UUID. Linked records in broker write order. |
| `decisions` | `{list}`: `roles` or `recent`; human and reader sessions only. Open decisions routed to a role, or the last 50 closed. |
| `credentials` | No args; human and reader sessions only. `[{service,account,role,dateKind,date,state}]` for the capability's business, never a token, file path or variable name. |
@@ -172,6 +174,12 @@ records the bus already keeps. Nothing new is written and no schema changed.
- `state` is `working` when `working` is set, else `waiting` when
`inputNeeded` is nonempty, else `idle`. Working wins over waiting, as on
the control board.
+- `stranded` lists messages to the role that an earlier holder was delivered
+ and never read, as `{id, from, run, at}`: the sender (`human` for the CLI),
+ the run it was delivered to, and when. Oldest first, at most 50, `[]` when
+ none. The bus neither redelivers, routes nor marks these read, and the
+ released run can no longer read them, so they stay listed. A person who
+ still needs one sends it again as a new message.
Why the bus and not a seat-to-role map: the business file's `holder` is a
display name, and the claim's holder is a run, not a seat, so no committed
@@ -182,7 +190,8 @@ Limits: a message routed but not yet received shows idle. A reply that fails
for a reason other than a gone session leaves its message unread, so the role
stays working; `since` shows how long. No error or offline state is derived.
A new holder doesn't inherit the previous holder's unread deliveries;
-decisions stay with the role. Unheld and released roles aren't listed.
+decisions stay with the role. Unheld and released roles aren't listed, so a
+message stranded for a role nobody holds shows once a run claims the role.
Unknown keys, roles, references, actions and verbs refuse. If writing refusal
evidence fails, the caller receives the static `storage-unavailable` code. `human` is the reserved
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
index 5e874ad3e..4ae20e103 100644
--- a/packages/bus/src/broker.mjs
+++ b/packages/bus/src/broker.mjs
@@ -43,6 +43,8 @@ const CLOSED = "('resolved','withdrawn','expired')";
export const RECENT = 50;
// How many replies `replies` returns, oldest first.
export const REPLIES = 50;
+// Row 80 (#1574): how many stranded messages `agents` lists for each role, oldest first.
+export const STRANDED = 50;
// Row 89 (#1583): the arguments `tasks` takes, and its page size by default and at most.
const TASK_ARGS = ['done', 'assignee', 'label', 'requirement', 'limit', 'after', 'task_ref'];
export const TASK_PAGE = 50;
@@ -1213,7 +1215,16 @@ export class Broker {
.map((d) => ({ id: d.id, question: d.question, class: d.class, blocking: !!d.blocking, task_ref: d.task_ref, at: d.at }));
const working = busy.messages ? { messages: busy.messages, since: busy.since } : null;
const state = working ? 'working' : inputNeeded.length ? 'waiting' : 'idle';
- return { ...c, state, working, inputNeeded };
+ // Row 80 (#1574): messages to the role that an earlier holder was delivered and never read.
+ // The run they went to no longer holds the role. A delivered row already exists, so routing
+ // and receive skip them. Listing them writes nothing.
+ const stranded = this.#store.all(
+ `SELECT m.id, m.from_role AS "from", d.holder_run AS run, d.at FROM messages m JOIN deliveries d ON d.message=m.id AND d.op='delivered' WHERE m.business=? AND m.to_role=? AND d.holder_run IS NOT ? AND NOT EXISTS(SELECT 1 FROM deliveries r WHERE r.message=m.id AND r.op='read') ORDER BY m.seq LIMIT ${STRANDED}`,
+ c.business,
+ c.role,
+ c.holder_run,
+ ).map((m) => ({ id: m.id, from: m.from, run: m.run, at: m.at }));
+ return { ...c, state, working, inputNeeded, stranded };
}
#claimEnd(s, h, op, decision) {
this.#store.run(
diff --git a/packages/bus/tests/agents.test.mjs b/packages/bus/tests/agents.test.mjs
index 23b5126b3..d92933bd6 100644
--- a/packages/bus/tests/agents.test.mjs
+++ b/packages/bus/tests/agents.test.mjs
@@ -55,7 +55,8 @@ test('agents: a held role with nothing on the bus is idle; a role session gets t
['coder', 'idle', null, []],
['pm', 'idle', null, []],
]);
- for (const r of rows) assert.deepEqual(Object.keys(r), [...CLAIM, 'state', 'working', 'inputNeeded']);
+ for (const r of rows) assert.deepEqual(Object.keys(r), [...CLAIM, 'state', 'working', 'inputNeeded', 'stranded']);
+ assert.deepEqual(rows.map((r) => r.stranded), [[], []]);
assert.deepEqual(call(b, reader, 'agents'), rows);
const plain = call(b, pm, 'agents');
for (const r of plain) assert.deepEqual(Object.keys(r), CLAIM);
@@ -157,3 +158,83 @@ test('agents: state reads only its own business, even for a run name both use',
const there = byRole(call(b, otherHuman, 'agents')).cto;
assert.deepEqual([there.state, there.working.messages, there.inputNeeded.length], ['working', 1, 1]);
});
+
+// Row 80 (#1574): a message delivered to a run that released the role unread is stranded for the
+// role. No later holder receives or reads it, and listing it writes no delivery row.
+test('agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it', (t) => {
+ const { b, store, agent, human } = setup(t);
+ const first = agent('pm', 'demo', 'pm-one');
+ const sent = call(b, human, 'message.send', { to: 'pm', body: 'left behind' });
+ assert.deepEqual(call(b, first, 'message.receive').map((m) => m.id), [sent.id]);
+ const before = store.all('SELECT * FROM deliveries');
+ call(b, first, 'role.release');
+ assert.deepEqual(call(b, human, 'agents'), [], 'a released role is not listed');
+ const second = agent('pm', 'demo', 'pm-two');
+ const row = byRole(call(b, human, 'agents')).pm;
+ assert.deepEqual(row.stranded, [{ id: sent.id, from: 'human', run: 'pm-one', at: delivered(store, sent.id) }]);
+ assert.deepEqual(call(b, second, 'message.receive'), []);
+ assert.throws(() => call(b, second, 'message.read', { id: sent.id }), { code: 'not-recipient' });
+ assert.throws(() => call(b, first, 'message.read', { id: sent.id }), { code: 'not-holder' });
+ assert.deepEqual(byRole(call(b, human, 'agents')).pm.stranded, row.stranded);
+ assert.deepEqual(store.all('SELECT * FROM deliveries'), before, 'the claim and the listing write no delivery row');
+});
+
+test('agents: a message the holder read is not stranded; one the current holder has not read is not listed', (t) => {
+ const { b, agent, human } = setup(t);
+ const first = agent('pm', 'demo', 'pm-one');
+ const read = call(b, human, 'message.send', { to: 'pm', body: 'read first' });
+ const unread = call(b, human, 'message.send', { to: 'pm', body: 'still held' });
+ call(b, first, 'message.receive');
+ call(b, first, 'message.read', { id: read.id });
+ assert.deepEqual(byRole(call(b, human, 'agents')).pm.stranded, [], 'the current holder still holds the unread one');
+ call(b, first, 'role.release');
+ agent('pm', 'demo', 'pm-two');
+ assert.deepEqual(byRole(call(b, human, 'agents')).pm.stranded.map((m) => m.id), [unread.id]);
+});
+
+test('agents: stranded is oldest first and capped at 50 for a role', (t) => {
+ const { b, agent, human } = setup(t);
+ const first = agent('pm', 'demo', 'pm-one');
+ const ids = Array.from({ length: 60 }, (_, i) => call(b, human, 'message.send', { to: 'pm', body: `m${i}` }).id);
+ assert.equal(call(b, first, 'message.receive').length, 60);
+ call(b, first, 'role.release');
+ agent('pm', 'demo', 'pm-two');
+ const stranded = byRole(call(b, human, 'agents')).pm.stranded;
+ assert.equal(stranded.length, 50);
+ assert.deepEqual(stranded.map((m) => m.id), ids.slice(0, 50));
+ assert.ok(stranded.every((m) => m.run === 'pm-one' && m.from === 'human'));
+});
+
+test('agents: stranded is per role and per business', (t) => {
+ const { b, agent, human } = setup(t);
+ const cto = agent('cto', 'demo', 'cto-one');
+ const pm = agent('pm', 'demo', 'pm-one');
+ const toCto = call(b, human, 'message.send', { to: 'cto', body: 'for cto' });
+ const toPm = call(b, human, 'message.send', { to: 'pm', body: 'for pm' });
+ call(b, cto, 'message.receive');
+ call(b, pm, 'message.receive');
+ call(b, cto, 'role.release');
+ call(b, pm, 'role.release');
+ agent('cto', 'demo', 'cto-two');
+ agent('pm', 'demo', 'pm-two');
+ const rows = byRole(call(b, human, 'agents'));
+ assert.deepEqual(rows.cto.stranded.map((m) => m.id), [toCto.id]);
+ assert.deepEqual(rows.pm.stranded.map((m) => m.id), [toPm.id]);
+ // The same role and run name in another business stays there.
+ const otherHuman = b.bindHuman({ business: 'other', human: 'jason', via: 'cli', outsideAgent: true });
+ const otherPm = agent('pm', 'other', 'pm-one');
+ const elsewhere = call(b, otherHuman, 'message.send', { to: 'pm', body: 'elsewhere' });
+ call(b, otherPm, 'message.receive');
+ call(b, otherPm, 'role.release');
+ agent('pm', 'other', 'pm-two');
+ assert.deepEqual(byRole(call(b, human, 'agents')).pm.stranded.map((m) => m.id), [toPm.id]);
+ assert.deepEqual(byRole(call(b, otherHuman, 'agents')).pm.stranded.map((m) => m.id), [elsewhere.id]);
+});
+
+// Row 80 (#1574), Sage ruling: a message routed to a held role and not yet received is not stranded.
+test('agents: a message routed to a held role and not yet received is not stranded', (t) => {
+ const { b, agent, human } = setup(t);
+ agent('pm', 'demo', 'pm-one');
+ call(b, human, 'message.send', { to: 'pm', body: 'routed, not received' });
+ assert.deepEqual(byRole(call(b, human, 'agents')).pm.stranded, []);
+});
@@ -0,0 +1,3 @@
675dbecafa919fea7aedaaf7b759e8862cae0cef7ae477570d4c2bbd56cac088 packages/bus/README.md
3a9de6f03a34afe8f450a59b7b880d6a70a2539cd9a9b4924520e6acb22e8838 packages/bus/src/broker.mjs
076137bca90b6594cc0888fb0daa2c57903fff5f1035122c00dd5540de65f6eb packages/bus/tests/agents.test.mjs
@@ -0,0 +1,230 @@
#!/usr/bin/env python3
# Row 80 (#1574) mutation runner. Written in Phase A. NOT RUN.
#
# Phase B usage, from the canonical checkout, after "slot clear":
# DOCKER_HOST=unix:///nonexistent.sock python3 -I <packet>/mutants.py <worktree> <packet>
#
# Every mutant rewrites one exact-once anchor in packages/bus/src/broker.mjs of the
# worktree, runs tests/agents.test.mjs in its own process group under a timeout, and
# restores the original bytes in a finally block. The manifest is checked before the
# baseline and after the last restore. A red baseline aborts before any mutant.
# A timeout is a failure, not a kill.
#
# Exit codes: 0 every mutant killed; 1 a mutant survived or a run timed out;
# 2 baseline red, timed out, or manifest mismatch; 3 an anchor was not found exactly once.
import hashlib
import os
import signal
import subprocess
import sys
TIMEOUT_S = 240
BROKER = 'packages/bus/src/broker.mjs'
SUITE = ['node', '--test', 'tests/agents.test.mjs']
EXTRA_ENV = {'DOCKER_HOST': 'unix:///nonexistent.sock'}
ERROR_MARKERS = ('SqliteError', 'RangeError', 'TypeError', 'ReferenceError', 'SyntaxError')
# (id, file, line in candidate, exact old text, exact new text, expected killer)
MUTANTS = [
('M01', BROKER, 47,
'export const STRANDED = 50;',
'export const STRANDED = 51;',
'agents.test.mjs:203 length 50'),
('M02', BROKER, 1048,
'ORDER BY m.seq LIMIT ${STRANDED}',
'ORDER BY m.seq DESC LIMIT ${STRANDED}',
'agents.test.mjs:204 oldest-first ids'),
('M03', BROKER, 1048,
'ORDER BY m.seq LIMIT ${STRANDED}`',
'ORDER BY m.seq`',
'agents.test.mjs:203 length 50'),
('M04', BROKER, 1048,
'd.holder_run IS NOT ? AND NOT EXISTS',
'(d.holder_run IS NOT ? OR 1=1) AND NOT EXISTS',
'agents.test.mjs:189 current holder still holds the unread one'),
('M05', BROKER, 1048,
'd.holder_run IS NOT ? AND NOT EXISTS',
'd.holder_run = ? AND NOT EXISTS',
'agents.test.mjs:174 released-run entry'),
('M06', BROKER, 1048,
" AND NOT EXISTS(SELECT 1 FROM deliveries r WHERE r.message=m.id AND r.op='read') ORDER BY m.seq LIMIT ${STRANDED}",
" ORDER BY m.seq LIMIT ${STRANDED}",
'agents.test.mjs:192 read message must not be listed'),
('M07', BROKER, 1048,
'WHERE m.business=? AND m.to_role=? AND d.holder_run IS NOT ?',
'WHERE (? IS NULL OR 1=1) AND m.to_role=? AND d.holder_run IS NOT ?',
'agents.test.mjs:230 per business'),
('M08', BROKER, 1048,
'WHERE m.business=? AND m.to_role=? AND d.holder_run IS NOT ?',
'WHERE m.business=? AND (? IS NULL OR 1=1) AND d.holder_run IS NOT ?',
'agents.test.mjs:221 per role'),
('M09', BROKER, 1048,
'd.holder_run AS run, d.at FROM',
'd.holder_run AS holder, d.at FROM',
'agents.test.mjs:174 entry shape'),
('M10', BROKER, 1048,
'm.from_role AS "from"',
'm.from_role AS "sender"',
'agents.test.mjs:174 entry shape'),
('M11', BROKER, 1048,
'd.holder_run AS run, d.at FROM',
'd.holder_run AS run FROM',
'agents.test.mjs:174 entry shape'),
('M12', BROKER, 1053,
'return { ...c, state, working, inputNeeded, stranded };',
'return { ...c, state, working, inputNeeded };',
'agents.test.mjs:58 key list'),
('M13', BROKER, 932,
'return s.human || s.reader ? claims.map((c) => this.#agentState(c)) : claims;',
'return claims.map((c) => this.#agentState(c));',
'agents.test.mjs:62 role session keys'),
('M14', BROKER, 1048,
"JOIN deliveries d ON d.message=m.id AND d.op='delivered' WHERE m.business=? AND m.to_role=? AND d.holder_run IS NOT ?",
"LEFT JOIN deliveries d ON d.message=m.id AND d.op='delivered' WHERE m.business=? AND m.to_role=? AND d.holder_run IS NOT ?",
'agents.test.mjs:239 routed, not yet received, must not be listed'),
('M15', BROKER, 1052,
").map((m) => ({ id: m.id, from: m.from, run: m.run, at: m.at }));",
");",
'agents.test.mjs:174 prototype check'),
]
def sha256_of(path):
digest = hashlib.sha256()
with open(path, 'rb') as handle:
for block in iter(lambda: handle.read(65536), b''):
digest.update(block)
return digest.hexdigest()
def read_manifest(packet):
entries = []
with open(os.path.join(packet, 'candidate-manifest.sha256'), encoding='utf-8') as handle:
for line in handle:
line = line.rstrip('\n')
if line:
digest, rel = line.split(' ', 1)
entries.append((digest, rel))
return entries
def manifest_mismatches(wt, entries):
return [rel for digest, rel in entries if sha256_of(os.path.join(wt, rel)) != digest]
def kill_group(pgid):
try:
os.killpg(pgid, signal.SIGKILL)
except ProcessLookupError:
pass
def run_suite(wt, log_path):
env = dict(os.environ, **EXTRA_ENV)
with open(log_path, 'wb') as log:
proc = subprocess.Popen(
SUITE,
cwd=os.path.join(wt, 'packages', 'bus'),
env=env,
stdout=log,
stderr=subprocess.STDOUT,
start_new_session=True,
)
try:
return proc.wait(timeout=TIMEOUT_S), 'exit'
except subprocess.TimeoutExpired:
kill_group(proc.pid)
proc.wait()
return None, 'timeout'
finally:
kill_group(proc.pid)
def worktree_leftovers(wt):
# Reads /proc cwd links only. Reports; kills nothing outside the run's own group.
found = []
for pid in filter(str.isdigit, os.listdir('/proc')):
try:
cwd = os.readlink(os.path.join('/proc', pid, 'cwd'))
except OSError:
continue
if cwd == wt or cwd.startswith(wt + os.sep):
found.append((pid, cwd))
return found
def main():
if len(sys.argv) != 3:
sys.stderr.write('usage: mutants.py <worktree> <packet_dir>\n')
return 2
wt = os.path.abspath(sys.argv[1])
packet = os.path.abspath(sys.argv[2])
out = os.path.join(packet, 'out')
os.makedirs(out, exist_ok=True)
entries = read_manifest(packet)
broken = manifest_mismatches(wt, entries)
if broken:
print('manifest mismatch before baseline:', broken)
return 2
rc, status = run_suite(wt, os.path.join(out, 'baseline.log'))
if status != 'exit' or rc != 0:
print('baseline red or timed out:', status, rc)
return 2
summary = ['baseline: green']
failures = []
anchor_error = False
for mid, rel, line, old, new, killer in MUTANTS:
path = os.path.join(wt, rel)
with open(path, 'rb') as handle:
original = handle.read()
text = original.decode('utf-8')
count = text.count(old)
if count != 1:
summary.append(f'{mid} {rel}:{line} ANCHOR count={count}; aborting run')
anchor_error = True
break
log_path = os.path.join(out, f'{mid}.log')
try:
with open(path, 'wb') as handle:
handle.write(text.replace(old, new, 1).encode('utf-8'))
rc, status = run_suite(wt, log_path)
finally:
with open(path, 'wb') as handle:
handle.write(original)
with open(log_path, 'r', encoding='utf-8', errors='replace') as handle:
log_text = handle.read()
if status == 'timeout':
verdict = 'TIMEOUT (counted as failure)'
failures.append(mid)
elif rc == 0:
verdict = 'SURVIVED'
failures.append(mid)
elif any(marker in log_text for marker in ERROR_MARKERS):
verdict = 'KILLED (error marker in log; check the reason)'
else:
verdict = 'KILLED'
summary.append(f'{mid} {rel}:{line} {verdict}; expected killer: {killer}')
restored = manifest_mismatches(wt, entries)
leftovers = worktree_leftovers(wt)
summary.append(f'manifest after restore: {"clean" if not restored else restored}')
summary.append(f'processes with cwd in worktree: {leftovers if leftovers else "none"}')
with open(os.path.join(out, 'summary.txt'), 'w', encoding='utf-8') as handle:
handle.write('\n'.join(summary) + '\n')
print('\n'.join(summary))
if anchor_error:
return 3
if restored:
return 2
if failures:
return 1
return 0
if __name__ == '__main__':
sys.exit(main())
@@ -0,0 +1,42 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (12.752283ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (11.240735ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (20.152707ms)
✔ agents: working wins over waiting, and Input needed still shows (8.917002ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (10.939823ms)
✔ agents: state reads only its own business, even for a run name both use (9.944258ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.526615ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (11.189995ms)
✖ agents: stranded is oldest first and capped at 50 for a role (55.217992ms)
✔ agents: stranded is per role and per business (20.109868ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.516322ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 232.590493
✖ failing tests:
test at tests/agents.test.mjs:195:1
✖ agents: stranded is oldest first and capped at 50 for a role (55.217992ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
51 !== 50
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:203:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 51,
expected: 50,
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,195 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (12.644952ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.043868ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (20.352083ms)
✔ agents: working wins over waiting, and Input needed still shows (8.804564ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.001814ms)
✔ agents: state reads only its own business, even for a run name both use (10.304056ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.31177ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.46188ms)
✖ agents: stranded is oldest first and capped at 50 for a role (54.771306ms)
✔ agents: stranded is per role and per business (18.734862ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.037597ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 229.912727
✖ failing tests:
test at tests/agents.test.mjs:195:1
✖ agents: stranded is oldest first and capped at 50 for a role (54.771306ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
+ '55083d44-6ccc-472f-b4aa-67d2200ac7ee',
+ 'aba3d2f8-5f77-45a7-999a-0c668455eaaf',
+ '4d6b208c-0227-437b-9fc4-f48938908190',
+ '817a2628-37fa-48c9-b95c-4a382750c8e6',
+ '3469fb50-6324-4bf1-b35e-5c681eaad143',
+ '732cca8f-3b49-4183-9cfd-922910c5024d',
+ '70b8d139-e963-49a2-ba5b-d4d53f1007f3',
+ '0a910e5c-f97c-49ca-9e6f-ff56274cba63',
+ 'f997cfc5-06c7-478b-b87d-61a73ac2be00',
+ 'ec6ccb41-ac88-43c9-ad9a-f0d5e750f389',
+ 'b02e4ef4-5601-4b75-b240-fc30d23604bc',
+ '5cc97f48-3a53-4870-b663-3b3ab7cbf5c5',
+ '71e88c95-78a2-440b-904c-31aa0695c1a7',
+ 'ae67d33a-b2a4-4997-ae5a-094e9268b7f0',
+ 'a562fc5c-af3d-438c-bab6-7c5a954298b9',
+ '2b762937-d161-49a8-968d-c0f0e99603f7',
+ '2e77c401-bfa4-4a76-af5a-f172f03e9943',
+ '7b74e4e3-dced-4320-ad54-42028e49c82d',
+ '2dbd06b0-aed8-4e7e-9144-0c164c36e529',
+ 'b2f67c76-7fa5-4a3e-9e52-259a669e7f31',
+ '7af9a1c9-cffb-439f-abf6-dcf3ef3bfdf2',
+ '08bf3dd7-2c73-4c86-bb07-f0197c265946',
+ '32b3f6f6-d0eb-4418-b56a-f29eb7341129',
+ '622387f7-12a2-404d-bd40-28719ec955d2',
+ '9631c2f1-71f3-4480-828e-8dc304c438a5',
+ '5d388d47-92a9-4192-a658-e707f38c042e',
+ '17825763-a87a-4cf6-87f5-d251fab9bbe8',
+ '08ef7bc2-4de3-4074-87a3-0c7f14152401',
+ '5f53af06-3c4d-46f7-9a03-02c93fa5a250',
+ '1ffe6436-0cd3-4271-8e21-e10b1d06ea26',
+ '7c9108ce-fd06-497e-9e89-9b4ee37fed0f',
+ 'fb410bae-3dd3-4d4d-9803-c7a9aa6f657a',
+ 'cf673490-4aee-47be-991a-bd1c6b9c59dc',
+ '790d92c3-b5ff-4c38-ab00-93c332e6d391',
+ 'e2186bb0-dbec-4cc6-b378-fefb7ed585f2',
+ '29c055d7-fe86-470c-b6d7-a43e242a0c6e',
+ '0df1ded2-ad94-4041-9d2e-f13f51000f1b',
+ '84388281-1a53-428a-a398-b2ddde7d2ccc',
+ 'd948bdb0-5252-4a9a-be8f-6c40a773329f',
+ '6865edb7-bcd6-4b19-b1f4-be0e039188d7',
+ 'e33f3e07-3f04-49f8-9635-c4fb34129c3c',
+ '9e742413-5eed-431e-9f0a-3b87c62983ff',
+ 'd9d9129e-d5fe-46f9-af77-14a3bae90ac3',
+ 'fb130852-be86-4e4a-bf06-c65bdb71ee52',
+ 'f9d96168-0238-40b7-a32f-ef429385abab',
+ '9f5fe7ac-a645-49ee-b58c-92b0ea770651',
+ '61ba553a-4652-421c-8d11-8e340589bfbf',
+ 'a3dce345-8c28-4b5c-b112-3388df676c24',
+ 'd15d1161-8dcd-483e-a93a-5aa9e22c616d',
- '32983330-24dc-4a92-a261-2deb207f56f1',
- '5c2393c2-f441-4c19-9204-0da1ec77bc3e',
- '05808a4a-3b69-4a8b-bdc0-13a0b31100f5',
- '016012c3-6cc5-497d-8e60-d28067ce24ec',
- '4c8d45cf-05de-4c49-9ebb-1ea07dc2ae66',
- '05d7d203-d380-4798-817c-39a77ccf39d9',
- '2c5e36ad-e899-4710-b8c3-47d29d9f8d97',
- '74de7d01-05b4-4791-b982-d24484b62ba3',
- '4810733b-a7bc-447e-9eab-b269e6d659f2',
- '5b4739ea-0687-4d04-82f3-426ea293f11f',
'164abdd0-de7a-4004-b58e-334f0721765d',
- 'd15d1161-8dcd-483e-a93a-5aa9e22c616d',
- 'a3dce345-8c28-4b5c-b112-3388df676c24',
- '61ba553a-4652-421c-8d11-8e340589bfbf',
- '9f5fe7ac-a645-49ee-b58c-92b0ea770651',
- 'f9d96168-0238-40b7-a32f-ef429385abab',
- 'fb130852-be86-4e4a-bf06-c65bdb71ee52',
- 'd9d9129e-d5fe-46f9-af77-14a3bae90ac3',
- '9e742413-5eed-431e-9f0a-3b87c62983ff',
- 'e33f3e07-3f04-49f8-9635-c4fb34129c3c',
- '6865edb7-bcd6-4b19-b1f4-be0e039188d7',
- 'd948bdb0-5252-4a9a-be8f-6c40a773329f',
- '84388281-1a53-428a-a398-b2ddde7d2ccc',
- '0df1ded2-ad94-4041-9d2e-f13f51000f1b',
- '29c055d7-fe86-470c-b6d7-a43e242a0c6e',
- 'e2186bb0-dbec-4cc6-b378-fefb7ed585f2',
- '790d92c3-b5ff-4c38-ab00-93c332e6d391',
- 'cf673490-4aee-47be-991a-bd1c6b9c59dc',
- 'fb410bae-3dd3-4d4d-9803-c7a9aa6f657a',
- '7c9108ce-fd06-497e-9e89-9b4ee37fed0f',
- '1ffe6436-0cd3-4271-8e21-e10b1d06ea26',
- '5f53af06-3c4d-46f7-9a03-02c93fa5a250',
- '08ef7bc2-4de3-4074-87a3-0c7f14152401',
- '17825763-a87a-4cf6-87f5-d251fab9bbe8',
- '5d388d47-92a9-4192-a658-e707f38c042e',
- '9631c2f1-71f3-4480-828e-8dc304c438a5',
- '622387f7-12a2-404d-bd40-28719ec955d2',
- '32b3f6f6-d0eb-4418-b56a-f29eb7341129',
- '08bf3dd7-2c73-4c86-bb07-f0197c265946',
- '7af9a1c9-cffb-439f-abf6-dcf3ef3bfdf2',
- 'b2f67c76-7fa5-4a3e-9e52-259a669e7f31',
- '2dbd06b0-aed8-4e7e-9144-0c164c36e529',
- '7b74e4e3-dced-4320-ad54-42028e49c82d',
- '2e77c401-bfa4-4a76-af5a-f172f03e9943',
- '2b762937-d161-49a8-968d-c0f0e99603f7',
- 'a562fc5c-af3d-438c-bab6-7c5a954298b9',
- 'ae67d33a-b2a4-4997-ae5a-094e9268b7f0',
- '71e88c95-78a2-440b-904c-31aa0695c1a7',
- '5cc97f48-3a53-4870-b663-3b3ab7cbf5c5',
- 'b02e4ef4-5601-4b75-b240-fc30d23604bc'
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:204:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [
'55083d44-6ccc-472f-b4aa-67d2200ac7ee', 'aba3d2f8-5f77-45a7-999a-0c668455eaaf',
'4d6b208c-0227-437b-9fc4-f48938908190', '817a2628-37fa-48c9-b95c-4a382750c8e6',
'3469fb50-6324-4bf1-b35e-5c681eaad143', '732cca8f-3b49-4183-9cfd-922910c5024d',
'70b8d139-e963-49a2-ba5b-d4d53f1007f3', '0a910e5c-f97c-49ca-9e6f-ff56274cba63',
'f997cfc5-06c7-478b-b87d-61a73ac2be00', 'ec6ccb41-ac88-43c9-ad9a-f0d5e750f389',
'b02e4ef4-5601-4b75-b240-fc30d23604bc', '5cc97f48-3a53-4870-b663-3b3ab7cbf5c5',
'71e88c95-78a2-440b-904c-31aa0695c1a7', 'ae67d33a-b2a4-4997-ae5a-094e9268b7f0',
'a562fc5c-af3d-438c-bab6-7c5a954298b9', '2b762937-d161-49a8-968d-c0f0e99603f7',
'2e77c401-bfa4-4a76-af5a-f172f03e9943', '7b74e4e3-dced-4320-ad54-42028e49c82d',
'2dbd06b0-aed8-4e7e-9144-0c164c36e529', 'b2f67c76-7fa5-4a3e-9e52-259a669e7f31',
'7af9a1c9-cffb-439f-abf6-dcf3ef3bfdf2', '08bf3dd7-2c73-4c86-bb07-f0197c265946',
'32b3f6f6-d0eb-4418-b56a-f29eb7341129', '622387f7-12a2-404d-bd40-28719ec955d2',
'9631c2f1-71f3-4480-828e-8dc304c438a5', '5d388d47-92a9-4192-a658-e707f38c042e',
'17825763-a87a-4cf6-87f5-d251fab9bbe8', '08ef7bc2-4de3-4074-87a3-0c7f14152401',
'5f53af06-3c4d-46f7-9a03-02c93fa5a250', '1ffe6436-0cd3-4271-8e21-e10b1d06ea26',
'7c9108ce-fd06-497e-9e89-9b4ee37fed0f', 'fb410bae-3dd3-4d4d-9803-c7a9aa6f657a',
'cf673490-4aee-47be-991a-bd1c6b9c59dc', '790d92c3-b5ff-4c38-ab00-93c332e6d391',
'e2186bb0-dbec-4cc6-b378-fefb7ed585f2', '29c055d7-fe86-470c-b6d7-a43e242a0c6e',
'0df1ded2-ad94-4041-9d2e-f13f51000f1b', '84388281-1a53-428a-a398-b2ddde7d2ccc',
'd948bdb0-5252-4a9a-be8f-6c40a773329f', '6865edb7-bcd6-4b19-b1f4-be0e039188d7',
'e33f3e07-3f04-49f8-9635-c4fb34129c3c', '9e742413-5eed-431e-9f0a-3b87c62983ff',
'd9d9129e-d5fe-46f9-af77-14a3bae90ac3', 'fb130852-be86-4e4a-bf06-c65bdb71ee52',
'f9d96168-0238-40b7-a32f-ef429385abab', '9f5fe7ac-a645-49ee-b58c-92b0ea770651',
'61ba553a-4652-421c-8d11-8e340589bfbf', 'a3dce345-8c28-4b5c-b112-3388df676c24',
'd15d1161-8dcd-483e-a93a-5aa9e22c616d', '164abdd0-de7a-4004-b58e-334f0721765d'
],
expected: [
'32983330-24dc-4a92-a261-2deb207f56f1', '5c2393c2-f441-4c19-9204-0da1ec77bc3e',
'05808a4a-3b69-4a8b-bdc0-13a0b31100f5', '016012c3-6cc5-497d-8e60-d28067ce24ec',
'4c8d45cf-05de-4c49-9ebb-1ea07dc2ae66', '05d7d203-d380-4798-817c-39a77ccf39d9',
'2c5e36ad-e899-4710-b8c3-47d29d9f8d97', '74de7d01-05b4-4791-b982-d24484b62ba3',
'4810733b-a7bc-447e-9eab-b269e6d659f2', '5b4739ea-0687-4d04-82f3-426ea293f11f',
'164abdd0-de7a-4004-b58e-334f0721765d', 'd15d1161-8dcd-483e-a93a-5aa9e22c616d',
'a3dce345-8c28-4b5c-b112-3388df676c24', '61ba553a-4652-421c-8d11-8e340589bfbf',
'9f5fe7ac-a645-49ee-b58c-92b0ea770651', 'f9d96168-0238-40b7-a32f-ef429385abab',
'fb130852-be86-4e4a-bf06-c65bdb71ee52', 'd9d9129e-d5fe-46f9-af77-14a3bae90ac3',
'9e742413-5eed-431e-9f0a-3b87c62983ff', 'e33f3e07-3f04-49f8-9635-c4fb34129c3c',
'6865edb7-bcd6-4b19-b1f4-be0e039188d7', 'd948bdb0-5252-4a9a-be8f-6c40a773329f',
'84388281-1a53-428a-a398-b2ddde7d2ccc', '0df1ded2-ad94-4041-9d2e-f13f51000f1b',
'29c055d7-fe86-470c-b6d7-a43e242a0c6e', 'e2186bb0-dbec-4cc6-b378-fefb7ed585f2',
'790d92c3-b5ff-4c38-ab00-93c332e6d391', 'cf673490-4aee-47be-991a-bd1c6b9c59dc',
'fb410bae-3dd3-4d4d-9803-c7a9aa6f657a', '7c9108ce-fd06-497e-9e89-9b4ee37fed0f',
'1ffe6436-0cd3-4271-8e21-e10b1d06ea26', '5f53af06-3c4d-46f7-9a03-02c93fa5a250',
'08ef7bc2-4de3-4074-87a3-0c7f14152401', '17825763-a87a-4cf6-87f5-d251fab9bbe8',
'5d388d47-92a9-4192-a658-e707f38c042e', '9631c2f1-71f3-4480-828e-8dc304c438a5',
'622387f7-12a2-404d-bd40-28719ec955d2', '32b3f6f6-d0eb-4418-b56a-f29eb7341129',
'08bf3dd7-2c73-4c86-bb07-f0197c265946', '7af9a1c9-cffb-439f-abf6-dcf3ef3bfdf2',
'b2f67c76-7fa5-4a3e-9e52-259a669e7f31', '2dbd06b0-aed8-4e7e-9144-0c164c36e529',
'7b74e4e3-dced-4320-ad54-42028e49c82d', '2e77c401-bfa4-4a76-af5a-f172f03e9943',
'2b762937-d161-49a8-968d-c0f0e99603f7', 'a562fc5c-af3d-438c-bab6-7c5a954298b9',
'ae67d33a-b2a4-4997-ae5a-094e9268b7f0', '71e88c95-78a2-440b-904c-31aa0695c1a7',
'5cc97f48-3a53-4870-b663-3b3ab7cbf5c5', 'b02e4ef4-5601-4b75-b240-fc30d23604bc'
],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,42 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (14.018212ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.404484ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (19.893261ms)
✔ agents: working wins over waiting, and Input needed still shows (8.853815ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (10.974427ms)
✔ agents: state reads only its own business, even for a run name both use (10.43503ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.94464ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.410041ms)
✖ agents: stranded is oldest first and capped at 50 for a role (57.142324ms)
✔ agents: stranded is per role and per business (19.412245ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.00832ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 233.969426
✖ failing tests:
test at tests/agents.test.mjs:195:1
✖ agents: stranded is oldest first and capped at 50 for a role (57.142324ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
60 !== 50
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:203:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 60,
expected: 50,
operator: 'strictEqual',
diff: 'simple'
}
@@ -0,0 +1,51 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (12.441273ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.365463ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (20.386997ms)
✔ agents: working wins over waiting, and Input needed still shows (8.886053ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.591541ms)
✔ agents: state reads only its own business, even for a run name both use (11.827669ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.05803ms)
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.16891ms)
✔ agents: stranded is oldest first and capped at 50 for a role (54.902965ms)
✔ agents: stranded is per role and per business (20.469862ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.417633ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 230.557747
✖ failing tests:
test at tests/agents.test.mjs:182:1
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.16891ms)
AssertionError [ERR_ASSERTION]: the current holder still holds the unread one
+ actual - expected
+ [
+ {
+ at: '2026-10-13T15:54:54.534Z',
+ from: 'human',
+ id: 'f09f9208-0519-4e62-9983-fa9e5a371098',
+ run: 'pm-one'
+ }
+ ]
- []
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:189:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: [ { id: 'f09f9208-0519-4e62-9983-fa9e5a371098', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:54.534Z' } ],
expected: [],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,127 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.603583ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.768598ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.695439ms)
✔ agents: working wins over waiting, and Input needed still shows (9.135384ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.090242ms)
✔ agents: state reads only its own business, even for a run name both use (10.834505ms)
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.201218ms)
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (9.425631ms)
✖ agents: stranded is oldest first and capped at 50 for a role (53.893519ms)
✖ agents: stranded is per role and per business (14.252833ms)
✔ agents: a message routed to a held role and not yet received is not stranded (8.036001ms)
ℹ tests 11
ℹ suites 0
ℹ pass 7
ℹ fail 4
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 228.950329
✖ failing tests:
test at tests/agents.test.mjs:164:1
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.201218ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ []
- [
- {
- at: '2026-10-13T15:54:54.788Z',
- from: 'human',
- id: '35c01e7d-5a6f-49c7-8a37-e26a05590a9e',
- run: 'pm-one'
- }
- ]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:174:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [],
expected: [ { id: '35c01e7d-5a6f-49c7-8a37-e26a05590a9e', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:54.788Z' } ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:182:1
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (9.425631ms)
AssertionError [ERR_ASSERTION]: the current holder still holds the unread one
+ actual - expected
+ [
+ {
+ at: '2026-10-13T15:54:54.803Z',
+ from: 'human',
+ id: 'b218866b-1f08-464e-b9f8-9d9b18c5f232',
+ run: 'pm-one'
+ }
+ ]
- []
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:189:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: [ { id: 'b218866b-1f08-464e-b9f8-9d9b18c5f232', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:54.803Z' } ],
expected: [],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:195:1
✖ agents: stranded is oldest first and capped at 50 for a role (53.893519ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
0 !== 50
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:203:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 0,
expected: 50,
operator: 'strictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:208:1
✖ agents: stranded is per role and per business (14.252833ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ []
- [
- '48a7749f-aab3-45ce-8653-509af8229b12'
- ]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:221:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [],
expected: [ '48a7749f-aab3-45ce-8653-509af8229b12' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,46 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.888453ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (13.65915ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (22.26238ms)
✔ agents: working wins over waiting, and Input needed still shows (8.987118ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.506964ms)
✔ agents: state reads only its own business, even for a run name both use (10.166438ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.526489ms)
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (11.724248ms)
✔ agents: stranded is oldest first and capped at 50 for a role (55.948507ms)
✔ agents: stranded is per role and per business (20.512801ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.099627ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 236.733094
✖ failing tests:
test at tests/agents.test.mjs:182:1
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (11.724248ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
+ '0a5efc06-e6a8-472b-9f55-fc6f9fb482a5',
'9a1ffff2-368c-4d5e-9eda-6fd8f72b69ed'
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:192:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ '0a5efc06-e6a8-472b-9f55-fc6f9fb482a5', '9a1ffff2-368c-4d5e-9eda-6fd8f72b69ed' ],
expected: [ '9a1ffff2-368c-4d5e-9eda-6fd8f72b69ed' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,46 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (14.346021ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.179165ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (20.658504ms)
✔ agents: working wins over waiting, and Input needed still shows (9.085835ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.039131ms)
✔ agents: state reads only its own business, even for a run name both use (11.056366ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.269627ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.467907ms)
✔ agents: stranded is oldest first and capped at 50 for a role (56.707206ms)
✖ agents: stranded is per role and per business (21.362732ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.107534ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 236.172894
✖ failing tests:
test at tests/agents.test.mjs:208:1
✖ agents: stranded is per role and per business (21.362732ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'152a2f1f-bb60-4db3-b8ff-f7915003f179',
+ '2028732b-3a61-4195-9e18-f210c6dfbc93'
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:230:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ '152a2f1f-bb60-4db3-b8ff-f7915003f179', '2028732b-3a61-4195-9e18-f210c6dfbc93' ],
expected: [ '152a2f1f-bb60-4db3-b8ff-f7915003f179' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,46 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.099202ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (11.574989ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (20.836902ms)
✔ agents: working wins over waiting, and Input needed still shows (8.522758ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.084594ms)
✔ agents: state reads only its own business, even for a run name both use (10.116703ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.93297ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (11.008621ms)
✔ agents: stranded is oldest first and capped at 50 for a role (57.268506ms)
✖ agents: stranded is per role and per business (16.263865ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.184589ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 232.816469
✖ failing tests:
test at tests/agents.test.mjs:208:1
✖ agents: stranded is per role and per business (16.263865ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
'3740d3df-f725-472f-99d5-468cd0e727ff',
+ '75af8c99-4e9e-4b55-871d-2970554900f7'
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:221:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ '3740d3df-f725-472f-99d5-468cd0e727ff', '75af8c99-4e9e-4b55-871d-2970554900f7' ],
expected: [ '3740d3df-f725-472f-99d5-468cd0e727ff' ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,72 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.499518ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (11.611927ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (20.082579ms)
✔ agents: working wins over waiting, and Input needed still shows (8.630664ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (10.615003ms)
✔ agents: state reads only its own business, even for a run name both use (10.395844ms)
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.315943ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.583457ms)
✖ agents: stranded is oldest first and capped at 50 for a role (56.519586ms)
✔ agents: stranded is per role and per business (18.860954ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.368797ms)
ℹ tests 11
ℹ suites 0
ℹ pass 9
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 230.171638
✖ failing tests:
test at tests/agents.test.mjs:164:1
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.315943ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
{
at: '2026-10-13T15:54:55.893Z',
from: 'human',
id: '22eae422-d3be-4b20-9973-1359640c03ee',
+ run: undefined
- run: 'pm-one'
}
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:174:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ { id: '22eae422-d3be-4b20-9973-1359640c03ee', from: 'human', run: undefined, at: '2026-10-13T15:54:55.893Z' } ],
expected: [ { id: '22eae422-d3be-4b20-9973-1359640c03ee', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:55.893Z' } ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:195:1
✖ agents: stranded is oldest first and capped at 50 for a role (56.519586ms)
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(stranded.every((m) => m.run === 'pm-one' && m.from === 'human'))
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:205:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '==',
diff: 'simple'
}
@@ -0,0 +1,72 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (14.749974ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.712908ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.523376ms)
✔ agents: working wins over waiting, and Input needed still shows (8.772902ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (10.237821ms)
✔ agents: state reads only its own business, even for a run name both use (10.496983ms)
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.98424ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (12.496498ms)
✖ agents: stranded is oldest first and capped at 50 for a role (59.486742ms)
✔ agents: stranded is per role and per business (20.480728ms)
✔ agents: a message routed to a held role and not yet received is not stranded (8.046688ms)
ℹ tests 11
ℹ suites 0
ℹ pass 9
ℹ fail 2
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 241.88664
✖ failing tests:
test at tests/agents.test.mjs:164:1
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.98424ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
{
at: '2026-10-13T15:54:56.162Z',
+ from: undefined,
- from: 'human',
id: '1d17a7d6-ed07-49ce-ad5d-4eb58027e704',
run: 'pm-one'
}
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:174:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ { id: '1d17a7d6-ed07-49ce-ad5d-4eb58027e704', from: undefined, run: 'pm-one', at: '2026-10-13T15:54:56.162Z' } ],
expected: [ { id: '1d17a7d6-ed07-49ce-ad5d-4eb58027e704', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:56.162Z' } ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:195:1
✖ agents: stranded is oldest first and capped at 50 for a role (59.486742ms)
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(stranded.every((m) => m.run === 'pm-one' && m.from === 'human'))
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:205:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '==',
diff: 'simple'
}
@@ -0,0 +1,51 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.637931ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.452222ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.902184ms)
✔ agents: working wins over waiting, and Input needed still shows (8.889045ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (10.704331ms)
✔ agents: state reads only its own business, even for a run name both use (10.471403ms)
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.165932ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (11.070015ms)
✔ agents: stranded is oldest first and capped at 50 for a role (54.486704ms)
✔ agents: stranded is per role and per business (19.40219ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.188969ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 239.342075
✖ failing tests:
test at tests/agents.test.mjs:164:1
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.165932ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
{
+ at: undefined,
- at: '2026-10-13T15:54:56.486Z',
from: 'human',
id: '72f80f6c-e2b3-4a4f-b1a9-84ef273e6196',
run: 'pm-one'
}
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:174:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ { id: '72f80f6c-e2b3-4a4f-b1a9-84ef273e6196', from: 'human', run: 'pm-one', at: undefined } ],
expected: [ { id: '72f80f6c-e2b3-4a4f-b1a9-84ef273e6196', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:56.486Z' } ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,161 @@
✖ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.873899ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.107001ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.840592ms)
✔ agents: working wins over waiting, and Input needed still shows (8.829779ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (10.687187ms)
✔ agents: state reads only its own business, even for a run name both use (10.972897ms)
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.820835ms)
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (9.309512ms)
✖ agents: stranded is oldest first and capped at 50 for a role (65.325186ms)
✖ agents: stranded is per role and per business (17.974378ms)
✖ agents: a message routed to a held role and not yet received is not stranded (8.761726ms)
ℹ tests 11
ℹ suites 0
ℹ pass 5
ℹ fail 6
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 243.88499
✖ failing tests:
test at tests/agents.test.mjs:49:1
✖ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.873899ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
... Skipped lines
[
'seq',
'at',
'business',
'role',
...
'inputNeeded',
- 'stranded'
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:58:32)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [
'seq', 'at',
'business', 'role',
'op', 'holder_run',
'harness', 'address',
'by', 'reason',
'decision', 'state',
'working', 'inputNeeded'
],
expected: [
'seq', 'at',
'business', 'role',
'op', 'holder_run',
'harness', 'address',
'by', 'reason',
'decision', 'state',
'working', 'inputNeeded',
'stranded'
],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:164:1
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.820835ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ undefined
- [
- {
- at: '2026-10-13T15:54:56.794Z',
- from: 'human',
- id: '8fb72196-1a2e-423e-8ee0-ebec5987d3b6',
- run: 'pm-one'
- }
- ]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:174:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: undefined,
expected: [ { id: '8fb72196-1a2e-423e-8ee0-ebec5987d3b6', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:56.794Z' } ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:182:1
✖ agents: a message the holder read is not stranded; one the current holder has not read is not listed (9.309512ms)
AssertionError [ERR_ASSERTION]: the current holder still holds the unread one
undefined !== []
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:189:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: [],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at tests/agents.test.mjs:195:1
✖ agents: stranded is oldest first and capped at 50 for a role (65.325186ms)
TypeError: Cannot read properties of undefined (reading 'length')
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:203:25)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
test at tests/agents.test.mjs:208:1
✖ agents: stranded is per role and per business (17.974378ms)
TypeError: Cannot read properties of undefined (reading 'map')
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:221:38)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
test at tests/agents.test.mjs:235:1
✖ agents: a message routed to a held role and not yet received is not stranded (8.761726ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
undefined !== []
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:239:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: undefined,
expected: [],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,69 @@
✖ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (14.161771ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.319292ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.004589ms)
✔ agents: working wins over waiting, and Input needed still shows (8.877211ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.507099ms)
✔ agents: state reads only its own business, even for a run name both use (10.642701ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.781784ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (11.017624ms)
✔ agents: stranded is oldest first and capped at 50 for a role (59.127457ms)
✔ agents: stranded is per role and per business (21.121818ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.260205ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 236.650829
✖ failing tests:
test at tests/agents.test.mjs:49:1
✖ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (14.161771ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
... Skipped lines
[
'seq',
'at',
'business',
'role',
...
'decision',
+ 'state',
+ 'working',
+ 'inputNeeded',
+ 'stranded'
]
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:62:33)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.start (node:internal/test_runner/test:1262:17)
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [
'seq', 'at',
'business', 'role',
'op', 'holder_run',
'harness', 'address',
'by', 'reason',
'decision', 'state',
'working', 'inputNeeded',
'stranded'
],
expected: [
'seq', 'at',
'business', 'role',
'op', 'holder_run',
'harness', 'address',
'by', 'reason',
'decision'
],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,51 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.592132ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.332976ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.73254ms)
✔ agents: working wins over waiting, and Input needed still shows (9.029973ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.28727ms)
✔ agents: state reads only its own business, even for a run name both use (10.541998ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (12.3017ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (11.246773ms)
✔ agents: stranded is oldest first and capped at 50 for a role (57.252666ms)
✔ agents: stranded is per role and per business (20.421571ms)
✖ agents: a message routed to a held role and not yet received is not stranded (8.847394ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 241.798137
✖ failing tests:
test at tests/agents.test.mjs:235:1
✖ agents: a message routed to a held role and not yet received is not stranded (8.847394ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ [
+ {
+ at: null,
+ from: 'human',
+ id: '0e45b017-c5e9-4fab-9fff-6980322dbfac',
+ run: null
+ }
+ ]
- []
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:239:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ { id: '0e45b017-c5e9-4fab-9fff-6980322dbfac', from: 'human', run: null, at: null } ],
expected: [],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,50 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (13.381601ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (12.415948ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.834708ms)
✔ agents: working wins over waiting, and Input needed still shows (8.677509ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.278163ms)
✔ agents: state reads only its own business, even for a run name both use (11.077726ms)
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.529937ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.97762ms)
✔ agents: stranded is oldest first and capped at 50 for a role (56.457296ms)
✔ agents: stranded is per role and per business (19.684156ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.564294ms)
ℹ tests 11
ℹ suites 0
ℹ pass 10
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 237.315375
✖ failing tests:
test at tests/agents.test.mjs:164:1
✖ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (10.529937ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
+ [Object: null prototype] {
- {
at: '2026-10-13T15:54:57.688Z',
from: 'human',
id: 'fc5a07d7-12d5-4583-83a8-19eb89488a4f',
run: 'pm-one'
}
at TestContext.<anonymous> (file:///mnt/storage/scratch/researcher/q80-r2/packages/bus/tests/agents.test.mjs:174:10)
at Test.runInAsyncScope (node:async_hooks:226:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ { id: 'fc5a07d7-12d5-4583-83a8-19eb89488a4f', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:57.688Z' } ],
expected: [ { id: 'fc5a07d7-12d5-4583-83a8-19eb89488a4f', from: 'human', run: 'pm-one', at: '2026-10-13T15:54:57.688Z' } ],
operator: 'deepStrictEqual',
diff: 'simple'
}
@@ -0,0 +1,19 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (14.632113ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (11.807351ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (21.851296ms)
✔ agents: working wins over waiting, and Input needed still shows (9.198706ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (11.028259ms)
✔ agents: state reads only its own business, even for a run name both use (10.825864ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (11.742989ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (10.529818ms)
✔ agents: stranded is oldest first and capped at 50 for a role (54.811441ms)
✔ agents: stranded is per role and per business (19.222134ms)
✔ agents: a message routed to a held role and not yet received is not stranded (7.342224ms)
ℹ tests 11
ℹ suites 0
ℹ pass 11
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 234.808698
@@ -0,0 +1,135 @@
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (28.850456ms)
✔ agents: working counts what the holder received and has not read; routed alone is not working (25.950478ms)
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (40.124738ms)
✔ agents: working wins over waiting, and Input needed still shows (18.841393ms)
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (26.567608ms)
✔ agents: state reads only its own business, even for a run name both use (26.226792ms)
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (25.374916ms)
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (25.348226ms)
✔ agents: stranded is oldest first and capped at 50 for a role (102.957295ms)
✔ agents: stranded is per role and per business (34.984157ms)
✔ agents: a message routed to a held role and not yet received is not stranded (13.10151ms)
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (33.35906ms)
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (29.135763ms)
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (31.300996ms)
✔ launch events require a human CLI capability; generic emit cannot forge authority events (19.811423ms)
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (22.599272ms)
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (25.400108ms)
✔ task action subjects and linked decision trail are complete and ordered (30.968353ms)
✔ launch binding is durable and reconnecting requires the identical trusted record (14.61573ms)
✔ business isolation includes inherited object names and cross-business message references (26.337654ms)
✔ authority never transfers between action, run, target, unresolved or replaced role holder (30.663888ms)
✔ task projection uses schema current view, skipping earlier and equal-start polls (15.494337ms)
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (23.321581ms)
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (12.418832ms)
✔ both arbiters require human resolution when their cross-role route is themselves (23.437939ms)
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (19.013415ms)
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (1.919809ms)
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (22.036894ms)
✔ credentials refuses a role session and any argument (20.898089ms)
✔ credentials reads the status on each request, and a broker without one lists none (25.414938ms)
✔ the broker process answers credentials without a token, path or variable in its output, log or store (86.113751ms)
✔ only validated broker references load; returned data and exceptions cannot expose a known token (3.923796ms)
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (2.514317ms)
✔ expiry refuses use and env references never become client data (0.821612ms)
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.862003ms)
✔ opaque tokens shorter than 16 characters refuse before use (0.411543ms)
✔ roles lists open decisions routed to a role, and never the human inbox (38.302998ms)
✔ recent lists closed decisions of every route, newest close first, with how each closed (35.730009ms)
✔ recent gives the closing event as closed when the decision was seen first (33.859094ms)
✔ recent stops at RECENT rows (121.35887ms)
✔ every row is what trail already gives the same session for that id (43.958557ms)
✔ a role session can't list decisions, so it can't read another role's open decisions (40.758066ms)
✔ decisions is a read: one business, strict arguments, nothing written (38.568074ms)
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (22.478181ms)
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (16.945686ms)
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (17.429192ms)
✔ endLaunch leaves a claim another run took alone (19.233864ms)
✔ refuse records action.refused against the caller with the code only (16.516819ms)
✔ launches off refuses role.launch with launch-revoked until launches on (20.857816ms)
✔ broker process: launch ops authorize role.launch, record refusals and end runs (107.012401ms)
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (3.208104ms)
✔ process reader gets own kernel identity without exposing environment values (0.700624ms)
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (1.014972ms)
✔ real pid 1 remains inspectable when its environment is protected (0.469097ms)
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (30.577464ms)
✔ missing and foreign-business citations refuse and roll back message and grant (22.701747ms)
✔ cross-role sends still need a matching resolved decision and consume it once (29.137333ms)
✔ messages pages all human messages newest first without writes; read state is history (374.426935ms)
✔ messages refuses role callers, invalid paging and cursors outside this human feed (18.507172ms)
✔ views messages passes only its paging arguments through (0.253538ms)
✔ messages isolates businesses even with a valid foreign cursor (10.639526ms)
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (90.421648ms)
✔ startup token refusal returns safe code without value or partial listening broker (53.49301ms)
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (85.750514ms)
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (102.78912ms)
✔ trusted host registers later launches; socket clients never have a registration verb (58.169052ms)
✔ runtime excludes declared project roots even when host supplies no repoRoots (41.294145ms)
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (52.867407ms)
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (41.812722ms)
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (22.411282ms)
✔ a message with no reply gives an empty list (19.261881ms)
✔ replies come oldest first and stop at REPLIES (98.408411ms)
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (38.607871ms)
✔ strict arguments; a role session gets human-required (39.461786ms)
✔ views passes replies through as one call with the id (0.255807ms)
✔ requirements returns the committed list to a holding role session, and no one else (32.768416ms)
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (18.533559ms)
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (21.318731ms)
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (32.851181ms)
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (28.26103ms)
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (47.894246ms)
✔ reviewFetch answers only the addressed reviewer, for the request it cites (32.514957ms)
✔ review.verdict answers one request once, to the role that asked (32.952745ms)
✔ task.close on a pushed task needs an approve verdict for the latest push (50.017638ms)
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (27.900102ms)
✔ v3b prototype refusals, views and append-only mutations (94.359391ms)
✔ gated approval authorizes once, survives store reopen, and fresh approval works (35.84911ms)
✔ another run cannot consume an approval; a failed check leaves it usable (26.125971ms)
✔ two scheduled callers have exactly one grant and one consumed refusal (26.948956ms)
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (38.992167ms)
✔ class drift gated to cross-role refuses before consumption (29.787033ms)
✔ class drift cross-role to gated refuses before consumption (30.891386ms)
✔ class drift gated to within-role refuses before consumption (23.437157ms)
✔ class drift cross-role to within-role refuses before consumption (26.103376ms)
✔ class drift within-role to gated refuses before consumption (19.75232ms)
✔ class drift within-role to cross-role refuses before consumption (19.812696ms)
✔ message.send consumes approval and prevents a later send or authorize (19.605373ms)
✔ role.revoke consumes approval and prevents a later revoke or authorize (20.702931ms)
✔ creates private WAL store and excludes a second writer until explicit close (18.464549ms)
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (19.584761ms)
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (20.851901ms)
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (68.3658ms)
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (13.971615ms)
✔ async transactions refuse before invoking their function (12.347706ms)
✔ the session default fits under the reply cap and pages to the end with next (180.020167ms)
✔ the short form: no description, assignees by role, every listed key (89.833222ms)
✔ each filter, alone and together, and total counts every match (162.873155ms)
✔ task_ref reads one task in full, as the whole board has it (86.170052ms)
✔ no arguments is the read the Console and mosaic make, unchanged (67.640008ms)
✔ an unknown argument or a bad value refuses invalid-request (284.211316ms)
✔ tasks rows carry priority and requirement for every session that reads tasks (43.378945ms)
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (59.817601ms)
✔ an empty business and one with snapshots but no task.created read cleanly (13.060277ms)
✔ recordTask keeps sync reads and a role write apart (26.779804ms)
✔ read_at must be one canonical UTC format, so the projection compares strings safely (14.289016ms)
✔ a bad entry refuses the whole record (14.108876ms)
✔ taskView reads the projection for one business (15.834154ms)
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (27.786318ms)
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (274.241659ms)
✔ without an adapter the server refuses every task verb (15.759583ms)
✔ the runtime refuses an invalid adapter and closes a valid one (15.467031ms)
✔ the process loads the S3 adapter from plain-data trackers (98.397273ms)
✔ socket capability stamps launch identity; shared views use wire, no SQL client (35.694185ms)
✔ two wire claims serialize; a lost reply never automatically retries (25.258957ms)
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (12.411913ms)
✔ client preserves UTF-8 when a response divides a multibyte character (13.001424ms)
✔ committed mutation followed by dropped reply reports unknown and is never retried (16.590033ms)
ℹ tests 127
ℹ suites 0
ℹ pass 127
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1022.490245
@@ -0,0 +1,18 @@
baseline: green
M01 packages/bus/src/broker.mjs:47 KILLED; expected killer: agents.test.mjs:203 length 50
M02 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:204 oldest-first ids
M03 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:203 length 50
M04 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:189 current holder still holds the unread one
M05 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 released-run entry
M06 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:192 read message must not be listed
M07 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:230 per business
M08 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:221 per role
M09 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 entry shape
M10 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 entry shape
M11 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 entry shape
M12 packages/bus/src/broker.mjs:1053 KILLED (error marker in log; check the reason); expected killer: agents.test.mjs:58 key list
M13 packages/bus/src/broker.mjs:932 KILLED; expected killer: agents.test.mjs:62 role session keys
M14 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:239 routed, not yet received, must not be listed
M15 packages/bus/src/broker.mjs:1052 KILLED; expected killer: agents.test.mjs:174 prototype check
manifest after restore: clean
processes with cwd in worktree: none
@@ -0,0 +1,18 @@
baseline: green
M01 packages/bus/src/broker.mjs:47 KILLED; expected killer: agents.test.mjs:203 length 50
M02 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:204 oldest-first ids
M03 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:203 length 50
M04 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:189 current holder still holds the unread one
M05 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 released-run entry
M06 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:192 read message must not be listed
M07 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:230 per business
M08 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:221 per role
M09 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 entry shape
M10 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 entry shape
M11 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:174 entry shape
M12 packages/bus/src/broker.mjs:1053 KILLED (error marker in log; check the reason); expected killer: agents.test.mjs:58 key list
M13 packages/bus/src/broker.mjs:932 KILLED; expected killer: agents.test.mjs:62 role session keys
M14 packages/bus/src/broker.mjs:1048 KILLED; expected killer: agents.test.mjs:239 routed, not yet received, must not be listed
M15 packages/bus/src/broker.mjs:1052 KILLED; expected killer: agents.test.mjs:174 prototype check
manifest after restore: clean
processes with cwd in worktree: none