gizmoduck: row 302 (#1809) gate results: run 1 stopped on launcher-released.test:89 (d6, mos-1430); run 2 on merge 783602e06 (5b63ea323 onto 1ac655005) red as ruled, suites green, M1-M5 M7-M9 killed; RESULTS.md and logs, packet only

This commit is contained in:
jason.woltje committed 2026-10-23 03:47:38 -05:00
1 parent c9fcf9b5af
commit 3ed9fd754a
5 files changed
+550

No files matched your search

+112
View File
@@ -0,0 +1,112 @@
# Row 302 (#1809): gate results
The slot ran from 08:15Z on 2026-10-23 (sage-3289), with Sage as gate owner and Dewey as reviewer.
Logs: run1/gate-run.log and run2/gate-run.log. Script: run2/run-gate.sh and run2/mutants.py. The
full per-file logs stay in /mnt/storage/scratch/gizmo-302-out/gate-run1/ and gate/.
## Commits
| Commit | What |
| --- | --- |
| f799e8b15 | red first: the tests over unfixed product (d5) |
| 64f6558ee | the fix |
| 5b63ea323 | d6: launcher-released.test.mjs:89, Mos ruling mos-1430 (relayed in sage-3297) |
The 5b63ea323 subject still says "Mos ruling pending sage-3293; local, not pushed". I wrote it before
mos-1430 arrived, and Sage said not to amend. The ruling is mos-1430, and the commit was pushed as a
fast-forward at about 08:23Z.
## Run 1 (08:18Z): stopped on a red outside the four pins
- Gate tree: 649ec67ab, a local merge of 64f6558ee onto origin/refactor 1ac655005.
- Red stage: as expected (the same reds as run 2).
- Green on 649ec67ab: idle-stop-race 1/1, runner.test 40/40 and compactions-launch 5/5. Then bus had
875 of 876 pass. The red was this row's own test, at launcher-released.test.mjs:89, 1 !== 0.
- It stopped at 08:19:28Z and went to Sage (gizmoduck-0388), then Mos. BUILD.md d6 has the cause.
## Run 2 (08:23:41Z to 08:38:14Z, 873 s)
The gate tree was 783602e06ed92f99c7c71d1e9c016a0f9e2c9b28, a local merge (not pushed). Parent 1 is
origin/refactor 1ac655005, and parent 2 is 5b63ea323. The 12 row paths equal 5b63ea323's, and none
of them changes in 0e30a85fa..1ac655005.
### Red: f799e8b15's product with the final test files from 5b63ea323
The five final test blobs:
| Blob | File |
| --- | --- |
| 52343932b231691ba2b4fc117547ea7f6f504704 | packages/bus/tests/land.test.mjs |
| 6fb6e15c2fd34f742f9aab718ff654ab2704e198 | packages/bus/tests/launcher-released.test.mjs (new in d6) |
| 27193a745c4ed8d4936de96c1768ab010a572856 | packages/bus/tests/threads.test.mjs |
| 9dfacfea15a487c4e7056ebae3e311cb514b0467 | packages/cli/tests/idle-stop-race.test.mjs |
| 0792431b60314a17ed74b3df0c5b3748dc3c1286 | packages/harness/tests/runner.test.mjs |
The script checked each blob with hash-object on the red tree. Only launcher-released differs from
f799e8b15, and no product file differs from it.
There were seven reds, and nothing else failed:
- idle-stop-race: the released run ended with 'session stopped working: not-holder', exit 22 not 0
- runner.test landing case: pin :771, with 22 vs 0
- threads.test threadIdle case: pin :394
- land.test landRelease case: pin :464
- launcher-released: all three tests
On the bus files, 33 of 38 passed and 5 failed.
Pin :772 sits after :771 in the same test, so :771 stops the test first. :771's message is out.stderr,
and that shows the old "session stopped working: not-holder" line and no "session released by the
launcher" line. :89's two new lines never run on red, because the earlier refusals fail first. Run 2's
green bus stage is their first green.
### Green on 783602e06
| Run | Result | Wall |
| --- | --- | --- |
| idle-stop-race | 1/1 | 2 s |
| runner.test whole | 40/40 | 12 s |
| compactions-launch | 5/5 | 14 s |
| bus | 876/876 | 24 s |
| harness | 151/151 | 13 s |
| cli | 918/918 | 615 s |
| test-auth | 15 | |
| test-conductor | 17 | |
| test-config | 55 | |
| test-discord | 81 | |
| test-extension-package | 18 | |
| test-foundation | 44 | |
| test-land-work | 86 | |
| test-queue | node 156/156, suite 28 | |
| test-release | 14 | |
| test-task | 91 | |
Every scripts/test-*.sh ended with rc 0 and 0 failed. The node suites skipped nothing and left no
todo. The tree was clean after the tests.
The shell scripts skipped two things:
- test-queue: "queue verify and render --check: this checkout is not the queue's canonical root".
The gate runs in a worktree, not /mnt/storage/src/mosaic-stack.
- test-task: "live provider cases (row 244: no provider call in the gate)", printed twice. It printed
no other skip line, so no Docker group was skipped.
### Mutants on 783602e06
Each kill file ran whole, and every listed test name had to fail. After each mutant the file was
checked out again and matched its sha256. At the end, broker.mjs was 0c6dbbc5… and runner.mjs was
72ec39eb…, both equal to 5b63ea323's, and the tree was clean.
| Mutant | Change | Killed by |
| --- | --- | --- |
| M1 | no add after threadIdle's release | launcher-released (threadIdle), idle-stop-race |
| M2 | #agent always not-holder | land, launcher-released (threadIdle, landRelease), idle-stop-race, runner landing case |
| M3 | runner ignores launcher-released | idle-stop-race, runner landing case |
| M4 | a released run exits session | idle-stop-race, runner landing case |
| M5 | every lost claim reads launcher-released | launcher-released (other way), idle-stop-race |
| M7 | role.claim's D1 check removed | launcher-released (threadIdle, landRelease) |
| M8 | no add after landRelease's release | land, launcher-released (landRelease), runner landing case |
| M9 | exit releases a launcher-released run | idle-stop-race |
All eight were killed by rule, and none survived. When the run ended, no node process had its cwd in
the worktree.
@@ -0,0 +1,57 @@
blobs: the five d5 test blobs match in f799e8b15561ea2c0f0735e5328ba149c7a1a7b5 and 649ec67abcd315ac877bbad65742017b998137e4
merge: 649ec67abcd315ac877bbad65742017b998137e4 = 64f6558ee4cc536447c720eb20b1f675f32ffbf0 onto 1ac655005e611157605a0dcc5adf7a37f9bca2b0; 12 row paths equal to 64f6558ee4cc536447c720eb20b1f675f32ffbf0, none touched in 0e30a85fa..1ac655005e611157605a0dcc5adf7a37f9bca2b0
TIP 649ec67abcd315ac877bbad65742017b998137e4 (merge) FIX 64f6558ee4cc536447c720eb20b1f675f32ffbf0 RED f799e8b15561ea2c0f0735e5328ba149c7a1a7b5 base 0e30a85fa onto 1ac655005e611157605a0dcc5adf7a37f9bca2b0 origin/refactor 1ac655005e611157605a0dcc5adf7a37f9bca2b0 start 2026-10-23T08:18:31Z
loadavg: 1.63 1.48 1.89 5/6323 1532949
== 1. red first on f799e8b15561ea2c0f0735e5328ba149c7a1a7b5 (unfixed product, final tests)
TMPDIR /mnt/storage/scratch/tmp/ggiJ
idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
TMPDIR /mnt/storage/scratch/tmp/g2U9
runner-land rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
TMPDIR /mnt/storage/scratch/tmp/g3Lr
bus rc=1 ℹ tests 38 ℹ pass 33 ℹ fail 5 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
✖ failing tests:
✖ landRelease releases the holding run by land-relaunch once it has asked message.receive and nothing delivered to it is unread, and waiting messages go to the next holder (34.180349ms)
✖ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (33.321208ms)
✖ row 302 a run landRelease released answers launcher-released, and claims nothing again (36.389735ms)
✖ row 302 a run threadIdle released answers launcher-released on receive, state, read and send, logs each, and claims nothing again (39.497664ms)
✖ row 302 with a run launcher-released, a run that lost its claim another way still answers not-holder (39.379523ms)
17: AssertionError [ERR_ASSERTION]: runner: acme/assistant claimed by run ra10cf293beb6
21: + actual - expected
32: actual: 'session stopped working: not-holder',
33: expected: 'session released by the launcher',
15: AssertionError [ERR_ASSERTION]: runner: demo/coder claimed by run coder-run
35: actual: 22,
36: expected: 0,
pin red at threads.test.mjs:394:
pin red at land.test.mjs:464:
pin red at runner.test.mjs:771:
:772 pattern absent from stderr (old not-holder line present)
every red on f799e8b15561ea2c0f0735e5328ba149c7a1a7b5:
✖ a run in a landing turn isn't released for a second held decision until its landing turns end and it has read its messages (602.229598ms)
✖ failing tests:
✖ landRelease releases the holding run by land-relaunch once it has asked message.receive and nothing delivered to it is unread, and waiting messages go to the next holder (34.180349ms)
✖ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (33.321208ms)
✖ row 302 a run landRelease released answers launcher-released, and claims nothing again (36.389735ms)
✖ row 302 a run threadIdle released answers launcher-released on receive, state, read and send, logs each, and claims nothing again (39.497664ms)
✖ row 302 REQ-THREAD-2 an idle-released run whose call lands before the SIGTERM ends stopped/0; a run whose claim the human revoked in the same window still ends session-invalid/22 (1672.44448ms)
✖ row 302 with a run launcher-released, a run that lost its claim another way still answers not-holder (39.379523ms)
red stage: both forcing cases and the four pins red
wall 5 s
== 2. green on 649ec67abcd315ac877bbad65742017b998137e4
TMPDIR /mnt/storage/scratch/tmp/gaYE
idle-stop-race rc=0 ℹ tests 1 ℹ pass 1 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 1 s
TMPDIR /mnt/storage/scratch/tmp/g9t4
runner rc=0 ℹ tests 40 ℹ pass 40 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 12 s
TMPDIR /mnt/storage/scratch/tmp/gwAp
compactions-launch rc=0 ℹ tests 5 ℹ pass 5 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 15 s
TMPDIR /mnt/storage/scratch/tmp/gPAB
bus rc=1 ℹ tests 876 ℹ pass 875 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
RED: bus, stop at 2026-10-23T08:19:28Z, wall 57 s
430:✖ row 302 a run threadIdle released answers launcher-released on receive, state, read and send, logs each, and claims nothing again (81.984434ms)
931:✖ failing tests:
934:✖ row 302 a run threadIdle released answers launcher-released on receive, state, read and send, logs each, and claims nothing again (81.984434ms)
935: AssertionError [ERR_ASSERTION]: nothing delivered to the released run
exit 1
@@ -0,0 +1,187 @@
blobs: the five final test blobs (d5, launcher-released from d6) match in 5b63ea3236d82e14956594b41a00cbd7f7dc5f71 and 783602e06ed92f99c7c71d1e9c016a0f9e2c9b28
merge: 783602e06ed92f99c7c71d1e9c016a0f9e2c9b28 = 5b63ea3236d82e14956594b41a00cbd7f7dc5f71 onto 1ac655005e611157605a0dcc5adf7a37f9bca2b0; 12 row paths equal to 5b63ea3236d82e14956594b41a00cbd7f7dc5f71, none touched in 0e30a85fa..1ac655005e611157605a0dcc5adf7a37f9bca2b0
TIP 783602e06ed92f99c7c71d1e9c016a0f9e2c9b28 (merge) FIX 5b63ea3236d82e14956594b41a00cbd7f7dc5f71 RED f799e8b15561ea2c0f0735e5328ba149c7a1a7b5 base 0e30a85fa onto 1ac655005e611157605a0dcc5adf7a37f9bca2b0 origin/refactor 1ac655005e611157605a0dcc5adf7a37f9bca2b0 start 2026-10-23T08:23:41Z
loadavg: 1.49 1.75 1.94 4/6320 1592551
== 1. red first: f799e8b15561ea2c0f0735e5328ba149c7a1a7b5 product with the final test files from 5b63ea3236d82e14956594b41a00cbd7f7dc5f71 checked out on top
red tree: product of f799e8b15561ea2c0f0735e5328ba149c7a1a7b5, tests of 5b63ea3236d82e14956594b41a00cbd7f7dc5f71: packages/bus/tests/launcher-released.test.mjs
TMPDIR /mnt/storage/scratch/tmp/gHpj
idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
TMPDIR /mnt/storage/scratch/tmp/gIww
runner-land rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
TMPDIR /mnt/storage/scratch/tmp/g8I5
bus rc=1 ℹ tests 38 ℹ pass 33 ℹ fail 5 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
✖ failing tests:
✖ landRelease releases the holding run by land-relaunch once it has asked message.receive and nothing delivered to it is unread, and waiting messages go to the next holder (37.255433ms)
✖ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (30.900781ms)
✖ row 302 a run landRelease released answers launcher-released, and claims nothing again (36.454968ms)
✖ row 302 a run threadIdle released answers launcher-released on receive, state, read and send, logs each, and claims nothing again (40.167008ms)
✖ row 302 with a run launcher-released, a run that lost its claim another way still answers not-holder (38.485853ms)
17: AssertionError [ERR_ASSERTION]: runner: acme/assistant claimed by run r3f96e5142838
21: + actual - expected
32: actual: 'session stopped working: not-holder',
33: expected: 'session released by the launcher',
15: AssertionError [ERR_ASSERTION]: runner: demo/coder claimed by run coder-run
35: actual: 22,
36: expected: 0,
pin red at threads.test.mjs:394:
pin red at land.test.mjs:464:
pin red at runner.test.mjs:771:
:772 pattern absent from stderr (old not-holder line present)
every red on f799e8b15561ea2c0f0735e5328ba149c7a1a7b5:
✖ a run in a landing turn isn't released for a second held decision until its landing turns end and it has read its messages (604.606436ms)
✖ failing tests:
✖ landRelease releases the holding run by land-relaunch once it has asked message.receive and nothing delivered to it is unread, and waiting messages go to the next holder (37.255433ms)
✖ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (30.900781ms)
✖ row 302 a run landRelease released answers launcher-released, and claims nothing again (36.454968ms)
✖ row 302 a run threadIdle released answers launcher-released on receive, state, read and send, logs each, and claims nothing again (40.167008ms)
✖ row 302 REQ-THREAD-2 an idle-released run whose call lands before the SIGTERM ends stopped/0; a run whose claim the human revoked in the same window still ends session-invalid/22 (1604.296753ms)
✖ row 302 with a run launcher-released, a run that lost its claim another way still answers not-holder (38.485853ms)
red stage: both forcing cases and the four pins red
wall 4 s
== 2. green on 783602e06ed92f99c7c71d1e9c016a0f9e2c9b28
TMPDIR /mnt/storage/scratch/tmp/gMtc
idle-stop-race rc=0 ℹ tests 1 ℹ pass 1 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 2 s
TMPDIR /mnt/storage/scratch/tmp/gLSw
runner rc=0 ℹ tests 40 ℹ pass 40 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 12 s
TMPDIR /mnt/storage/scratch/tmp/gTQ3
compactions-launch rc=0 ℹ tests 5 ℹ pass 5 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 14 s
TMPDIR /mnt/storage/scratch/tmp/gAbg
bus rc=0 ℹ tests 876 ℹ pass 876 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 24 s
TMPDIR /mnt/storage/scratch/tmp/gzOd
harness rc=0 ℹ tests 151 ℹ pass 151 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 13 s
TMPDIR /mnt/storage/scratch/tmp/gxSF
cli rc=0 ℹ tests 918 ℹ pass 918 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
wall 615 s
TMPDIR /mnt/storage/scratch/tmp/gL7z
test-auth rc=0
selftest: 15 passed, 0 failed
wall 1 s
TMPDIR /mnt/storage/scratch/tmp/ghcv
test-conductor rc=0
selftest: 17 passed, 0 failed
wall 6 s
TMPDIR /mnt/storage/scratch/tmp/gCsn
test-config rc=0
selftest: 55 passed, 0 failed
wall 3 s
TMPDIR /mnt/storage/scratch/tmp/guh1
test-discord rc=0
discord suite: 81 passed, 0 failed
wall 7 s
TMPDIR /mnt/storage/scratch/tmp/gVDP
test-extension-package rc=0
extension package selftest: 18 passed, 0 failed
wall 1 s
TMPDIR /mnt/storage/scratch/tmp/g1V8
test-foundation rc=0
selftest: 44 passed, 0 failed
wall 38 s
TMPDIR /mnt/storage/scratch/tmp/gYsp
test-land-work rc=0
---
land-work selftests: 86 passed, 0 failed
wall 11 s
TMPDIR /mnt/storage/scratch/tmp/gucV
test-queue rc=0 ℹ tests 156 ℹ pass 156 ℹ fail 0
queue suite: 28 passed, 0 failed
wall 21 s
TMPDIR /mnt/storage/scratch/tmp/gGva
test-release rc=0
selftest: 14 passed, 0 failed
wall 3 s
TMPDIR /mnt/storage/scratch/tmp/g4vO
test-task rc=0
selftest: 91 passed, 0 failed
wall 16 s
after tests: clean
== skips
suite/test-queue.log:skip queue verify and render --check: this checkout (/mnt/storage/scratch/gizmo-302) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)
suite/test-task.log:skip live provider cases (row 244: no provider call in the gate)
suite/test-task.log:skip live provider cases (row 244: no provider call in the gate)
== 3. mutants
TMPDIR /mnt/storage/scratch/tmp/gDiY
M1.launcher-released rc=1 ℹ tests 3 ℹ pass 1 ℹ fail 2 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 a run threadIdle released answers launcher-released
TMPDIR /mnt/storage/scratch/tmp/glVj
M1.idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 REQ-THREAD-2 an idle-released run
M1 KILLED by rule
wall 2 s
TMPDIR /mnt/storage/scratch/tmp/grHO
M2.land rc=1 ℹ tests 18 ℹ pass 17 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: landRelease releases the holding run by land-relaunch
TMPDIR /mnt/storage/scratch/tmp/giID
M2.launcher-released rc=1 ℹ tests 3 ℹ pass 0 ℹ fail 3 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 a run threadIdle released answers launcher-released
killed: row 302 a run landRelease released answers launcher-released
TMPDIR /mnt/storage/scratch/tmp/gXTo
M2.idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 REQ-THREAD-2 an idle-released run
TMPDIR /mnt/storage/scratch/tmp/gTkJ
M2.runner rc=1 ℹ tests 40 ℹ pass 39 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: a run in a landing turn isn't released for a second held decision
M2 KILLED by rule
wall 15 s
TMPDIR /mnt/storage/scratch/tmp/ge9B
M3.idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 REQ-THREAD-2 an idle-released run
TMPDIR /mnt/storage/scratch/tmp/gYUi
M3.runner rc=1 ℹ tests 40 ℹ pass 39 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: a run in a landing turn isn't released for a second held decision
M3 KILLED by rule
wall 33 s
TMPDIR /mnt/storage/scratch/tmp/gw5X
M4.idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 REQ-THREAD-2 an idle-released run
TMPDIR /mnt/storage/scratch/tmp/g90Y
M4.runner rc=1 ℹ tests 40 ℹ pass 39 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: a run in a landing turn isn't released for a second held decision
M4 KILLED by rule
wall 14 s
TMPDIR /mnt/storage/scratch/tmp/gNlw
M5.launcher-released rc=1 ℹ tests 3 ℹ pass 1 ℹ fail 2 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 with a run launcher-released, a run that lost its claim
TMPDIR /mnt/storage/scratch/tmp/gCk7
M5.idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 REQ-THREAD-2 an idle-released run
M5 KILLED by rule
wall 2 s
TMPDIR /mnt/storage/scratch/tmp/gaHU
M7.launcher-released rc=1 ℹ tests 3 ℹ pass 1 ℹ fail 2 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 a run threadIdle released answers launcher-released
killed: row 302 a run landRelease released answers launcher-released
M7 KILLED by rule
wall 1 s
TMPDIR /mnt/storage/scratch/tmp/g3K9
M8.land rc=1 ℹ tests 18 ℹ pass 17 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: landRelease releases the holding run by land-relaunch
TMPDIR /mnt/storage/scratch/tmp/ge6z
M8.launcher-released rc=1 ℹ tests 3 ℹ pass 2 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 a run landRelease released answers launcher-released
TMPDIR /mnt/storage/scratch/tmp/gWPU
M8.runner rc=1 ℹ tests 40 ℹ pass 39 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: a run in a landing turn isn't released for a second held decision
M8 KILLED by rule
wall 13 s
TMPDIR /mnt/storage/scratch/tmp/gqwU
M9.idle-stop-race rc=1 ℹ tests 1 ℹ pass 0 ℹ fail 1 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0
killed: row 302 REQ-THREAD-2 an idle-released run
M9 KILLED by rule
wall 2 s
end 2026-10-23T08:38:14Z wall 873 s
node with cwd in the worktree: 0
exit 0
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
# Row 302 (#1809) mutants, from BUILD.md d3 and d4. Each replaces one exact string, once, in one file.
# Kill rule: every (test file, failing test name) listed fails in that file's run.
# mutants.py list | apply M | file M | kills M
import sys
BROKER = "packages/bus/src/broker.mjs"
RUNNER = "packages/harness/src/runner.mjs"
ADD = " this.#launcherReleased.add(key);\n"
IDLE = ("packages/cli/tests/idle-stop-race.test.mjs", "row 302 REQ-THREAD-2 an idle-released run")
LR1 = ("packages/bus/tests/launcher-released.test.mjs", "row 302 a run threadIdle released answers launcher-released")
LR2 = ("packages/bus/tests/launcher-released.test.mjs", "row 302 with a run launcher-released, a run that lost its claim")
LR3 = ("packages/bus/tests/launcher-released.test.mjs", "row 302 a run landRelease released answers launcher-released")
LAND = ("packages/bus/tests/land.test.mjs", "landRelease releases the holding run by land-relaunch")
RUN = ("packages/harness/tests/runner.test.mjs", "a run in a landing turn isn't released for a second held decision")
M = {
"M1": (BROKER, "this.#claimEnd(session, this.#own(session), 'release', null));\n" + ADD,
"this.#claimEnd(session, this.#own(session), 'release', null));\n", [IDLE, LR1]),
"M2": (BROKER, "fail(this.#launcherReleased.has(s.business + ':' + s.run) ? 'launcher-released' : 'not-holder');",
"fail('not-holder');", [IDLE, LR1, LR3, LAND, RUN]),
"M3": (RUNNER, " if (err.code === LAUNCHER_RELEASED) {", " if (false) {", [IDLE, RUN]),
"M4": (RUNNER, " released = true;\n return true;", " released = true;\n code = EXIT.session;\n return true;", [IDLE, RUN]),
"M5": (BROKER, "? 'launcher-released' : 'not-holder')", "? 'launcher-released' : 'launcher-released')", [IDLE, LR2]),
"M7": (BROKER, " if (this.#launcherReleased.has(s.business + ':' + s.run)) fail('launcher-released');\n", "", [LR1, LR3]),
"M8": (BROKER, "'land-relaunch'));\n" + ADD, "'land-relaunch'));\n", [LR3, LAND, RUN]),
"M9": (RUNNER, "if (code === EXIT.stopped && !released) {", "if (code === EXIT.stopped) {", [IDLE]),
}
cmd = sys.argv[1]
if cmd == "list":
print(" ".join(M))
elif cmd == "file":
print(M[sys.argv[2]][0])
elif cmd == "kills":
for f, name in M[sys.argv[2]][3]:
print(f + "\t" + name)
elif cmd == "apply":
path, old, new, _ = M[sys.argv[2]]
s = open(path).read()
if s.count(old) != 1:
sys.exit(f"{sys.argv[2]}: anchor found {s.count(old)} times in {path}")
open(path, "w").write(s.replace(old, new))
print(path)
else:
sys.exit("usage: mutants.py list|apply M|file M|kills M")
@@ -0,0 +1,147 @@
#!/bin/bash
# Row 302 (#1809, Vikunja 588) gate. Plan: agents/gizmoduck/work/queue-302/BUILD.md d3 "Run plan", d4, d5.
# 0. Preflight: worktree at TIP and clean, the five test blobs from d5. TIP is the local merge of 64f6558ee
# onto origin/refactor 1ac655005 (sage-3289); the 12 row paths are unchanged in BASE..1ac655005.
# 1. Red (mos-1415): f799e8b15 (final tests, unfixed product). idle-stop-race and the runner.test land case
# must fail. The bus files are run and recorded. A green forcing case here is a STOP.
# 2. On TIP: idle-stop-race alone 600 s, runner.test whole 900 s, compactions-launch whole 600 s,
# bus 1200 s, harness 1200 s, cli 2100 s, then the scripts/test-*.sh at 900 s each.
# 3. M1-M5, M7, M8, M9 (mutants.py). Each kill-listed file runs whole; every listed test name must fail.
# After each: git checkout, sha256 equal to the candidate's, tree clean. A survivor is a STOP to Sage.
# mos-1272: a first-run red in a new test is placed and reported after; any other red stops the run.
set -o pipefail
WT=/mnt/storage/scratch/gizmo-302
# Run 2 (BUILD d6): FIX is the d6 tip; TIP is a fresh merge of it onto ONTO, set when the run is cleared.
TIP=${TIP:?set TIP to the run-2 merge sha}
FIX=5b63ea3236d82e14956594b41a00cbd7f7dc5f71
ONTO=${ONTO:?set ONTO to origin/refactor at the merge}
BR=gizmoduck/row302-gate
RED=f799e8b15561ea2c0f0735e5328ba149c7a1a7b5
BASE=0e30a85fa
OUT=/mnt/storage/scratch/gizmo-302-out/gate
PY=/mnt/storage/scratch/gizmo-302-out/mutants.py
cd "$WT" || exit 9
[ "$(git rev-parse HEAD)" = "$TIP" ] || { echo "not on the gate commit"; exit 9; }
[ -z "$(git status --porcelain --untracked-files=no)" ] || { echo "dirty"; exit 9; }
TESTS=""
while read -r blob f; do
[ "$(git rev-parse "$TIP:$f")" = "$blob" ] && [ "$(git rev-parse "$FIX:$f")" = "$blob" ] || { echo "blob mismatch $f"; exit 9; }
TESTS="$TESTS $f"
done <<'EOF'
52343932b231691ba2b4fc117547ea7f6f504704 packages/bus/tests/land.test.mjs
6fb6e15c2fd34f742f9aab718ff654ab2704e198 packages/bus/tests/launcher-released.test.mjs
27193a745c4ed8d4936de96c1768ab010a572856 packages/bus/tests/threads.test.mjs
9dfacfea15a487c4e7056ebae3e311cb514b0467 packages/cli/tests/idle-stop-race.test.mjs
0792431b60314a17ed74b3df0c5b3748dc3c1286 packages/harness/tests/runner.test.mjs
EOF
echo "blobs: the five final test blobs (d5, launcher-released from d6) match in $FIX and $TIP"
[ -L node_modules ] || ln -s /mnt/storage/src/mosaic-stack/node_modules node_modules
[ -L node_modules ] || { echo "no node_modules link"; exit 8; }
[ "$(git rev-parse $TIP^1) $(git rev-parse $TIP^2)" = "$ONTO $FIX" ] || { echo "merge parents wrong"; exit 9; }
paths=$(git diff --name-only $BASE $FIX)
[ "$(echo "$paths" | wc -l)" -eq 12 ] || { echo "row paths not 12"; exit 9; }
over=$(git diff --name-only $BASE $ONTO -- $paths)
[ -z "$over" ] || { echo "BASE..ONTO touches row paths:"; echo "$over"; exit 9; }
git diff --quiet $FIX $TIP -- $paths || { echo "merge changed a row path"; exit 9; }
echo "merge: $TIP = $FIX onto $ONTO; 12 row paths equal to $FIX, none touched in $BASE..$ONTO"
[ -e "$OUT" ] && { echo "$OUT exists; move it first"; exit 9; }
mkdir -p "$OUT/red" "$OUT/suite" "$OUT/mut"
newtmp() { export TMPDIR=$(mktemp -d /mnt/storage/scratch/tmp/gXXX); echo " TMPDIR $TMPDIR"; }
echo "TIP $TIP (merge) FIX $FIX RED $RED base $BASE onto $ONTO origin/refactor $(git rev-parse origin/refactor) start $(date -u +%FT%TZ)"; echo "loadavg: $(cat /proc/loadavg)"
T0=$SECONDS; t0=$SECONDS; lap() { echo " wall $((SECONDS - t0)) s"; t0=$SECONDS; }
counts() { grep -E '^ℹ (tests|pass|fail|cancelled|skipped|todo) ' "$1" | tr '\n' ' '; echo; }
timed() { # log dir limit args... ; sets rc
local log=$1 dir=$2 lim=$3; shift 3
newtmp
(cd "$dir" && timeout -k 10 "$lim" "$@") > "$log" 2>&1
rc=$?
if [ $rc -eq 124 ] || [ $rc -eq 137 ]; then
echo "TIMEOUT after $lim s: $(basename "$log" .log). To Sage."
case $(basename "$log") in test-*.log) echo "SHELL-PHASE TIMEOUT (mos-1275): to Mos unplaced";; esac
fi
echo "$(basename "$log" .log) rc=$rc $(counts "$log")"
}
green() { # log dir limit args... ; any red stops
timed "$@"
if [ $rc -ne 0 ]; then
echo "RED: $(basename "$1" .log), stop at $(date -u +%FT%TZ), wall $((SECONDS - T0)) s"
grep -nE '^not ok|✖|AssertionError|Error:' "$1" | head -40
exit 1
fi
}
echo "== 1. red first: $RED product with the final test files from $FIX checked out on top"
git checkout -q --detach "$RED" || exit 9
git checkout -q "$FIX" -- $TESTS || exit 9
while read -r f; do [ "$(git hash-object "$f")" = "$(git rev-parse "$FIX:$f")" ] || { echo "red tree blob wrong $f"; exit 9; }; done < <(echo $TESTS | tr ' ' '\n')
[ -z "$(git diff --name-only HEAD -- 'packages/*/src/*')" ] || exit 9
echo " red tree: product of $RED, tests of $FIX: $(git diff --cached --name-only HEAD | tr '\n' ' ')"
[ -z "$(git diff --name-only $BASE HEAD -- 'packages/*/src/*')" ] || { echo "red commit changes product files"; git checkout -q $BR; exit 9; }
timed "$OUT/red/idle-stop-race.log" "$WT/packages/cli" 600 node --test tests/idle-stop-race.test.mjs; r1=$rc
timed "$OUT/red/runner-land.log" "$WT/packages/harness" 600 node --test --test-name-pattern="^a run in a landing turn isn't released for a second held decision" tests/runner.test.mjs; r2=$rc
timed "$OUT/red/bus.log" "$WT/packages/bus" 600 node --test tests/launcher-released.test.mjs tests/threads.test.mjs tests/land.test.mjs
grep -E '✖ ' "$OUT/red/bus.log" | sort -u | sed 's/^/ /' | head -20
git reset -q --hard "$RED" && git checkout -q $BR || exit 9
[ "$(git rev-parse HEAD)" = "$TIP" ] && [ -z "$(git status --porcelain --untracked-files=no)" ] || { echo "not back on TIP clean"; exit 9; }
red_ok=1
[ $r1 -ne 0 ] && grep -qF "✖ row 302 REQ-THREAD-2 an idle-released run" "$OUT/red/idle-stop-race.log" || { echo " idle-stop-race NOT red on $RED"; red_ok=0; }
[ $r2 -ne 0 ] && grep -qF "✖ a run in a landing turn isn't released for a second held decision" "$OUT/red/runner-land.log" || { echo " runner.test land case NOT red on $RED"; red_ok=0; }
grep -nE 'AssertionError|actual|expected' "$OUT/red/idle-stop-race.log" | head -12 | sed 's/^/ /'
grep -nE 'AssertionError|actual|expected' "$OUT/red/runner-land.log" | head -8 | sed 's/^/ /'
# The four ruled pins (mos-1414/1415/1416). :772 sits after :771 in one test, so :771 stops it first;
# :771's message is out.stderr, so the log shows the old "stopped working: not-holder" line and no
# "released by the launcher" line, which is the line :772 now pins.
grep -qF "✖ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting" "$OUT/red/bus.log" || { echo " threads.test threadIdle case NOT red"; red_ok=0; }
grep -qF "✖ landRelease releases the holding run by land-relaunch" "$OUT/red/bus.log" || { echo " land.test landRelease case NOT red"; red_ok=0; }
for pin in "threads.test.mjs:394:" "land.test.mjs:464:"; do
grep -qF "$pin" "$OUT/red/bus.log" && echo " pin red at $pin" || { echo " pin $pin not in the failure stacks"; red_ok=0; }
done
grep -qF "runner.test.mjs:771:" "$OUT/red/runner-land.log" && echo " pin red at runner.test.mjs:771:" || { echo " pin runner.test.mjs:771 not in the failure stack"; red_ok=0; }
grep -qF "session stopped working: not-holder" "$OUT/red/runner-land.log" && ! grep -qF "session released by the launcher" "$OUT/red/runner-land.log" \
&& echo " :772 pattern absent from stderr (old not-holder line present)" || { echo " :772 evidence missing"; red_ok=0; }
echo " every red on $RED:"; cat "$OUT"/red/*.log | grep -E '^✖ |^ ✖ |✖ ' | sed 's/^ *//' | sort -u | sed 's/^/ /'
[ $red_ok -eq 1 ] && echo " red stage: both forcing cases and the four pins red" || { echo "STOP: red stage failed, to Sage"; exit 3; }
lap
echo "== 2. green on $TIP"
green "$OUT/suite/idle-stop-race.log" "$WT/packages/cli" 600 node --test tests/idle-stop-race.test.mjs; lap
green "$OUT/suite/runner.log" "$WT/packages/harness" 900 node --test tests/runner.test.mjs; lap
green "$OUT/suite/compactions-launch.log" "$WT/packages/cli" 600 node --test tests/compactions-launch.test.mjs; lap
green "$OUT/suite/bus.log" "$WT/packages/bus" 1200 node --test tests/*.test.mjs; lap
green "$OUT/suite/harness.log" "$WT/packages/harness" 1200 node --test tests/*.test.mjs; lap
green "$OUT/suite/cli.log" "$WT/packages/cli" 2100 node --test tests/*.test.mjs; lap
for s in "$WT"/scripts/test-*.sh; do
n=$(basename "$s" .sh)
green "$OUT/suite/$n.log" "$WT" 900 bash "$s"
tail -2 "$OUT/suite/$n.log" | sed 's/^/ /'; lap
done
[ -z "$(git status --porcelain --untracked-files=no)" ] && echo "after tests: clean" || { echo "after tests: DIRTY"; exit 1; }
echo "== skips"
grep -HE '^ℹ skipped [1-9]|^ℹ todo [1-9]' "$OUT"/suite/*.log | sed "s#$OUT/##"
grep -HiE '^(skip|# skip|SKIP)|skipped' "$OUT"/suite/test-*.log | grep -v '^ℹ' | sed "s#$OUT/##" | head -40
echo "== 3. mutants"
limit() { case $1 in *cli/*) echo 600;; *runner.test*) echo 900;; *) echo 600;; esac; }
for m in $(python3 -B "$PY" list); do
src=$(python3 -B "$PY" file "$m")
sum=$(git show "HEAD:$src" | sha256sum | cut -c1-64)
python3 -B "$PY" apply "$m" >/dev/null || { echo "$m apply-failed"; git checkout -- "$src"; exit 8; }
git diff > "$OUT/mut/$m.diff"
ok=1
for f in $(python3 -B "$PY" kills "$m" | cut -f1 | sort -u); do
pkg=${f%%/tests/*}; rel=tests/${f#*/tests/}
log="$OUT/mut/$m.$(basename "$f" .test.mjs).log"
timed "$log" "$WT/$pkg" "$(limit "$f")" node --test "$rel"
[ $rc -ne 0 ] || { echo " $m survived in $f"; ok=0; }
while IFS=$'\t' read -r kf name; do
[ "$kf" = "$f" ] || continue
grep -qF "✖ $name" "$log" && echo " killed: $name" || { echo " NOT failing: $name"; ok=0; }
done < <(python3 -B "$PY" kills "$m")
done
git checkout -- "$src"
[ "$(sha256sum "$WT/$src" | cut -c1-64)" = "$sum" ] && [ -z "$(git status --porcelain --untracked-files=no)" ] || { echo "$m restore-failed"; exit 7; }
if [ $ok -eq 1 ]; then echo "$m KILLED by rule"; else echo "STOP: $m kill rule not met, to Sage"; exit 4; fi
lap
done
echo "end $(date -u +%FT%TZ) wall $((SECONDS - T0)) s"
cd /; echo "node with cwd in the worktree: $(for p in $(pgrep -x node); do readlink /proc/$p/cwd; done 2>/dev/null | grep -c "$WT")"