Compare commits

..
465 changed files with 650 additions and 101728 deletions

No files matched your search

-29
View File
@@ -5382,32 +5382,3 @@ Gander: after Duckworth-0100 design approval with C1-C5, prepared the two host-s
2026-10-23T02:21:06Z | Sage, rows 270+271 landing, 571 landing, MVP rows | Before: 270 (#1775) and 271 (#1776) were approved on gizmoduck/row270-271-r4 49cee846e and 2b964a082 after combined gate C2 run 5 GREEN on 53406f3e4 (bus 873, seat 202, cli 905, ten scripts, 38/38 mutants). After: 33 commits cherry-picked onto 767bb62c7 as 7328da8ca, range-diff all "=", 40 paths identical to the candidate; 270 manifest f4174458 matches, 271 manifest 3ab1f5c8 matches on 29 paths, the other 4 moved under 270 and match its manifest. Done revs 3396/3398, #1775 c30962 and #1776 c30964 closed, P19 463 c861. 571 (Gyro, Fenton APPROVE) picked as ee5f7b9ef, 6345aae3d, 767bb62c7 (blobs 9382f85b, 7ec0897b), 1ac76a417 left out; N7 911dad2aa (Fenton-0014) picked after. Rows 293-299 added (574, FED R6, R4, R7, GitHub grant, Q228, 573), queue commit 253346e3c. Correction: the push sync step checked out O..S paths over the canonical worktree without testing for uncommitted edits, so any pending SESSIONS or BUILD-LOG line in the canonical checkout at 02:06Z would have been overwritten; the sync now skips edited paths. Schema 3n is not live (LIVE 0cbe2e9b3 at 3m).
2026-10-23T03:59:52Z | Sage, row 293 (Vikunja 574) landing and 3m-3n live window | Before: live 0cbe2e9b3 at schema 3m; 574 approved by Filbert (c30982, cdda41f5) on gander/v574-r2 a9cae2bd6 after run 2 GREEN on 6bfab273b (four files 153/0, seat 202/0, cli 905/0, 312 flagged commits with 0 maintenance children). After: Darkwing's window put live on 464010fbe at 3n (activation 20261023T034557Z-464010fbe4c6, 26/97/5/28, Console 7332 200, W9b pm ra38826f3c6e2 left live, STATE darkwing/window-migrate-3n 8708927e5); 574's six commits cherry-picked onto 464010fbe as e51d11640, range-diff all =, patch-ids equal, only docs differ from a9cae2bd6. #1805 closed c31013, P19 386 c887 and 574 c888. Residual: queue store.mjs, discord git.mjs, harness tools.mjs commit without the maintenance flags; no whole-root test covers them yet.
2026-10-23T05:47:17Z | Sage, row 292 (#1797) landing, idle-stop race row 302, rows 300/301, row 294 rounds 2-3 | Before: refactor 4a9c536e8; 292's gate on 0d0021454 hit one red at compactions-launch.test.mjs:229, ['session-invalid',22,null] where ['stopped',0,null] was expected, product and test unchanged. Gizmoduck read it as a race: threadIdle releases the claim, then the launcher sends SIGTERM, and a runner call in between gets not-holder and exits 22. Mos (mos-1411) rejected loosening :229, let 292 count one whole unedited green cli rerun, and allowed one rerun for that exact signature on other gates until the race row lands (hits logged on Vikunja 588). The 10-run diagnostic passed 10/10, but one runner log (r846b8d083502) showed not-holder then exit 22. After: the cli rerun was 910/910. 292 LANDED 6aab979e6 05:18Z (7 cherry-picks, range-diff all =, patch-ids equal), done rev 3447, #1797 closed c31038, Vikunja 588 c891. Briefs 86d5ac69b (R6-N1 #1807, R6-N4 #1808, rows 300/301) and e3ef1eaf6/fdedc56e2 (race, #1809, row 302). Row 302 design d1/d2 approved by Dewey with D1 (role.claim refuses a released run), c31044. Mos ruled landRelease folded in, code launcher-released, and four old-test lines moved to exact values (mos-1414/1415/1416): threads.test:394, runner.test:771-772, land.test:464. Row 294 round 2 stopped at webui G5 granted-user.test:269: max(seq) over an empty events table is NULL. Round 3 is one line, coalesce(max(seq),0) (mos-1417), Duckworth APPROVE c31045 rev 3462, gate pending. Queue commit 756284e8e (revs 3448-3456). Correction: two review-request attempts this window ran without MOSAIC_GITEA_CREDENTIAL_FILE exported and failed (3450 Launchpad, 3451/3452 Sage); the posted request was 3453/3454.
2026-10-23T07:11:43Z | Sage, row 294 (#1800) rounds 3-4 and landing, row 219 edits 2-3, R9 transient and row 303 | Before: refactor 09d0d6faf; 294 run 3 on cb1648f3 stopped with 20 cli reds from two causes. A: the stack-release rehearsal fixture copies lacked cli access.mjs and transport.mjs, which 294's config.mjs now imports. B: the B1-B3 boot tests read warnings that now carry the fixture tracker line. Mos ruled A as two copy-list entries and B as a full pin, no filter: a TRACKER const and deepEqual (mos-1419). After: round 4 8616b9a4f, manifest a1ff5d67, Duckworth APPROVE c31053 rev 3469 with C1/C2. Run 4 from npm ci green: webui 365, cli 909, bus 873, 10 scripts, M1-M11 killed. Merged tree d3059c2c3 (11 cherry-picks, range-diff all =, patch-id 8371405a equal): stack-release-external 25/25, stack-upgrade 21/21. stack-release 223/224 on the first run, R9 at :2178: TypeError on join(r.dir) with r.dir null, so rehearse stopped before its directory and the output was lost. R9 passed 6/6 run alone on d3059c2c3, 09d0d6faf and 24b745447. Mos (mos-1422) allowed one unedited whole rerun: 224/224. 294 LANDED d3059c2c3 07:04Z, done rev 3471, #1800 closed c31068, P19 269 c895. Row 303 (#1810, Vikunja 589, brief ad6ca7930) adds an r.dir guard in R9 only. Queue commit 80793d824 (revs 3464-3473). Row 219: Rocko's second edit 7cbd839d0 (mos-1418, Dewey dewey-0883) restarted and went red at thread-launch C2-09a :489 on a legacy history path. The third edit 5f2ef92e5 (mos-1420, Dewey dewey-0885) reads the native session path. 219 now rebases onto 80793d824, because 294 overlaps its webui files. Correction: the first merged-tree check counted on the 292 drift and found an unrelated transient, and my P19 placeholder sed also rewrote the script's own guard line; the guard refused to post, and I restored the line before posting.
Row 299 (573, #1806, Gander, Filbert): before, the P10 band test timed a fault run minus a separate baseline run, and a loaded whole-suite run went red. Mos approved direct timing from host /proc/uptime stamps with ambient load only (mos-1409). After: rebased onto 80793d824 as ffa93b054 (range-diff 3/3 =, manifest 277ace0b unchanged). Gate 07:26Z-07:50Z: case1 whole 3x 53/0/0, cli whole 917/0/0 (59 files, load 1.54-7.17), P10 inner 2.27 s, outer 4.01 s, M1-M6 killed. M4's planned guard return then exact outer-reason failure counts as its kill (sage-3271, mos-1426). Filbert APPROVE c31084 rev 3485, N1 M1 margin 0.02 s. 299 LANDED ffb2fedfb 08:03Z, done rev 3487, #1806 closed c31087; queue commit 8a35ffadb (revs 3474-3487). Row 303: Duckworth APPROVE c31079 rev 3480 with C1, the whole-file gate. Rows 219 (bfa421b6c) and 295 r2 (b16cef1d0) rebases: Dewey static clean. Corrections: Launchpad and Gander have no token, and the CLI refuses another seat's token file, so I posted both requests as sage (c31082, c31083). My sage-3265 wording led Duckworth to poll queue show into Gander's slot (07:20Z-07:26Z); I ruled it ambient load (sage-3274).
2026-10-23T10:48:40Z | Sage, rows 302, 295 and 219 landings, the Docker pool diagnostic, rows for Vikunja 590 and 591 | Before: refactor 1ac655005. 302 (#1809, Gizmoduck, Dewey) LANDED 3ed9fd754 08:49Z: 7 commits onto 1ac655005, range-diff all =, tree = gated merge 783602e06; queue commit 07802dc57 (revs 3488-3494). Row 219's gate went 11/3 in test-release.sh: release activate's health check failed because Docker could not create sage-diag1437_default, since all predefined address pools were used up. Under mos-1437 I reproduced it on clean 07802dc57 (11/3, the same stderr). I then removed 18 unused gate _default networks, and the rerun went 14/0 with the run-task marker ok. Mos accepted the removal and ruled that a probe that can create something waits for the go and a removal waits for the report (mos-1438). 295 (#1801, Morgana, Dewey) round 2 gate on d68b4300d (manifest e94c9aeb) was green. It LANDED 2efd127ce 10:10Z: 9 commits onto 07802dc57, HEAD~1 tree = gated a86592ffc. Done rev 3502, #1801 c31105, P19 414 c911. 219 (#1720, Rocko, Dewey): the restart on the post-295 merge 054da642f (manifest 4a2271dd, my mos-1439 call) passed node 2523/0/2 and shells 449/0, with 24 mutants killed. It LANDED 5fdfd7275 10:40Z (8 row commits plus packet-only evidence, tree e86a84a85 = gated). Done rev 3509, #1720 c31110, P19 416 c913. Queue commit 90633c864 (revs 3495-3510). Brief docs/plans/2026-10-23_gate-env-rows.md names rows for 590 (claude-session slug) and 591 (compose network cleanup), and DEFERRED.md gets 219 N1 (U6). Row 272 (Huey) conflicts with 5fdfd7275 in code, so it moves back to in-progress for a rebase. Its new fallback is bounded to a session.list access-refused on an omitted-session route (sage-3357). Corrections: my network create probe ran before Mos's go, and the removal ran before the report. My first slot-order line put the diag start at 09:44Z; it was about 09:41Z. My 219 push piped its output through grep, but the after-fetch confirmed origin. Queue commit 90633c864 also carries Huey's rev 3510 (272 back to in-progress), and its message names only 3495-3509.
2026-10-23T11:03:46Z | Gyro Vikunja571 mos-1444 PRD d8 follow-on | Branch gyro/editor-571-d8 from origin/refactor c16e943b9. Both designs now keep library.convert outside ACTIONS/ROUTED and broker processing, retain REQ-WAIT-1/hard-wait test unchanged, constrain unmarked story eligibility to mapped book/playground scope, and add whole-host pre-import restore recovery from remote import manifests plus the Gitea archive commit. Lookups refuse until one current version is proven; VM1012 restore needs Jason present under Q185. W7 no longer owns hard-waits.test.mjs. Canonical queue next gyro returned nothing; direct Mos assignment governs. Static diff, exact replacement and append-only checks pass. No code, tests, build, browser, private-file or live action. Fenton re-check requested after authorized branch push.
2026-10-22 | Huey | Row 272 / 264e (#1777) preparation on huey/row272, base 2d0d407ba. Before: bus session metadata and launcher isolation exist, CLI/Console expose only the saved thread default. Draft: session CLI, Console chooser with isolated drafts/cursors/receipts, metadata counts and safe-clear operation receipts against Gizmoduck's 0260 contracts; narrow deferred B6 reply fence. Tests authored, not run: Gander row 253 holds Sage's slot; no Node, claim, HTTPS git, push or live changes. This entry records preparation after the first draft, not a green acceptance result.
2026-10-22 | Huey | Row 272 draft, 264d additive contract gizmoduck-0272 (78e14352f). Added confirmed cancellation through the human channel, cancelled receipt retirement distinction, named refusals and routed-message cancellation output. Before: cancelled was not recognized as terminal; after: draft CLI stops polling and Console shows the before/after retirement outcome. Acceptance remains unverified: no Node/tests/claim/commit/push under Sage's gate. No runtime/lifecycle authority expanded.
2026-10-23 | Huey | Row 272 / 264e sage-3141 local rebase. Before: uncommitted draft on 2d0d407ba. After: same draft on new huey/row272-b23783f39 at b23783f39, with 270/271 landed (7328da8ca) and schema 3n. Product changes auto-merged; both append-only logs retain the full new base and original Huey additions. Checked landed session.list and clear/cancel/operation envelopes against the wired draft: no incompatible contract change. Historical unavailable-dependency cases stay as stand-ins; actual base supplies counters and lifecycle state. No tests/Node/claim/commit/push while Gander holds row 574 run 2. Existing-test fixture/assertion delta is named in the packet for Mos's ruling via Sage before execution.
2026-10-23 | Huey | Row 272 sage-3145 preservation correction. refs/stash is shared, so it was unsafe as sole draft storage. Pinned exact stash commit 07dc9d2f7944b4781b5e80dfa18425f4749f7a45 to local huey/row272-stash-keep and left the entry untouched. Sage explicitly directed committing the rebased draft before testing to preserve it: an untested local checkpoint, no acceptance claim. No Node/test/queue/network/live action. Separate claims and test CLEARs remain pending; old-test delta is with Mos via sage-3144.
2026-10-23 | Huey | Row 272 early static review follow-up, scrooge-272-early-read-huey-1. Before: a bad-session 404 erased sibling draft/recovery caches, malformed clear/cancel write receipts omitted the audit line, and another session's op key produced an ambiguous error. Draft after: purge only on named thread-level refusals, write one redacted malformed-receipt audit line, and identify key reuse without a write. New browser/HTTP/CLI tests authored, unrun under test hold; approved old-test hunks unchanged. Published 850b22680/round-1 manifest unchanged; follow-up is uncommitted, no acceptance claim.
2026-10-23 | Huey | Row 272 round 2 on row 219 landing 5fdfd7275, after 295. Replayed round 1 and B1/N1/N2; seven conflicts resolved retaining both log histories, both test sets, 219 instance chooser and 295 owner-settings-only transport. Static comparison confirms old tests differ only by mos-1388 approved hunks. Sage3357/Mos1442 authorize bounded granted-user legacy fallback: only session.list access-refused and omitted-session route; no new session grants or owner routing. RED first under3358 on new file only: 1 expected legacy assertion failure, 3 guards pass, 3.504s, TMPDIR mktemp/no underscore, no compose network; slot returned as huey0035. Then implemented fallback and added timeout/bus/malformed guards plus isolated-copy mutant runner, all unrun afterward. Candidate commit/push precedes Sage's full gate by3354; no green claim.
2026-10-23 | Huey | Row 272 round 3 per mos-1455 / sage-3435. Gate run 1 on b44332a93 RED: bus 891/0, business 231/0, CLI 940/1, plugins 110/1, webui 372/20; no mutants. Fixed only new CLI fixture role authority and three null-old render guards. Catching browser tests unchanged. manifest.r3 freezes the same 17 paths. Authorized pre-gate follow-up commit/push; no local tests, Node or queue writes; separate compactions dependency and Sage gate remain pending.
2026-10-23 | Sage (1ef1e4f8) | Row 272 landing (#1777, 264e) | Gate r4 on bea0c8e1c over 1e629c892: bus 891/0, cli 941/0, webui 392/0, business 231/0; plugins 110/1, the single red being row 65 harness.test.mjs:192 naming compactions.mjs, which row 307 owned and fixed. M1-M6 and F1-F4 killed, restore clean. Landed d33989230, queue commit 8dc132bec.
2026-10-23 | Sage (1ef1e4f8) | Row 307 landing (#1814, Vikunja 598) | Six first-parent commits replayed onto 8dc132bec with matching patch-ids, 16 paths equal to 6fdfe3790, manifest digest 17c9f8d9 rebuilt from git. Gate green 14:37:21Z: bus 891/0, cli 941/0, plugins 119/0, webui 392/0, business 231/0, every other package 0 failed 0 skipped, every scripts/test-*.sh passed (skips: test-queue canonical root, test-task live provider x2). M1-M4 killed, restore clean. Landed d243f6b25, DEFERRED 307 N1 0621c439e, queue commit fe4ee8c7b. Correction: my first note said Vikunja 598 done when I had only commented (951); Mos closed it (952).
2026-10-23T17:29:46Z | Gyro Vikunja571 sage-3542 Connections amendment | Branch gyro/editor-connections-design cut exactly from landed PRD1.17 30e6bb680; read REQ-LIB-5 in that PRD. Replaced stale J-b waits in parent and W4. Proposed W8 owns current authorized Markdown/DOCX links/backlinks list, labels, versioned refresh, leakage refusals and fixture tests. Build order under mos-1470/comment961 is W7 closed routing candidate, W8 landing, then W7 human first-real-import opening. No REQ-LIB-8 condition or acceptance change. Q234/mos-1363/S0 M1-M14 and post-10-27/MVP priority fixed. Static diff, twelve brief sections and append-only checks pass. No repo Node, tests, build, browser, queue mutation or live action. Fenton reviews after authorized docs branch push; Sage lands on approval.
2026-10-23T17:32:37Z | Gyro sage-3544 fenton-0016 N1/N2 delta | Before: W7 Gate/final real-conversion list omit the W8 build-order cross-reference and W8 human-view filtering cites agent settings. After: both locations explicitly put W8 landing before human opening as mos-1470 build order, not acceptance; comment/tracked-deletion links are not current story links and never appear in the human Connections view regardless of agent settings. New commit atop approved 5af060fb5, no amend. Static diff and append-only checks pass. Docs only, no repo Node/tests/live action. Fenton checks only this delta.
-8
View File
@@ -47,14 +47,6 @@ its launch configuration remains fixed, including on resume. Use Filbert's
wrapper to select that configuration; a direct shared-helper invocation uses
its own supplied flags or the system defaults.
Any run that includes the webui suite, whether a seat's slot run or a landing
gate, sets `MOSAIC_REQUIRE_EDITOR_BUILD=1`, so a missing editor toolchain fails
the run instead of skipping the rebuild test. A worktree that links the
canonical `node_modules` also runs `npm ci --ignore-scripts --no-audit --no-fund`
in its own `packages/webui` first. The root install carries esbuild 0.28.1
through pi-coding-agent, and the rebuild needs the 0.28.2 that
`packages/webui/package-lock.json` pins (Vikunja 597, mos-1453).
All agents follow repository governance and current user direction. Team
leadership does not add deployment or push authority. Coordinate overlapping
work with Sage and preserve other sessions' changes.
-6
View File
@@ -90,9 +90,3 @@ M1-M6 have one target each in their defined scope. M5 now suppresses only the be
Rebased all three commits from 4a9c536e8 onto 80793d824 under new branch gander/row299-8079, preserving gander/row299-p10. No conflict. The range-diff has three equal pairs and all per-commit stable patch-ids match. Source is e6751ecab; both manifest blobs equal the approved 1ec2b9765 blobs, so digest 277ace0b is unchanged. Direct test/helper, product case1 script, shared CLI helper and sudo-fixture paths have zero drift over 4a9c536e8..80793d824. Row294's CLI config/access and stack-release-test changes are in the new base and covered by the required full CLI suite. No package/source/test implementation changed in this integration. Full records in integration-8079/.
Gate remains held for CLEAR. Ambient load >=4 remains a target, not a wait condition under mos-1409; no stress process. Record each of three whole case1 starts and the whole CLI suite's load and per-mode direct timings. Numeric windows and the 7 s guard remain fixed. Any red, guard intervention, timeout, survivor or overshoot stops to Sage for Mos before edits or retry.
## Gate run 1: sage-3268, 2026-10-23
GREEN on ffa93b054 / 277ace0b. Three whole case1 runs 53/0/0 each; whole CLI 917/0/0 across 59 files. Total 1076/0/0, no cancelled/todo. M1-M6 all killed at their intended assertions, with byte-identical clean restores. No unmutated guard intervention, external timeout, retry or carry. UTC run 07:26:52–07:50:16 (1404 s). CLI load reached 7.17; direct CLI intervals inner exec/hop 2.27/2.27, outer exec/hop 4.01/4.01.
M4 follows sage-3273 / mos-1426: the 7 s fixture guard returned, then exact outer-reason assertion at case1-accept.test.mjs:445 failed on probe-inner-command. No timeout or cleanup-only kill. M1 measured 1.23 s, preserving the noted narrow kill margin. Sweep found zero gate residuals; four MCP harness processes predate this run. Full records, load samples, assertion locations and named base evidence are in run1/RESULTS.md and run1/results.json. Manifest remains unchanged.
@@ -1 +0,0 @@
CLEAR
@@ -1,18 +0,0 @@
{
"label": "M1-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gh8s2Og",
"started_utc": "2026-10-23T07:49:28Z",
"start_load": "1.51 2.50 2.68 3/5810 1153451",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M1-syntax.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:49:28Z",
"load": "1.51 2.50 2.68 2/5811 1153452"
}
]
Whitespace-only changes.
@@ -1 +0,0 @@
CLEAR
@@ -1,21 +0,0 @@
{
"label": "M1",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 inner reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gxjj9Vd",
"started_utc": "2026-10-23T07:49:30Z",
"start_load": "1.51 2.50 2.68 1/5816 1156782",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M1.log",
"expected_red": true
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:49:30Z",
"load": "1.51 2.50 2.68 3/5817 1156783"
}
]
-29
View File
@@ -1,29 +0,0 @@
TAP version 13
# Subtest: row253 C4 P10 inner reason holds under both sudo models
not ok 1 - row253 C4 P10 inner reason holds under both sudo models
---
duration_ms: 4641.831075
type: 'test'
location: '/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:421:49'
failureType: 'testCodeFailure'
error: 'exec: direct probe 1.23s; baseline 1.764558389s is diagnostic only'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: true
actual: false
operator: '=='
stack: |-
TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:450:29)
async Test.run (node:internal/test_runner/test:1409:7)
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
...
# {"fault":"inner","mode":"exec","baselineSeconds":1.764558389,"faultSeconds":2.8568522200000004,"probeSeconds":1.23}
1..1
# tests 1
# suites 0
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 4737.590412
@@ -1 +0,0 @@
CLEAR
@@ -1,18 +0,0 @@
{
"label": "M2-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gZ30EQX",
"started_utc": "2026-10-23T07:49:36Z",
"start_load": "1.47 2.48 2.67 1/5822 1162481",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M2-syntax.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:49:36Z",
"load": "1.47 2.48 2.67 3/5823 1162482"
}
]
Whitespace-only changes.
@@ -1 +0,0 @@
CLEAR
@@ -1,21 +0,0 @@
{
"label": "M2",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 inner reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gYr4G6o",
"started_utc": "2026-10-23T07:49:37Z",
"start_load": "1.47 2.48 2.67 1/5823 1165689",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M2.log",
"expected_red": true
}
@@ -1,12 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:49:37Z",
"load": "1.47 2.48 2.67 3/5824 1165690"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:49:42Z",
"load": "1.43 2.45 2.66 3/5865 1168855"
}
]
-29
View File
@@ -1,29 +0,0 @@
TAP version 13
# Subtest: row253 C4 P10 inner reason holds under both sudo models
not ok 1 - row253 C4 P10 inner reason holds under both sudo models
---
duration_ms: 6624.625527
type: 'test'
location: '/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:421:49'
failureType: 'testCodeFailure'
error: 'exec: direct probe 3.24s; baseline 1.754618234s is diagnostic only'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: true
actual: false
operator: '=='
stack: |-
TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:450:29)
async Test.run (node:internal/test_runner/test:1409:7)
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
...
# {"fault":"inner","mode":"exec","baselineSeconds":1.754618234,"faultSeconds":4.849417662,"probeSeconds":3.24}
1..1
# tests 1
# suites 0
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 6718.852297
@@ -1,6 +0,0 @@
CLEAR
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1169351/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1169352/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1169353/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1169354/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1169382/cmdline: No such file or directory
@@ -1,18 +0,0 @@
{
"label": "M3-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gwCkjzX",
"started_utc": "2026-10-23T07:49:45Z",
"start_load": "1.40 2.43 2.66 2/5844 1172866",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M3-syntax.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:49:45Z",
"load": "1.40 2.43 2.66 4/5845 1172867"
}
]
Whitespace-only changes.
@@ -1,7 +0,0 @@
CLEAR
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1172650/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1172687/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1172732/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1172780/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1172825/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1172863/cmdline: No such file or directory
@@ -1,21 +0,0 @@
{
"label": "M3",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 outer reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/g6TrU8V",
"started_utc": "2026-10-23T07:49:46Z",
"start_load": "1.40 2.43 2.66 2/5868 1176268",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M3.log",
"expected_red": true
}
@@ -1,12 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:49:46Z",
"load": "1.40 2.43 2.66 4/5869 1176269"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:49:51Z",
"load": "1.44 2.42 2.65 1/5889 1179184"
}
]
-29
View File
@@ -1,29 +0,0 @@
TAP version 13
# Subtest: row253 C4 P10 outer reason holds under both sudo models
not ok 1 - row253 C4 P10 outer reason holds under both sudo models
---
duration_ms: 6474.774742
type: 'test'
location: '/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:421:49'
failureType: 'testCodeFailure'
error: 'exec: direct probe 3.01s; baseline 1.7982556909999998s is diagnostic only'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: true
actual: false
operator: '=='
stack: |-
TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:452:11)
async Test.run (node:internal/test_runner/test:1409:7)
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
...
# {"fault":"outer","mode":"exec","baselineSeconds":1.7982556909999998,"faultSeconds":4.664919980999999,"probeSeconds":3.01}
1..1
# tests 1
# suites 0
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 6573.218398
@@ -1 +0,0 @@
CLEAR
@@ -1,18 +0,0 @@
{
"label": "M4-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gRPd59t",
"started_utc": "2026-10-23T07:49:54Z",
"start_load": "1.41 2.40 2.64 3/5836 1182894",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M4-syntax.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:49:54Z",
"load": "1.41 2.40 2.64 7/5837 1182895"
}
]
Whitespace-only changes.
@@ -1,3 +0,0 @@
CLEAR
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1182788/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1182883/cmdline: No such file or directory
@@ -1,21 +0,0 @@
{
"label": "M4",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 outer reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gAKhO44",
"started_utc": "2026-10-23T07:49:56Z",
"start_load": "1.41 2.40 2.64 8/5839 1186447",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M4.log",
"expected_red": true
}
@@ -1,12 +0,0 @@
[
{
"wall_seconds": 0.001,
"utc": "2026-10-23T07:49:56Z",
"load": "1.41 2.40 2.64 8/5838 1186448"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:50:01Z",
"load": "1.54 2.41 2.64 5/5866 1190264"
}
]
-92
View File
@@ -1,92 +0,0 @@
TAP version 13
# Subtest: row253 C4 P10 outer reason holds under both sudo models
not ok 1 - row253 C4 P10 outer reason holds under both sudo models
---
duration_ms: 8880.927284
type: 'test'
location: '/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:421:49'
failureType: 'testCodeFailure'
error: |-
The input did not match the regular expression /P10 tester-socket-squat unnamed boundary=failed reason=probe-outer-timeout /. Input:
'F1 units-user pass [email protected] and mosaic-webui.service are active as mosaic (uid 997)\n' +
'F2 console-loopback pass healthz answers, and 732 is bound to 127.0.0.1 only, by MainPID 200\n' +
'F3 tester-reply pass chief replied to case1-accept-e61888cb4c54\n' +
'F4 precheck pass case2-precheck.sh --profile factory exits 0\n' +
"F5 bwrap-label pass bwrap 300 reads 'bwrap (enforce)' and its claude descendant 302 reads 'bwrap//&unpriv_bwrap (enforce)'\n" +
"F6 claude-pin pass /opt/mosaic-stack/claude-2.1.0/node_modules/@anthropic-ai/claude-code/bin/claude.exe prints '2.1.0 (Claude Code)'\n" +
'F7 pm-live pass one live launch: pm run r-0002\n' +
"F8 credential-file pass /srv/mosaic/.config/mosaic-dev/secrets/claude-session.env is 'mosaic 600 regular file'\n" +
'F9 autoupdater-off pass /etc/claude-code/managed-settings.json is root:root 0644 with env.DISABLE_AUTOUPDATER "1"\n' +
'F10 node-pin pass /opt/mosaic-stack/node-v24.1.0/bin/node prints v24.1.0\n' +
'F11 no-discord pass /srv/mosaic/.mosaic-dev/discord is absent\n' +
'P1 mosaic-sudo closed sudo -l: User mosaic is not allowed to run sudo on dev-53.\n' +
"P2 mosaic-groups-keys closed id -G is '997'; authorized_keys is absent\n" +
'P3 localadmin-sudo accepted Q183 sudo -l -U localadmin lists 1 NOPASSWD lines\n' +
"P4 pve-root-pbs accepted Q182+Q183 root on pve over VM 1008, and PBS backups that hold /srv/mosaic with the credential; this script can't see pve\n" +
'P5 jarvis-reach closed jarvis is in none of sudo, docker and lxd (groups: jarvis)\n' +
'P6 group-members closed sudo holds only localadmin, and docker and lxd have no members\n' +
'P7 sudoers-d closed no file under /etc/sudoers.d names mosaic\n' +
'P8 lan-listeners closed 732 is on 127.0.0.1 only by MainPID 200; no TCP listener on 7331 or 7333; tester uses /srv/mosaic/.mosaic-dev/console/tester.sock\n' +
'P9 bwrap-userns accepted mos-1096 hostcheck items 1-6 ok, jarvis is denied bwrap, and group mosaic has no other member\n' +
'P10 tester-socket-squat unnamed boundary=failed reason=probe-inner-command path=/srv/mosaic/.mosaic-dev/console/tester.sock MainPID=200; hostile same-uid substitution remains\n' +
'P11 hostcheck-before-bus closed mosaic-hostcheck.service is enabled, and its Before= names [email protected]\n' +
'count pass 11\n' +
'count FAIL 0\n' +
'count closed 7\n' +
'count accepted Q182+Q183 1\n' +
'count accepted Q183 1\n' +
'count accepted mos-1096 1\n' +
'count unnamed 1\n' +
'case1-accept: every F check passes; send the whole output to Duckworth, and each unnamed line to Mos\n'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected:
actual: |-
F1 units-user pass [email protected] and mosaic-webui.service are active as mosaic (uid 997)
F2 console-loopback pass healthz answers, and 732 is bound to 127.0.0.1 only, by MainPID 200
F3 tester-reply pass chief replied to case1-accept-e61888cb4c54
F4 precheck pass case2-precheck.sh --profile factory exits 0
F5 bwrap-label pass bwrap 300 reads 'bwrap (enforce)' and its claude descendant 302 reads 'bwrap//&unpriv_bwrap (enforce)'
F6 claude-pin pass /opt/mosaic-stack/claude-2.1.0/node_modules/@anthropic-ai/claude-code/bin/claude.exe prints '2.1.0 (Claude Code)'
F7 pm-live pass one live launch: pm run r-0002
F8 credential-file pass /srv/mosaic/.config/mosaic-dev/secrets/claude-session.env is 'mosaic 600 regular file'
F9 autoupdater-off pass /etc/claude-code/managed-settings.json is root:root 0644 with env.DISABLE_AUTOUPDATER "1"
F10 node-pin pass /opt/mosaic-stack/node-v24.1.0/bin/node prints v24.1.0
F11 no-discord pass /srv/mosaic/.mosaic-dev/discord is absent
P1 mosaic-sudo closed sudo -l: User mosaic is not allowed to run sudo on dev-53.
P2 mosaic-groups-keys closed id -G is '997'; authorized_keys is absent
P3 localadmin-sudo accepted Q183 sudo -l -U localadmin lists 1 NOPASSWD lines
P4 pve-root-pbs accepted Q182+Q183 root on pve over VM 1008, and PBS backups that hold /srv/mosaic with the credential; this script can't see pve
P5 jarvis-reach closed jarvis is in none of sudo, docker and lxd (groups: jarvis)
P6 group-members closed sudo holds only localadmin, and docker and lxd have no members
P7 sudoers-d closed no file under /etc/sudoers.d names mosaic
P8 lan-listeners closed 732 is on 127.0.0.1 only by MainPID 200; no TCP listener on 7331 or 7333; tester uses /srv/mosaic/.mosaic-dev/console/tester.sock
P9 bwrap-userns accepted mos-1096 hostcheck items 1-6 ok, jarvis is denied bwrap, and group mosaic has no other member
P10 tester-socket-squat unnamed boundary=failed reason=probe-inner-command path=/srv/mosaic/.mosaic-dev/console/tester.sock MainPID=200; hostile same-uid substitution remains
P11 hostcheck-before-bus closed mosaic-hostcheck.service is enabled, and its Before= names [email protected]
count pass 11
count FAIL 0
count closed 7
count accepted Q182+Q183 1
count accepted Q183 1
count accepted mos-1096 1
count unnamed 1
case1-accept: every F check passes; send the whole output to Duckworth, and each unnamed line to Mos
operator: 'match'
stack: |-
TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:445:10)
async Test.run (node:internal/test_runner/test:1409:7)
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
...
1..1
# tests 1
# suites 0
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 8984.292623
@@ -1,2 +0,0 @@
CLEAR
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1193437/cmdline: No such file or directory
@@ -1,18 +0,0 @@
{
"label": "M5-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case-p10-timing-fixture.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/g8waDyO",
"started_utc": "2026-10-23T07:50:06Z",
"start_load": "1.65 2.42 2.65 2/5826 1197030",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M5-syntax.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:50:06Z",
"load": "1.65 2.42 2.65 4/5827 1197031"
}
]
Whitespace-only changes.
@@ -1,2 +0,0 @@
CLEAR
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/1197017/cmdline: No such file or directory
@@ -1,21 +0,0 @@
{
"label": "M5",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 inner reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gdAgQSv",
"started_utc": "2026-10-23T07:50:07Z",
"start_load": "1.65 2.42 2.65 2/5824 1200489",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M5.log",
"expected_red": true
}
@@ -1,12 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:50:07Z",
"load": "1.65 2.42 2.65 6/5827 1200493"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:50:12Z",
"load": "1.60 2.40 2.64 2/5882 1203150"
}
]
-38
View File
@@ -1,38 +0,0 @@
TAP version 13
# Subtest: row253 C4 P10 inner reason holds under both sudo models
not ok 1 - row253 C4 P10 inner reason holds under both sudo models
---
duration_ms: 5653.123684
type: 'test'
location: '/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:421:49'
failureType: 'testCodeFailure'
error: |-
Got unwanted exception: P10 observer pair is required
Actual message: "P10 observer needs exactly one complete ordered pair"
code: 'ERR_ASSERTION'
name: 'AssertionError'
actual:
error: 'P10 observer needs exactly one complete ordered pair'
stack: |-
readProbeSeconds (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case-p10-timing-fixture.mjs:56:42)
file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:448:55
getActual (node:assert:580:5)
strict.doesNotThrow (node:assert:748:32)
TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:448:24)
async Test.run (node:internal/test_runner/test:1409:7)
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
operator: 'doesNotThrow'
stack: |-
TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:448:24)
async Test.run (node:internal/test_runner/test:1409:7)
async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
...
1..1
# tests 1
# suites 0
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 5762.289353
@@ -1 +0,0 @@
CLEAR
@@ -1,18 +0,0 @@
{
"label": "M6-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case-p10-timing-fixture.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gD2IEb2",
"started_utc": "2026-10-23T07:50:15Z",
"start_load": "1.63 2.39 2.63 1/5845 1206646",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M6-syntax.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:50:15Z",
"load": "1.63 2.39 2.63 4/5846 1206647"
}
]
Whitespace-only changes.
@@ -1 +0,0 @@
CLEAR
@@ -1,21 +0,0 @@
{
"label": "M6",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row299 P10 observer records are complete and ordered$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gAZq1pv",
"started_utc": "2026-10-23T07:50:16Z",
"start_load": "1.63 2.39 2.63 2/5837 1210084",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M6.log",
"expected_red": true
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:50:16Z",
"load": "1.63 2.39 2.63 2/5838 1210085"
}
]
-29
View File
@@ -1,29 +0,0 @@
TAP version 13
# Subtest: row299 P10 observer records are complete and ordered
not ok 1 - row299 P10 observer records are complete and ordered
---
duration_ms: 1.544819
type: 'test'
location: '/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:405:1'
failureType: 'testCodeFailure'
error: 'Missing expected exception: equal readings'
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected:
operator: 'throws'
stack: |-
TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196/packages/cli/tests/case1-accept.test.mjs:418:58)
Test.runInAsyncScope (node:async_hooks:226:14)
Test.run (node:internal/test_runner/test:1402:25)
Test.start (node:internal/test_runner/test:1262:17)
startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17)
...
1..1
# tests 1
# suites 0
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 97.805057
@@ -1,78 +0,0 @@
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/M1-syntax.busy.log
0e86c022784e85084f08044940ec6623e736e2eea3e87afe994cebcdaa18c016 agents/gander/work/queue-299/run1/M1-syntax.command.json
6552beee45c19264b36614eb09e49f4c24e66521732071036c194b7ab5b6c3ee agents/gander/work/queue-299/run1/M1-syntax.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/M1-syntax.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/M1.busy.log
9bfeb9cb89dde406b0b8997250139dc1eb925fb17a7d308c59ab628bd46f175d agents/gander/work/queue-299/run1/M1.command.json
c834b00bfe2b7fca539cd93a428b7d92b377a93d6a3aad65e33916735e4fca4e agents/gander/work/queue-299/run1/M1.load.json
6566b6d9f613a5904d85b0d0032a0dcd29aa81dcdfd363234537594006c1c5d4 agents/gander/work/queue-299/run1/M1.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/M2-syntax.busy.log
4c04e5dcd4e7620a50436f09b60dfb5e0177978d765e5f14fc3da301cb91c729 agents/gander/work/queue-299/run1/M2-syntax.command.json
827351dfdde96da9bc13133600a6d2997299ed442df774e1c7718c34f02259c1 agents/gander/work/queue-299/run1/M2-syntax.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/M2-syntax.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/M2.busy.log
4f0f7aef97edc93582921f5b15745bc72b3aae8ba7a71aaa145cd7d78b080af6 agents/gander/work/queue-299/run1/M2.command.json
d1ccdfc399964b4a9f61f2ff8eb5304b9556033e1e255467b0887460e56f5ae0 agents/gander/work/queue-299/run1/M2.load.json
b80762fb0b571cadaad5fcf5e43e040c533d2aca1cf939ea4247c5c8f50bd176 agents/gander/work/queue-299/run1/M2.log
8e62af85b120ec37099cfba76475359132a1ec673b55350da4442a2356f18fb4 agents/gander/work/queue-299/run1/M3-syntax.busy.log
019d63399b36b47bdf38730229aabd8edb5c25e27f7f78f462c70963a02aca69 agents/gander/work/queue-299/run1/M3-syntax.command.json
d31ae584602d69e1c6d68e1186b45d518741028e5f9ca289ddba6b472638e634 agents/gander/work/queue-299/run1/M3-syntax.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/M3-syntax.log
2d80452846bb5af54c76122f0647cb850bbf22ed114e17f9fb883b2c41f3d82e agents/gander/work/queue-299/run1/M3.busy.log
5619bd5a00679fc783d1f0ef8111570268238fc5cfc3b0586539fece039a0d14 agents/gander/work/queue-299/run1/M3.command.json
3ac8b2e351f5b3e016114f7ff45cc71a1d6287c4dc8d52640c6233424afdc59b agents/gander/work/queue-299/run1/M3.load.json
d5f21e277400f33779ea94940979bc89ae54c7484a762f373027bf837b98a47a agents/gander/work/queue-299/run1/M3.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/M4-syntax.busy.log
c6f7857ef123cddd6190eba9e6b9a3356821bb0b3a797a1b05a2e19d108c5ec7 agents/gander/work/queue-299/run1/M4-syntax.command.json
f983475d9ea0c5cbff43d0de9f8514488d20e2d7732af8d050ca10b9fb81c061 agents/gander/work/queue-299/run1/M4-syntax.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/M4-syntax.log
d2361f293ed1242c07568092784e830638a3da691d01019a18beaff859d96b2a agents/gander/work/queue-299/run1/M4.busy.log
f66ae61b9ed0ea5a720f5c2457ecfb8cc610e192cd619ee5433f24af25f17f85 agents/gander/work/queue-299/run1/M4.command.json
cd20239485328874f8bbe30acd9470c3874011ef5bb6f39f33ed210b7c4a4f27 agents/gander/work/queue-299/run1/M4.load.json
e64c363e8f11574be893acce37a4152c90c31f5547ca6d48780160c556f0db70 agents/gander/work/queue-299/run1/M4.log
7c3a3b6bcf027e99e0f3903215f4ffca88d8bff9fb3a8ef92d3b28bfa68ba52a agents/gander/work/queue-299/run1/M5-syntax.busy.log
3e0f4c82616fa3fa7274ad91ec3f2baa86b7b22288d7507730e66c8e4809c681 agents/gander/work/queue-299/run1/M5-syntax.command.json
e0093f4ad39d9d4342b43c0ed2d7671747870d6d6166d0692eecbf3dc8033645 agents/gander/work/queue-299/run1/M5-syntax.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/M5-syntax.log
f104c336fdfa56a241f1b769938b71eafbfb237a88b3089309671eb5a8db4f0e agents/gander/work/queue-299/run1/M5.busy.log
35f7ce5f6e56047d600633a0e27826f6f54aa585552593bfb4954f8469238f7a agents/gander/work/queue-299/run1/M5.command.json
059de490b1a31be3a8c9a02ff49f84b744d057f66d4f55508e637e6b0896b670 agents/gander/work/queue-299/run1/M5.load.json
42e0a43b161e61775b0d4bdde73be4c131a8d6edb4aabf14422755e553272a3f agents/gander/work/queue-299/run1/M5.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/M6-syntax.busy.log
867359f0e7ebf5516ae1e1147327e9f6e20d48cb2993b46866f9d90a9ebdbecb agents/gander/work/queue-299/run1/M6-syntax.command.json
8d1d69b01dffda714da78c7f08e14b7d1db12a788c812ab02d3a3faa6c52d8a6 agents/gander/work/queue-299/run1/M6-syntax.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/M6-syntax.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/M6.busy.log
3e46e6d020a0fe9782b3e84462f634daed0885c0e992e482f7d815524fe2294e agents/gander/work/queue-299/run1/M6.command.json
24e987a747661e01b9e2a28b0580a0be5b16fad57da5c8c35f41b82835ea76ed agents/gander/work/queue-299/run1/M6.load.json
8a0f18ea13b69c71a742a755eb7437d06e49679b777880a8db7b4297ae9849d9 agents/gander/work/queue-299/run1/M6.log
e8efed810462567a977a64235454f5d59e92dbfb570d5537652c8deb52b9de66 agents/gander/work/queue-299/run1/RESULTS.md
e055720cf64d62331a1e957d285d2583bfb3708fc1b9bf951ab8a99a25c5b2e4 agents/gander/work/queue-299/run1/ambient-overlap.json
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/case1-whole-1.busy.log
16ea379e1482e79b380c9a7be82703e735bea7ef80f1e785a032af9198b26c35 agents/gander/work/queue-299/run1/case1-whole-1.command.json
d87a93023d545cd38fcf0a77577c88326897700325fbecd84fd8287a26b33864 agents/gander/work/queue-299/run1/case1-whole-1.load.json
c4d7cf6a001a6741af3aa0e0615989327f63fe92999e8fb6d46c2d30f8c08f09 agents/gander/work/queue-299/run1/case1-whole-1.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/case1-whole-2.busy.log
4b69775fb03d9fa56a9eef0c9dc8f3cb00013aa4d601f433519ef1dafcc2544c agents/gander/work/queue-299/run1/case1-whole-2.command.json
62c4cc338455841d9faf1198acddc3f3204346800e2db7222d1fc33aba189fe3 agents/gander/work/queue-299/run1/case1-whole-2.load.json
2ed90fe79a18f794363c47e34440b877a3ffa1256f9a5badb31b317ecbc2fb7b agents/gander/work/queue-299/run1/case1-whole-2.log
56d73910ed8d6773724be75e02506a365e5e03c4c98be07a32d49957f24b3e4a agents/gander/work/queue-299/run1/case1-whole-3.busy.log
a9225b3ae990e328d739d9259b5dfce0391d5054dedd074f53b81c92e7225c1a agents/gander/work/queue-299/run1/case1-whole-3.command.json
dc440ef86b769bf498ed9fcaa178ef9098f7bb9233dd625579d344464c00b11a agents/gander/work/queue-299/run1/case1-whole-3.load.json
a803a8e73902337b63d229d0703d45ec9fccd7a1930e192d322d4cc79b9774d6 agents/gander/work/queue-299/run1/case1-whole-3.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/cli-whole.busy.log
e3ea8c0434fb979a4943f1bfab1984ff8b919bb062945803e1ddcaa61170d1a5 agents/gander/work/queue-299/run1/cli-whole.command.json
db54ea06016fa065f25ed62f5704757a727ff37009e010fa43b1e297bfb2b51b agents/gander/work/queue-299/run1/cli-whole.load.json
5222a0807a5ed3d8548711d09e7d3b09504f18b5f3f095c2529b4eedf5a2846b agents/gander/work/queue-299/run1/cli-whole.log
d58a500c8e125540aeee461cde68aa6bfe65ab386ae15c9af7dfe363a73a9fd2 agents/gander/work/queue-299/run1/controller.log
906c08da89e164e214464014edb672f8d389cb3eab70929d994bcff2794ff45a agents/gander/work/queue-299/run1/results.json
b7450a29a470bb48c300d630cd8079be283187d372b9bafd0fbaaafb261e9639 agents/gander/work/queue-299/run1/sweep.json
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/syntax-1.busy.log
03471d51f50a2607f65bc6bfc5764119421fedd003bd569b5fc9ce7fa57c6be6 agents/gander/work/queue-299/run1/syntax-1.command.json
e429b112499bf432c8f561b02119025476f57f03208ee67a85282802a431de2d agents/gander/work/queue-299/run1/syntax-1.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/syntax-1.log
ba45d57c9b255311bb220598f90c1a4fb01b420511974c28f102881cbd7df21a agents/gander/work/queue-299/run1/syntax-2.busy.log
287a012953621602eaf7eb129a836b2e3be076b72d6da7131b5e605d2bb5c4ff agents/gander/work/queue-299/run1/syntax-2.command.json
795e4a257a3836bfe65ddfa5a734ed239145d1add7d543d52263707467e2345d agents/gander/work/queue-299/run1/syntax-2.load.json
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 agents/gander/work/queue-299/run1/syntax-2.log
13987615007f93b11780d44e827ce6a9a57e4373f0074a838ca87b762758d053 agents/gander/work/queue-299/run1/window.py
@@ -1,38 +0,0 @@
# Row 299 gate run 1
Grant sage-3268. Candidate ffa93b054f28852a75017928d8478bdf9046e717, base 80793d824, manifest 277ace0b4274970d5bd4c05cf8fe99aa1e7ebc469a719e4cefcb334a75d3865d. Run 2026-10-23T07:26:52Z to 2026-10-23T07:50:16Z, 1404 seconds by UTC timestamps. No carried result or retry.
The preflight passed. All three case1 files and all 59 CLI files ran whole. Unmutated total: 1076 pass, 0 fail, 0 skip, 0 cancelled, 0 todo. Mutants: 6/6 killed by named assertions, no external timeout. All six restores match their original SHA256 and have clean git status. Sweep: 0 gate residuals; four MCP harness processes predate the gate, with start times in sweep.json.
| Stage | Pass | Fail | Skip | Wall seconds | Start load |
| --- | ---: | ---: | ---: | ---: | --- |
| case1-whole-1 | 53 | 0 | 0 | 239.134 | 1.05 |
| case1-whole-2 | 53 | 0 | 0 | 240.044 | 3.41 |
| case1-whole-3 | 53 | 0 | 0 | 235.011 | 2.08 |
| cli-whole | 917 | 0 | 0 | 631.848 | 1.91 |
CLI sampled 1-minute load range: 1.54 to 7.17. Ambient >=4 was a target, not a wait condition. No stress process. Each of the three case1 start loads and the CLI start/load samples are recorded. The direct readings below come from the test diagnostics, with fixed inner [1.25,2.75) and outer [3.25,4.75) bands.
| Stage | Inner exec | Inner hop | Outer exec | Outer hop |
| --- | ---: | ---: | ---: | ---: |
| case1-whole-1 | 2.25 | 2.27 | 4 | 4 |
| case1-whole-2 | 2.29 | 2.28 | 4 | 4.01 |
| case1-whole-3 | 2.25 | 2.26 | 4 | 4 |
| cli-whole | 2.27 | 2.27 | 4.01 | 4.01 |
| Mutant | Named killer | Assertion | Direct interval | Wall seconds |
| --- | --- | --- | --- | ---: |
| M1 | row253 C4 P10 inner reason holds under both sudo models | case1-accept.test.mjs:450 lower band | 1.23 | 4.774 |
| M2 | row253 C4 P10 inner reason holds under both sudo models | case1-accept.test.mjs:450 upper band | 3.24 | 6.768 |
| M3 | row253 C4 P10 outer reason holds under both sudo models | case1-accept.test.mjs:452 outer lower band | 3.01 | 6.618 |
| M4 | row253 C4 P10 outer reason holds under both sudo models | case1-accept.test.mjs:445 exact probe-outer-timeout reason | not reached | 9.023 |
| M5 | row253 C4 P10 inner reason holds under both sudo models | case1-accept.test.mjs:448 required complete pair (doesNotThrow) | not reached | 5.816 |
| M6 | row299 P10 observer records are complete and ordered | case1-accept.test.mjs:418 equal readings must refuse (throws) | not reached | 0.164 |
M1 measured 1.23 s, below 1.25 by only 0.02 s. This is the anticipated startup-overhead risk. It died at the intended lower-band assertion; no tuning or retry was used.
M4 classification follows sage-3271, sage-3273 and mos-1426. The unchanged 7000 ms fixture guard returned; the named outer test failed with ERR_ASSERTION / match at line 445 because P10 reported reason=probe-inner-command instead of exact reason=probe-outer-timeout. It returned rc 1 in 9.023 s including the baseline. No external command timeout or cleanup-only failure was counted. Raw evidence: M4.log, M4.command.json, results.json guard_return_receipt and clean restore.
sage-3274 reported a read-only canonical queue polling overlap for receipts window 07:20–07:26Z. It wrote nothing and touched no worktree or test path. This is accepted ambient load, not a rerun condition; ambient-overlap.json keeps the report.
All raw logs, command headers with timeout -k 10, TMPDIRs, per-stage load samples, controller, results, and restores are in this directory. Every run used a fresh short TMPDIR directly under /mnt/storage/scratch/tmp. No source or assertion changed during the gate.
@@ -1,10 +0,0 @@
{
"source": "sage-3274",
"reported_utc": "2026-10-23T07:27:24Z",
"window_utc": [
"2026-10-23T07:20:00Z",
"2026-10-23T07:26:00Z"
],
"activity": "Read-only canonical queue show 303 every 20 seconds by Duckworth, stopped; no writes or test/worktree paths touched",
"classification": "Allowed ambient overlap under mos-1409, no rerun or recheck"
}
@@ -1 +0,0 @@
CLEAR
@@ -1,19 +0,0 @@
{
"label": "case1-whole-1",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/geSGqXZ",
"started_utc": "2026-10-23T07:26:57Z",
"start_load": "1.05 1.69 2.00 1/6640 205920",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/case1-whole-1.log",
"expected_red": false
}
@@ -1,242 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:26:57Z",
"load": "1.05 1.69 2.00 5/6641 205921"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:27:02Z",
"load": "1.05 1.68 1.99 2/6664 208983"
},
{
"wall_seconds": 10.001,
"utc": "2026-10-23T07:27:07Z",
"load": "1.12 1.69 1.99 4/6679 212072"
},
{
"wall_seconds": 15.001,
"utc": "2026-10-23T07:27:12Z",
"load": "1.19 1.69 1.99 4/6676 215231"
},
{
"wall_seconds": 20.001,
"utc": "2026-10-23T07:27:17Z",
"load": "1.26 1.70 1.99 2/6696 218364"
},
{
"wall_seconds": 25.002,
"utc": "2026-10-23T07:27:22Z",
"load": "1.24 1.69 1.99 2/6689 221537"
},
{
"wall_seconds": 30.002,
"utc": "2026-10-23T07:27:27Z",
"load": "1.22 1.67 1.98 2/6683 224753"
},
{
"wall_seconds": 35.002,
"utc": "2026-10-23T07:27:32Z",
"load": "1.36 1.70 1.99 3/6686 228651"
},
{
"wall_seconds": 40.002,
"utc": "2026-10-23T07:27:37Z",
"load": "1.33 1.68 1.98 3/6709 231645"
},
{
"wall_seconds": 45.003,
"utc": "2026-10-23T07:27:42Z",
"load": "1.22 1.66 1.97 2/6719 234495"
},
{
"wall_seconds": 50.003,
"utc": "2026-10-23T07:27:47Z",
"load": "1.21 1.64 1.97 3/6710 235979"
},
{
"wall_seconds": 55.003,
"utc": "2026-10-23T07:27:52Z",
"load": "1.27 1.65 1.97 3/6724 238345"
},
{
"wall_seconds": 60.003,
"utc": "2026-10-23T07:27:57Z",
"load": "1.33 1.66 1.97 4/6734 240013"
},
{
"wall_seconds": 65.004,
"utc": "2026-10-23T07:28:02Z",
"load": "1.38 1.66 1.97 1/6730 240697"
},
{
"wall_seconds": 70.004,
"utc": "2026-10-23T07:28:07Z",
"load": "1.43 1.67 1.97 4/6727 243478"
},
{
"wall_seconds": 75.004,
"utc": "2026-10-23T07:28:12Z",
"load": "1.48 1.67 1.97 2/6745 245706"
},
{
"wall_seconds": 80.004,
"utc": "2026-10-23T07:28:17Z",
"load": "1.44 1.66 1.96 2/6741 247933"
},
{
"wall_seconds": 85.005,
"utc": "2026-10-23T07:28:22Z",
"load": "1.48 1.67 1.97 1/6742 249267"
},
{
"wall_seconds": 90.005,
"utc": "2026-10-23T07:28:27Z",
"load": "1.53 1.68 1.97 1/6710 251793"
},
{
"wall_seconds": 95.005,
"utc": "2026-10-23T07:28:32Z",
"load": "1.48 1.66 1.96 2/6712 253250"
},
{
"wall_seconds": 100.005,
"utc": "2026-10-23T07:28:37Z",
"load": "1.53 1.67 1.96 4/6719 256547"
},
{
"wall_seconds": 105.006,
"utc": "2026-10-23T07:28:42Z",
"load": "1.56 1.68 1.96 5/6721 259938"
},
{
"wall_seconds": 110.006,
"utc": "2026-10-23T07:28:47Z",
"load": "1.68 1.70 1.97 4/6762 263119"
},
{
"wall_seconds": 115.006,
"utc": "2026-10-23T07:28:52Z",
"load": "1.86 1.74 1.98 3/6741 266483"
},
{
"wall_seconds": 120.006,
"utc": "2026-10-23T07:28:57Z",
"load": "2.20 1.81 2.00 2/6714 269932"
},
{
"wall_seconds": 125.006,
"utc": "2026-10-23T07:29:02Z",
"load": "2.42 1.86 2.02 6/6713 274031"
},
{
"wall_seconds": 130.007,
"utc": "2026-10-23T07:29:07Z",
"load": "2.55 1.90 2.03 3/6718 277881"
},
{
"wall_seconds": 135.007,
"utc": "2026-10-23T07:29:12Z",
"load": "2.58 1.91 2.03 2/6741 281990"
},
{
"wall_seconds": 140.007,
"utc": "2026-10-23T07:29:17Z",
"load": "2.62 1.93 2.04 4/6740 286159"
},
{
"wall_seconds": 145.007,
"utc": "2026-10-23T07:29:22Z",
"load": "2.73 1.97 2.05 2/6748 290530"
},
{
"wall_seconds": 150.008,
"utc": "2026-10-23T07:29:27Z",
"load": "2.99 2.04 2.07 2/6701 294400"
},
{
"wall_seconds": 155.008,
"utc": "2026-10-23T07:29:32Z",
"load": "3.07 2.07 2.08 3/6694 297610"
},
{
"wall_seconds": 160.008,
"utc": "2026-10-23T07:29:37Z",
"load": "3.15 2.10 2.09 5/6705 300813"
},
{
"wall_seconds": 165.008,
"utc": "2026-10-23T07:29:42Z",
"load": "3.05 2.10 2.09 2/6703 304321"
},
{
"wall_seconds": 170.008,
"utc": "2026-10-23T07:29:47Z",
"load": "3.05 2.11 2.10 3/6739 307613"
},
{
"wall_seconds": 175.009,
"utc": "2026-10-23T07:29:52Z",
"load": "2.97 2.11 2.10 2/6745 310850"
},
{
"wall_seconds": 180.009,
"utc": "2026-10-23T07:29:57Z",
"load": "2.89 2.11 2.09 4/6709 314125"
},
{
"wall_seconds": 185.009,
"utc": "2026-10-23T07:30:02Z",
"load": "3.14 2.17 2.12 4/6698 317556"
},
{
"wall_seconds": 190.009,
"utc": "2026-10-23T07:30:07Z",
"load": "3.93 2.35 2.17 2/6708 321964"
},
{
"wall_seconds": 195.009,
"utc": "2026-10-23T07:30:12Z",
"load": "3.93 2.38 2.18 2/6713 325120"
},
{
"wall_seconds": 200.01,
"utc": "2026-10-23T07:30:17Z",
"load": "3.78 2.38 2.18 3/6721 328405"
},
{
"wall_seconds": 205.01,
"utc": "2026-10-23T07:30:22Z",
"load": "3.80 2.40 2.19 2/6725 331643"
},
{
"wall_seconds": 210.01,
"utc": "2026-10-23T07:30:27Z",
"load": "3.89 2.45 2.21 5/6714 335757"
},
{
"wall_seconds": 215.01,
"utc": "2026-10-23T07:30:32Z",
"load": "3.74 2.44 2.21 2/6706 339141"
},
{
"wall_seconds": 220.01,
"utc": "2026-10-23T07:30:37Z",
"load": "3.60 2.43 2.20 3/6722 342107"
},
{
"wall_seconds": 225.011,
"utc": "2026-10-23T07:30:42Z",
"load": "3.63 2.46 2.21 4/6716 345179"
},
{
"wall_seconds": 230.011,
"utc": "2026-10-23T07:30:47Z",
"load": "3.66 2.48 2.22 2/6740 349322"
},
{
"wall_seconds": 235.011,
"utc": "2026-10-23T07:30:52Z",
"load": "3.53 2.47 2.22 3/6745 352500"
}
]
@@ -1,332 +0,0 @@
TAP version 13
# Subtest: row253 socket observation uses configured root, metadata and the Console peer without sending bytes
ok 1 - row253 socket observation uses configured root, metadata and the Console peer without sending bytes
---
duration_ms: 1855.818133
type: 'test'
...
# Subtest: row253 P10 refuses unsafe metadata, wrong peers and an unsafe Python without claiming closure
ok 2 - row253 P10 refuses unsafe metadata, wrong peers and an unsafe Python without claiming closure
---
duration_ms: 29336.896059
type: 'test'
...
# Subtest: row253 acceptance rejects bad config and unsupported copies before talk
ok 3 - row253 acceptance rejects bad config and unsupported copies before talk
---
duration_ms: 1492.589344
type: 'test'
...
# Subtest: row253 stalled peer observation ends within its bound without leaving a reader
ok 4 - row253 stalled peer observation ends within its bound without leaving a reader
---
duration_ms: 3995.592937
type: 'test'
...
# Subtest: row253 P8 refuses both retired TCP and board listeners
ok 5 - row253 P8 refuses both retired TCP and board listeners
---
duration_ms: 3885.105115
type: 'test'
...
# Subtest: row253 C4 acceptance query inner reason holds under both sudo models
ok 6 - row253 C4 acceptance query inner reason holds under both sudo models
---
duration_ms: 10722.031738
type: 'test'
...
# Subtest: row253 C4 acceptance query outer reason discards stdout and names residual cleanup
ok 7 - row253 C4 acceptance query outer reason discards stdout and names residual cleanup
---
duration_ms: 14183.471618
type: 'test'
...
# Subtest: row253 C4 acceptance query overflow is output-limit in both models
ok 8 - row253 C4 acceptance query overflow is output-limit in both models
---
duration_ms: 492.660764
type: 'test'
...
# Subtest: row299 P10 timing copy preserves shipped bytes and isolates observer variables
ok 9 - row299 P10 timing copy preserves shipped bytes and isolates observer variables
---
duration_ms: 0.874413
type: 'test'
...
# Subtest: row299 P10 observers preserve stdout stderr status and the EXIT trap
ok 10 - row299 P10 observers preserve stdout stderr status and the EXIT trap
---
duration_ms: 3.117643
type: 'test'
...
# Subtest: row299 P10 observer records are complete and ordered
ok 11 - row299 P10 observer records are complete and ordered
---
duration_ms: 0.494254
type: 'test'
...
# Subtest: row253 C4 P10 inner reason holds under both sudo models
ok 12 - row253 C4 P10 inner reason holds under both sudo models
---
duration_ms: 11837.509919
type: 'test'
...
# {"fault":"inner","mode":"exec","baselineSeconds":1.8914214159999974,"faultSeconds":3.974223306999993,"probeSeconds":2.25}
# {"fault":"inner","mode":"hop","baselineSeconds":1.8980776110000006,"faultSeconds":4.004310756999999,"probeSeconds":2.27}
# Subtest: row253 C4 P10 outer reason holds under both sudo models
ok 13 - row253 C4 P10 outer reason holds under both sudo models
---
duration_ms: 15238.957947
type: 'test'
...
# {"fault":"outer","mode":"exec","baselineSeconds":1.8725320299999875,"faultSeconds":5.715126132999998,"probeSeconds":4}
# {"fault":"outer","mode":"hop","baselineSeconds":1.8715896639999992,"faultSeconds":5.726812752999991,"probeSeconds":4}
# Subtest: row253 C4 P10 overflow reason holds under both sudo models
ok 14 - row253 C4 P10 overflow reason holds under both sudo models
---
duration_ms: 3757.733977
type: 'test'
...
# Subtest: row 195 accept: every check passing exits 0, with each P mark and counts that match the lines
ok 15 - row 195 accept: every check passing exits 0, with each P mark and counts that match the lines
---
duration_ms: 1879.003371
type: 'test'
...
# Subtest: row 195 accept: exits 1 with each F check failing alone, and its line names it
ok 16 - row 195 accept: exits 1 with each F check failing alone, and its line names it
---
duration_ms: 21149.551708
type: 'test'
...
# Subtest: row 195 accept: F3 fails on exit 0 with no reply line, and its evidence takes talk's error
ok 17 - row 195 accept: F3 fails on exit 0 with no reply line, and its evidence takes talk's error
---
duration_ms: 3936.849005
type: 'test'
...
# Subtest: row 195 accept: F1 fails on a unit that isn't active or isn't User=mosaic
ok 18 - row 195 accept: F1 fails on a unit that isn't active or isn't User=mosaic
---
duration_ms: 3519.175544
type: 'test'
...
# Subtest: row 195 accept: F2 fails when healthz doesn't answer and when another pid holds the port
ok 19 - row 195 accept: F2 fails when healthz doesn't answer and when another pid holds the port
---
duration_ms: 3846.383271
type: 'test'
...
# Subtest: row 195 accept: F5 fails on unpriv_bwrap (enforce), on complain and on a trailing space
ok 20 - row 195 accept: F5 fails on unpriv_bwrap (enforce), on complain and on a trailing space
---
duration_ms: 8775.592742
type: 'test'
...
# Subtest: row 195 accept: F5 fails with no bwrap of mosaic's, and passes on comm alone
ok 21 - row 195 accept: F5 fails with no bwrap of mosaic's, and passes on comm alone
---
duration_ms: 4053.330344
type: 'test'
...
# Subtest: row 195 accept: F6 fails on a stub that prints nothing, on a path outside claude-<pin> and on a .. segment
ok 22 - row 195 accept: F6 fails on a stub that prints nothing, on a path outside claude-<pin> and on a .. segment
---
duration_ms: 5151.877925
type: 'test'
...
# Subtest: row 195 accept: F7 fails on two live PM launches, one for another business, and no launch.by
ok 23 - row 195 accept: F7 fails on two live PM launches, one for another business, and no launch.by
---
duration_ms: 5579.901611
type: 'test'
...
# Subtest: row 195 accept: F8 fails on 0640, on another owner and on a symlink, and never prints the credential
ok 24 - row 195 accept: F8 fails on 0640, on another owner and on a symlink, and never prints the credential
---
duration_ms: 5585.627061
type: 'test'
...
# Subtest: row 195 accept: F9 fails on another owner, a group-writable mode and a number for the flag
ok 25 - row 195 accept: F9 fails on another owner, a group-writable mode and a number for the flag
---
duration_ms: 5536.898215
type: 'test'
...
# Subtest: row 195 accept: F9 won't run --node as root off the pin path or with a writable directory above it
ok 26 - row 195 accept: F9 won't run --node as root off the pin path or with a writable directory above it
---
duration_ms: 5246.446744
type: 'test'
...
# Subtest: row 195 accept: F11 fails on one *.json under discord/ and passes on an empty directory
ok 27 - row 195 accept: F11 fails on one *.json under discord/ and passes on an empty directory
---
duration_ms: 3711.063365
type: 'test'
...
# Subtest: row 195 accept: each P check reports unnamed on its fault, and the exit stays 0
ok 28 - row 195 accept: each P check reports unnamed on its fault, and the exit stays 0
---
duration_ms: 16646.70564
type: 'test'
...
# Subtest: row 195 accept: P2 is unnamed with a supplementary group, and P5 names docker
ok 29 - row 195 accept: P2 is unnamed with a supplementary group, and P5 names docker
---
duration_ms: 3728.983
type: 'test'
...
# Subtest: row 195 accept: P5 is closed with no jarvis account, and P2 with an empty authorized_keys
ok 30 - row 195 accept: P5 is closed with no jarvis account, and P2 with an empty authorized_keys
---
duration_ms: 1843.108704
type: 'test'
...
# Subtest: row 195 accept: P9 is unnamed once for each item missing
ok 31 - row 195 accept: P9 is unnamed once for each item missing
---
duration_ms: 9276.56305
type: 'test'
...
# Subtest: row253 accept: P10 fails its observation with another peer; P11 with the unit disabled
ok 32 - row253 accept: P10 fails its observation with another peer; P11 with the unit disabled
---
duration_ms: 3822.919805
type: 'test'
...
# Subtest: row 195 accept: every P check unnamed together still exits 0
ok 33 - row 195 accept: every P check unnamed together still exits 0
---
duration_ms: 1656.312404
type: 'test'
...
# Subtest: row 195 accept: a bad args file refuses with exit 2 before any check, each for its own reason
ok 34 - row 195 accept: a bad args file refuses with exit 2 before any check, each for its own reason
---
duration_ms: 97.36437
type: 'test'
...
# Subtest: row 195 accept: usage errors and a run without --root as a user exit 2
ok 35 - row 195 accept: usage errors and a run without --root as a user exit 2
---
duration_ms: 10.881957
type: 'test'
...
# Subtest: row 195 accept: every in-instance call goes through sudo -u mosaic -H env PATH=<node dir>:...
ok 36 - row 195 accept: every in-instance call goes through sudo -u mosaic -H env PATH=<node dir>:...
---
duration_ms: 1850.760145
type: 'test'
...
# Subtest: row 195 accept: the host check runs with --check and never --enforce
ok 37 - row 195 accept: the host check runs with --check and never --enforce
---
duration_ms: 1869.942933
type: 'test'
...
# Subtest: row276 legacy call inventory pins every production bound and the conversation contract
ok 38 - row276 legacy call inventory pins every production bound and the conversation contract
---
duration_ms: 0.366334
type: 'test'
...
# Subtest: row276 talk legacy inner timeout cleans both sudo models
ok 39 - row276 talk legacy inner timeout cleans both sudo models
---
duration_ms: 1692.158566
type: 'test'
...
# Subtest: row276 precheck legacy inner timeout cleans both sudo models
ok 40 - row276 precheck legacy inner timeout cleans both sudo models
---
duration_ms: 1720.136504
type: 'test'
...
# Subtest: row276 claude-version legacy inner timeout cleans both sudo models
ok 41 - row276 claude-version legacy inner timeout cleans both sudo models
---
duration_ms: 1702.886014
type: 'test'
...
# Subtest: row276 pm-list legacy inner timeout cleans both sudo models
ok 42 - row276 pm-list legacy inner timeout cleans both sudo models
---
duration_ms: 1710.920935
type: 'test'
...
# Subtest: row276 node-version legacy inner timeout cleans both sudo models
ok 43 - row276 node-version legacy inner timeout cleans both sudo models
---
duration_ms: 1712.683898
type: 'test'
...
# Subtest: row276 legacy streams and display status preserve failures without granting success
ok 44 - row276 legacy streams and display status preserve failures without granting success
---
duration_ms: 2671.771328
type: 'test'
...
# Subtest: row276 trailer grammar cannot make supervisor failure pass
ok 45 - row276 trailer grammar cannot make supervisor failure pass
---
duration_ms: 2089.079622
type: 'test'
...
# Subtest: row276 earlier forged trailer and appended zero remain failures
ok 46 - row276 earlier forged trailer and appended zero remain failures
---
duration_ms: 513.433074
type: 'test'
...
# Subtest: row276 precheck outer bound discards success status and fixture cleans residual
ok 47 - row276 precheck outer bound discards success status and fixture cleans residual
---
duration_ms: 2173.848153
type: 'test'
...
# Subtest: row276 case1 capture and legacy tools refuse unsafe system tools
ok 48 - row276 case1 capture and legacy tools refuse unsafe system tools
---
duration_ms: 76.5521
type: 'test'
...
# Subtest: row276 stderr retention is bounded and keeps the final diagnostic
ok 49 - row276 stderr retention is bounded and keeps the final diagnostic
---
duration_ms: 278.525167
type: 'test'
...
# Subtest: row276 version and PM checks refuse successful-looking stdout on supervisor failure
ok 50 - row276 version and PM checks refuse successful-looking stdout on supervisor failure
---
duration_ms: 15.742297
type: 'test'
...
# Subtest: row276 full acceptance keeps all five healthy calls in both sudo models
ok 51 - row276 full acceptance keeps all five healthy calls in both sudo models
---
duration_ms: 3757.894895
type: 'test'
...
# Subtest: row276 vanished pid stat read returns 3 with empty stderr in both scripts
ok 52 - row276 vanished pid stat read returns 3 with empty stderr in both scripts
---
duration_ms: 4.785932
type: 'test'
...
# Subtest: row276 legacy stdout snapshot preserves exact bytes on success and command failure
ok 53 - row276 legacy stdout snapshot preserves exact bytes on success and command failure
---
duration_ms: 3281.165451
type: 'test'
...
1..53
# tests 53
# suites 0
# pass 53
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 239100.197017
@@ -1 +0,0 @@
CLEAR
@@ -1,19 +0,0 @@
{
"label": "case1-whole-2",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gd0qwWL",
"started_utc": "2026-10-23T07:30:57Z",
"start_load": "3.41 2.47 2.22 4/6666 357541",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/case1-whole-2.log",
"expected_red": false
}
@@ -1,247 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:30:57Z",
"load": "3.41 2.47 2.22 8/6667 357542"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:31:02Z",
"load": "3.21 2.44 2.21 6/6697 360865"
},
{
"wall_seconds": 10.001,
"utc": "2026-10-23T07:31:07Z",
"load": "3.44 2.50 2.23 2/6704 364103"
},
{
"wall_seconds": 15.001,
"utc": "2026-10-23T07:31:12Z",
"load": "3.24 2.48 2.23 2/6696 367319"
},
{
"wall_seconds": 20.001,
"utc": "2026-10-23T07:31:17Z",
"load": "3.14 2.47 2.23 8/6721 370622"
},
{
"wall_seconds": 25.002,
"utc": "2026-10-23T07:31:22Z",
"load": "3.05 2.46 2.22 3/6707 373850"
},
{
"wall_seconds": 30.002,
"utc": "2026-10-23T07:31:27Z",
"load": "2.89 2.44 2.22 2/6664 377071"
},
{
"wall_seconds": 35.002,
"utc": "2026-10-23T07:31:32Z",
"load": "2.73 2.41 2.21 2/6679 380056"
},
{
"wall_seconds": 40.002,
"utc": "2026-10-23T07:31:37Z",
"load": "2.52 2.37 2.20 4/6709 384877"
},
{
"wall_seconds": 45.002,
"utc": "2026-10-23T07:31:42Z",
"load": "2.71 2.42 2.21 3/6727 386330"
},
{
"wall_seconds": 50.003,
"utc": "2026-10-23T07:31:47Z",
"load": "2.58 2.39 2.21 1/6740 387775"
},
{
"wall_seconds": 55.003,
"utc": "2026-10-23T07:31:52Z",
"load": "2.69 2.42 2.22 9/6763 389481"
},
{
"wall_seconds": 60.003,
"utc": "2026-10-23T07:31:57Z",
"load": "2.56 2.39 2.21 3/6722 390241"
},
{
"wall_seconds": 65.003,
"utc": "2026-10-23T07:32:02Z",
"load": "2.43 2.37 2.20 4/6732 391752"
},
{
"wall_seconds": 70.004,
"utc": "2026-10-23T07:32:07Z",
"load": "2.40 2.36 2.20 9/6738 395390"
},
{
"wall_seconds": 75.004,
"utc": "2026-10-23T07:32:12Z",
"load": "2.44 2.38 2.21 6/6731 398840"
},
{
"wall_seconds": 80.004,
"utc": "2026-10-23T07:32:17Z",
"load": "2.57 2.40 2.22 3/6790 402895"
},
{
"wall_seconds": 85.004,
"utc": "2026-10-23T07:32:22Z",
"load": "2.60 2.41 2.22 1/6721 405197"
},
{
"wall_seconds": 90.005,
"utc": "2026-10-23T07:32:27Z",
"load": "2.48 2.39 2.21 6/6682 407571"
},
{
"wall_seconds": 95.005,
"utc": "2026-10-23T07:32:32Z",
"load": "2.44 2.38 2.21 3/6688 408595"
},
{
"wall_seconds": 100.005,
"utc": "2026-10-23T07:32:37Z",
"load": "2.32 2.36 2.21 4/6690 411784"
},
{
"wall_seconds": 105.005,
"utc": "2026-10-23T07:32:42Z",
"load": "2.38 2.37 2.21 2/6695 414989"
},
{
"wall_seconds": 110.006,
"utc": "2026-10-23T07:32:47Z",
"load": "2.27 2.35 2.20 2/6747 418296"
},
{
"wall_seconds": 115.006,
"utc": "2026-10-23T07:32:52Z",
"load": "2.16 2.32 2.20 3/6725 421487"
},
{
"wall_seconds": 120.006,
"utc": "2026-10-23T07:32:57Z",
"load": "2.31 2.35 2.21 2/6717 424642"
},
{
"wall_seconds": 125.006,
"utc": "2026-10-23T07:33:02Z",
"load": "2.37 2.36 2.21 2/6711 427881"
},
{
"wall_seconds": 130.007,
"utc": "2026-10-23T07:33:07Z",
"load": "2.34 2.36 2.21 8/6702 431078"
},
{
"wall_seconds": 135.007,
"utc": "2026-10-23T07:33:12Z",
"load": "2.55 2.40 2.22 4/6715 434482"
},
{
"wall_seconds": 140.007,
"utc": "2026-10-23T07:33:17Z",
"load": "2.59 2.41 2.23 8/6722 437629"
},
{
"wall_seconds": 145.007,
"utc": "2026-10-23T07:33:22Z",
"load": "3.10 2.52 2.27 5/6730 441654"
},
{
"wall_seconds": 150.008,
"utc": "2026-10-23T07:33:27Z",
"load": "2.93 2.50 2.26 3/6688 445391"
},
{
"wall_seconds": 155.008,
"utc": "2026-10-23T07:33:32Z",
"load": "2.86 2.49 2.26 2/6720 449750"
},
{
"wall_seconds": 160.008,
"utc": "2026-10-23T07:33:37Z",
"load": "2.63 2.45 2.24 3/6720 454134"
},
{
"wall_seconds": 165.008,
"utc": "2026-10-23T07:33:42Z",
"load": "2.58 2.44 2.24 3/6705 458552"
},
{
"wall_seconds": 170.008,
"utc": "2026-10-23T07:33:47Z",
"load": "2.53 2.43 2.24 2/6751 462649"
},
{
"wall_seconds": 175.009,
"utc": "2026-10-23T07:33:52Z",
"load": "2.49 2.42 2.24 2/6728 466002"
},
{
"wall_seconds": 180.009,
"utc": "2026-10-23T07:33:57Z",
"load": "2.37 2.40 2.23 4/6684 469149"
},
{
"wall_seconds": 185.009,
"utc": "2026-10-23T07:34:02Z",
"load": "2.50 2.43 2.24 10/6506 472229"
},
{
"wall_seconds": 190.009,
"utc": "2026-10-23T07:34:07Z",
"load": "2.78 2.49 2.26 3/6479 475928"
},
{
"wall_seconds": 195.01,
"utc": "2026-10-23T07:34:12Z",
"load": "2.64 2.46 2.26 3/6479 479085"
},
{
"wall_seconds": 200.01,
"utc": "2026-10-23T07:34:17Z",
"load": "2.51 2.44 2.25 3/6502 482380"
},
{
"wall_seconds": 205.01,
"utc": "2026-10-23T07:34:22Z",
"load": "2.63 2.46 2.26 4/6485 486156"
},
{
"wall_seconds": 210.01,
"utc": "2026-10-23T07:34:27Z",
"load": "2.50 2.44 2.25 2/6457 489465"
},
{
"wall_seconds": 215.011,
"utc": "2026-10-23T07:34:32Z",
"load": "2.38 2.41 2.25 2/6462 492613"
},
{
"wall_seconds": 220.011,
"utc": "2026-10-23T07:34:37Z",
"load": "2.27 2.39 2.24 2/6495 494796"
},
{
"wall_seconds": 225.011,
"utc": "2026-10-23T07:34:42Z",
"load": "2.08 2.35 2.23 1/6512 496267"
},
{
"wall_seconds": 230.011,
"utc": "2026-10-23T07:34:47Z",
"load": "2.00 2.33 2.22 2/6527 499579"
},
{
"wall_seconds": 235.012,
"utc": "2026-10-23T07:34:52Z",
"load": "2.00 2.32 2.22 2/6514 502183"
},
{
"wall_seconds": 240.012,
"utc": "2026-10-23T07:34:57Z",
"load": "2.00 2.32 2.22 8/6467 505173"
}
]
@@ -1,332 +0,0 @@
TAP version 13
# Subtest: row253 socket observation uses configured root, metadata and the Console peer without sending bytes
ok 1 - row253 socket observation uses configured root, metadata and the Console peer without sending bytes
---
duration_ms: 1878.940051
type: 'test'
...
# Subtest: row253 P10 refuses unsafe metadata, wrong peers and an unsafe Python without claiming closure
ok 2 - row253 P10 refuses unsafe metadata, wrong peers and an unsafe Python without claiming closure
---
duration_ms: 29659.298682
type: 'test'
...
# Subtest: row253 acceptance rejects bad config and unsupported copies before talk
ok 3 - row253 acceptance rejects bad config and unsupported copies before talk
---
duration_ms: 1402.898543
type: 'test'
...
# Subtest: row253 stalled peer observation ends within its bound without leaving a reader
ok 4 - row253 stalled peer observation ends within its bound without leaving a reader
---
duration_ms: 3999.716359
type: 'test'
...
# Subtest: row253 P8 refuses both retired TCP and board listeners
ok 5 - row253 P8 refuses both retired TCP and board listeners
---
duration_ms: 3772.509207
type: 'test'
...
# Subtest: row253 C4 acceptance query inner reason holds under both sudo models
ok 6 - row253 C4 acceptance query inner reason holds under both sudo models
---
duration_ms: 10718.848845
type: 'test'
...
# Subtest: row253 C4 acceptance query outer reason discards stdout and names residual cleanup
ok 7 - row253 C4 acceptance query outer reason discards stdout and names residual cleanup
---
duration_ms: 14188.226585
type: 'test'
...
# Subtest: row253 C4 acceptance query overflow is output-limit in both models
ok 8 - row253 C4 acceptance query overflow is output-limit in both models
---
duration_ms: 508.639752
type: 'test'
...
# Subtest: row299 P10 timing copy preserves shipped bytes and isolates observer variables
ok 9 - row299 P10 timing copy preserves shipped bytes and isolates observer variables
---
duration_ms: 0.798822
type: 'test'
...
# Subtest: row299 P10 observers preserve stdout stderr status and the EXIT trap
ok 10 - row299 P10 observers preserve stdout stderr status and the EXIT trap
---
duration_ms: 3.117025
type: 'test'
...
# Subtest: row299 P10 observer records are complete and ordered
ok 11 - row299 P10 observer records are complete and ordered
---
duration_ms: 0.531705
type: 'test'
...
# Subtest: row253 C4 P10 inner reason holds under both sudo models
ok 12 - row253 C4 P10 inner reason holds under both sudo models
---
duration_ms: 12501.629468
type: 'test'
...
# {"fault":"inner","mode":"exec","baselineSeconds":1.9894229939999932,"faultSeconds":4.213512103000001,"probeSeconds":2.29}
# {"fault":"inner","mode":"hop","baselineSeconds":2.056171266999998,"faultSeconds":4.169351735999997,"probeSeconds":2.28}
# Subtest: row253 C4 P10 outer reason holds under both sudo models
ok 13 - row253 C4 P10 outer reason holds under both sudo models
---
duration_ms: 15355.835698
type: 'test'
...
# {"fault":"outer","mode":"exec","baselineSeconds":1.9589971570000053,"faultSeconds":5.726783651999998,"probeSeconds":4}
# {"fault":"outer","mode":"hop","baselineSeconds":1.879084925999996,"faultSeconds":5.732443853999998,"probeSeconds":4.01}
# Subtest: row253 C4 P10 overflow reason holds under both sudo models
ok 14 - row253 C4 P10 overflow reason holds under both sudo models
---
duration_ms: 3793.194421
type: 'test'
...
# Subtest: row 195 accept: every check passing exits 0, with each P mark and counts that match the lines
ok 15 - row 195 accept: every check passing exits 0, with each P mark and counts that match the lines
---
duration_ms: 1868.627362
type: 'test'
...
# Subtest: row 195 accept: exits 1 with each F check failing alone, and its line names it
ok 16 - row 195 accept: exits 1 with each F check failing alone, and its line names it
---
duration_ms: 21072.838361
type: 'test'
...
# Subtest: row 195 accept: F3 fails on exit 0 with no reply line, and its evidence takes talk's error
ok 17 - row 195 accept: F3 fails on exit 0 with no reply line, and its evidence takes talk's error
---
duration_ms: 3708.467117
type: 'test'
...
# Subtest: row 195 accept: F1 fails on a unit that isn't active or isn't User=mosaic
ok 18 - row 195 accept: F1 fails on a unit that isn't active or isn't User=mosaic
---
duration_ms: 3517.599317
type: 'test'
...
# Subtest: row 195 accept: F2 fails when healthz doesn't answer and when another pid holds the port
ok 19 - row 195 accept: F2 fails when healthz doesn't answer and when another pid holds the port
---
duration_ms: 4025.946308
type: 'test'
...
# Subtest: row 195 accept: F5 fails on unpriv_bwrap (enforce), on complain and on a trailing space
ok 20 - row 195 accept: F5 fails on unpriv_bwrap (enforce), on complain and on a trailing space
---
duration_ms: 8845.119954
type: 'test'
...
# Subtest: row 195 accept: F5 fails with no bwrap of mosaic's, and passes on comm alone
ok 21 - row 195 accept: F5 fails with no bwrap of mosaic's, and passes on comm alone
---
duration_ms: 4126.5763
type: 'test'
...
# Subtest: row 195 accept: F6 fails on a stub that prints nothing, on a path outside claude-<pin> and on a .. segment
ok 22 - row 195 accept: F6 fails on a stub that prints nothing, on a path outside claude-<pin> and on a .. segment
---
duration_ms: 5137.178557
type: 'test'
...
# Subtest: row 195 accept: F7 fails on two live PM launches, one for another business, and no launch.by
ok 23 - row 195 accept: F7 fails on two live PM launches, one for another business, and no launch.by
---
duration_ms: 5691.366549
type: 'test'
...
# Subtest: row 195 accept: F8 fails on 0640, on another owner and on a symlink, and never prints the credential
ok 24 - row 195 accept: F8 fails on 0640, on another owner and on a symlink, and never prints the credential
---
duration_ms: 5730.966972
type: 'test'
...
# Subtest: row 195 accept: F9 fails on another owner, a group-writable mode and a number for the flag
ok 25 - row 195 accept: F9 fails on another owner, a group-writable mode and a number for the flag
---
duration_ms: 5621.584201
type: 'test'
...
# Subtest: row 195 accept: F9 won't run --node as root off the pin path or with a writable directory above it
ok 26 - row 195 accept: F9 won't run --node as root off the pin path or with a writable directory above it
---
duration_ms: 5316.258522
type: 'test'
...
# Subtest: row 195 accept: F11 fails on one *.json under discord/ and passes on an empty directory
ok 27 - row 195 accept: F11 fails on one *.json under discord/ and passes on an empty directory
---
duration_ms: 3764.13795
type: 'test'
...
# Subtest: row 195 accept: each P check reports unnamed on its fault, and the exit stays 0
ok 28 - row 195 accept: each P check reports unnamed on its fault, and the exit stays 0
---
duration_ms: 16622.156132
type: 'test'
...
# Subtest: row 195 accept: P2 is unnamed with a supplementary group, and P5 names docker
ok 29 - row 195 accept: P2 is unnamed with a supplementary group, and P5 names docker
---
duration_ms: 3681.147919
type: 'test'
...
# Subtest: row 195 accept: P5 is closed with no jarvis account, and P2 with an empty authorized_keys
ok 30 - row 195 accept: P5 is closed with no jarvis account, and P2 with an empty authorized_keys
---
duration_ms: 1837.622854
type: 'test'
...
# Subtest: row 195 accept: P9 is unnamed once for each item missing
ok 31 - row 195 accept: P9 is unnamed once for each item missing
---
duration_ms: 9351.705376
type: 'test'
...
# Subtest: row253 accept: P10 fails its observation with another peer; P11 with the unit disabled
ok 32 - row253 accept: P10 fails its observation with another peer; P11 with the unit disabled
---
duration_ms: 3724.049411
type: 'test'
...
# Subtest: row 195 accept: every P check unnamed together still exits 0
ok 33 - row 195 accept: every P check unnamed together still exits 0
---
duration_ms: 1644.081467
type: 'test'
...
# Subtest: row 195 accept: a bad args file refuses with exit 2 before any check, each for its own reason
ok 34 - row 195 accept: a bad args file refuses with exit 2 before any check, each for its own reason
---
duration_ms: 93.429959
type: 'test'
...
# Subtest: row 195 accept: usage errors and a run without --root as a user exit 2
ok 35 - row 195 accept: usage errors and a run without --root as a user exit 2
---
duration_ms: 10.484275
type: 'test'
...
# Subtest: row 195 accept: every in-instance call goes through sudo -u mosaic -H env PATH=<node dir>:...
ok 36 - row 195 accept: every in-instance call goes through sudo -u mosaic -H env PATH=<node dir>:...
---
duration_ms: 1850.954185
type: 'test'
...
# Subtest: row 195 accept: the host check runs with --check and never --enforce
ok 37 - row 195 accept: the host check runs with --check and never --enforce
---
duration_ms: 1829.605146
type: 'test'
...
# Subtest: row276 legacy call inventory pins every production bound and the conversation contract
ok 38 - row276 legacy call inventory pins every production bound and the conversation contract
---
duration_ms: 0.390713
type: 'test'
...
# Subtest: row276 talk legacy inner timeout cleans both sudo models
ok 39 - row276 talk legacy inner timeout cleans both sudo models
---
duration_ms: 1671.508097
type: 'test'
...
# Subtest: row276 precheck legacy inner timeout cleans both sudo models
ok 40 - row276 precheck legacy inner timeout cleans both sudo models
---
duration_ms: 1671.245175
type: 'test'
...
# Subtest: row276 claude-version legacy inner timeout cleans both sudo models
ok 41 - row276 claude-version legacy inner timeout cleans both sudo models
---
duration_ms: 1675.495392
type: 'test'
...
# Subtest: row276 pm-list legacy inner timeout cleans both sudo models
ok 42 - row276 pm-list legacy inner timeout cleans both sudo models
---
duration_ms: 1661.382885
type: 'test'
...
# Subtest: row276 node-version legacy inner timeout cleans both sudo models
ok 43 - row276 node-version legacy inner timeout cleans both sudo models
---
duration_ms: 1692.3437
type: 'test'
...
# Subtest: row276 legacy streams and display status preserve failures without granting success
ok 44 - row276 legacy streams and display status preserve failures without granting success
---
duration_ms: 2545.7498
type: 'test'
...
# Subtest: row276 trailer grammar cannot make supervisor failure pass
ok 45 - row276 trailer grammar cannot make supervisor failure pass
---
duration_ms: 2097.946825
type: 'test'
...
# Subtest: row276 earlier forged trailer and appended zero remain failures
ok 46 - row276 earlier forged trailer and appended zero remain failures
---
duration_ms: 521.451262
type: 'test'
...
# Subtest: row276 precheck outer bound discards success status and fixture cleans residual
ok 47 - row276 precheck outer bound discards success status and fixture cleans residual
---
duration_ms: 2170.592563
type: 'test'
...
# Subtest: row276 case1 capture and legacy tools refuse unsafe system tools
ok 48 - row276 case1 capture and legacy tools refuse unsafe system tools
---
duration_ms: 76.678871
type: 'test'
...
# Subtest: row276 stderr retention is bounded and keeps the final diagnostic
ok 49 - row276 stderr retention is bounded and keeps the final diagnostic
---
duration_ms: 261.872028
type: 'test'
...
# Subtest: row276 version and PM checks refuse successful-looking stdout on supervisor failure
ok 50 - row276 version and PM checks refuse successful-looking stdout on supervisor failure
---
duration_ms: 16.458898
type: 'test'
...
# Subtest: row276 full acceptance keeps all five healthy calls in both sudo models
ok 51 - row276 full acceptance keeps all five healthy calls in both sudo models
---
duration_ms: 3762.37926
type: 'test'
...
# Subtest: row276 vanished pid stat read returns 3 with empty stderr in both scripts
ok 52 - row276 vanished pid stat read returns 3 with empty stderr in both scripts
---
duration_ms: 4.628196
type: 'test'
...
# Subtest: row276 legacy stdout snapshot preserves exact bytes on success and command failure
ok 53 - row276 legacy stdout snapshot preserves exact bytes on success and command failure
---
duration_ms: 3223.67506
type: 'test'
...
1..53
# tests 53
# suites 0
# pass 53
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 240011.017536
@@ -1,3 +0,0 @@
CLEAR
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/445652/cmdline: No such file or directory
/mnt/storage/scratch/sage-busy-now.sh: line 4: /proc/505165/cmdline: No such file or directory
@@ -1,19 +0,0 @@
{
"label": "case1-whole-3",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gdjuph7",
"started_utc": "2026-10-23T07:34:59Z",
"start_load": "2.08 2.33 2.22 4/6464 509071",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/case1-whole-3.log",
"expected_red": false
}
@@ -1,237 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:34:59Z",
"load": "2.08 2.33 2.22 8/6465 509072"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:35:04Z",
"load": "2.23 2.36 2.23 4/6481 514861"
},
{
"wall_seconds": 10.001,
"utc": "2026-10-23T07:35:09Z",
"load": "2.13 2.33 2.22 3/6475 518876"
},
{
"wall_seconds": 15.001,
"utc": "2026-10-23T07:35:14Z",
"load": "2.04 2.31 2.22 3/6502 522276"
},
{
"wall_seconds": 20.001,
"utc": "2026-10-23T07:35:19Z",
"load": "2.04 2.31 2.22 3/6502 525490"
},
{
"wall_seconds": 25.001,
"utc": "2026-10-23T07:35:24Z",
"load": "2.04 2.30 2.21 5/6478 528962"
},
{
"wall_seconds": 30.002,
"utc": "2026-10-23T07:35:29Z",
"load": "2.03 2.30 2.21 3/6458 532409"
},
{
"wall_seconds": 35.002,
"utc": "2026-10-23T07:35:34Z",
"load": "2.03 2.29 2.21 2/6481 535342"
},
{
"wall_seconds": 40.002,
"utc": "2026-10-23T07:35:39Z",
"load": "2.03 2.29 2.21 3/6483 537759"
},
{
"wall_seconds": 45.002,
"utc": "2026-10-23T07:35:44Z",
"load": "1.86 2.25 2.20 5/6511 539004"
},
{
"wall_seconds": 50.003,
"utc": "2026-10-23T07:35:49Z",
"load": "1.72 2.21 2.19 2/6524 540002"
},
{
"wall_seconds": 55.003,
"utc": "2026-10-23T07:35:54Z",
"load": "1.58 2.17 2.17 2/6482 540672"
},
{
"wall_seconds": 60.003,
"utc": "2026-10-23T07:35:59Z",
"load": "1.53 2.15 2.17 4/6471 541194"
},
{
"wall_seconds": 65.003,
"utc": "2026-10-23T07:36:04Z",
"load": "1.81 2.20 2.18 2/6474 541568"
},
{
"wall_seconds": 70.003,
"utc": "2026-10-23T07:36:09Z",
"load": "2.31 2.30 2.21 4/6503 545391"
},
{
"wall_seconds": 75.004,
"utc": "2026-10-23T07:36:14Z",
"load": "2.28 2.29 2.21 4/6517 548112"
},
{
"wall_seconds": 80.004,
"utc": "2026-10-23T07:36:19Z",
"load": "2.42 2.32 2.22 3/6526 551314"
},
{
"wall_seconds": 85.004,
"utc": "2026-10-23T07:36:24Z",
"load": "2.38 2.31 2.22 23/6474 553438"
},
{
"wall_seconds": 90.004,
"utc": "2026-10-23T07:36:29Z",
"load": "2.27 2.29 2.21 3/6475 556781"
},
{
"wall_seconds": 95.005,
"utc": "2026-10-23T07:36:34Z",
"load": "2.25 2.29 2.21 4/6460 559513"
},
{
"wall_seconds": 100.005,
"utc": "2026-10-23T07:36:39Z",
"load": "2.79 2.40 2.25 4/6488 566252"
},
{
"wall_seconds": 105.005,
"utc": "2026-10-23T07:36:44Z",
"load": "2.81 2.41 2.25 4/6480 569779"
},
{
"wall_seconds": 110.005,
"utc": "2026-10-23T07:36:49Z",
"load": "2.66 2.39 2.25 3/6489 572874"
},
{
"wall_seconds": 115.006,
"utc": "2026-10-23T07:36:54Z",
"load": "2.61 2.38 2.25 3/6447 576109"
},
{
"wall_seconds": 120.006,
"utc": "2026-10-23T07:36:59Z",
"load": "2.64 2.39 2.25 3/6433 579360"
},
{
"wall_seconds": 125.006,
"utc": "2026-10-23T07:37:04Z",
"load": "2.59 2.38 2.25 6/6448 582606"
},
{
"wall_seconds": 130.006,
"utc": "2026-10-23T07:37:09Z",
"load": "2.54 2.38 2.25 5/6451 585750"
},
{
"wall_seconds": 135.006,
"utc": "2026-10-23T07:37:14Z",
"load": "2.42 2.35 2.24 3/6464 588554"
},
{
"wall_seconds": 140.007,
"utc": "2026-10-23T07:37:19Z",
"load": "2.31 2.33 2.23 5/6469 591375"
},
{
"wall_seconds": 145.007,
"utc": "2026-10-23T07:37:24Z",
"load": "2.20 2.31 2.23 3/6436 594632"
},
{
"wall_seconds": 150.007,
"utc": "2026-10-23T07:37:29Z",
"load": "2.10 2.29 2.22 4/6408 597793"
},
{
"wall_seconds": 155.007,
"utc": "2026-10-23T07:37:34Z",
"load": "2.02 2.27 2.21 6/6423 601114"
},
{
"wall_seconds": 160.008,
"utc": "2026-10-23T07:37:39Z",
"load": "1.93 2.24 2.21 5/6420 604470"
},
{
"wall_seconds": 165.008,
"utc": "2026-10-23T07:37:44Z",
"load": "1.86 2.22 2.20 4/6456 608664"
},
{
"wall_seconds": 170.008,
"utc": "2026-10-23T07:37:49Z",
"load": "1.87 2.22 2.20 4/6455 612187"
},
{
"wall_seconds": 175.008,
"utc": "2026-10-23T07:37:54Z",
"load": "2.04 2.25 2.21 4/6441 616556"
},
{
"wall_seconds": 180.009,
"utc": "2026-10-23T07:37:59Z",
"load": "2.36 2.31 2.23 5/6417 620859"
},
{
"wall_seconds": 185.009,
"utc": "2026-10-23T07:38:04Z",
"load": "2.25 2.29 2.22 4/6428 625167"
},
{
"wall_seconds": 190.009,
"utc": "2026-10-23T07:38:09Z",
"load": "2.15 2.27 2.21 3/6424 629560"
},
{
"wall_seconds": 195.009,
"utc": "2026-10-23T07:38:14Z",
"load": "2.06 2.25 2.21 3/6441 632894"
},
{
"wall_seconds": 200.009,
"utc": "2026-10-23T07:38:19Z",
"load": "1.97 2.22 2.20 4/6447 636095"
},
{
"wall_seconds": 205.01,
"utc": "2026-10-23T07:38:24Z",
"load": "1.97 2.22 2.20 3/6421 639217"
},
{
"wall_seconds": 210.01,
"utc": "2026-10-23T07:38:29Z",
"load": "2.06 2.23 2.20 3/6413 642341"
},
{
"wall_seconds": 215.01,
"utc": "2026-10-23T07:38:34Z",
"load": "1.89 2.20 2.19 2/6452 644528"
},
{
"wall_seconds": 220.01,
"utc": "2026-10-23T07:38:39Z",
"load": "1.98 2.21 2.20 5/6458 646052"
},
{
"wall_seconds": 225.011,
"utc": "2026-10-23T07:38:44Z",
"load": "1.90 2.19 2.19 3/6453 648762"
},
{
"wall_seconds": 230.011,
"utc": "2026-10-23T07:38:49Z",
"load": "1.99 2.20 2.19 3/6456 650851"
}
]
@@ -1,332 +0,0 @@
TAP version 13
# Subtest: row253 socket observation uses configured root, metadata and the Console peer without sending bytes
ok 1 - row253 socket observation uses configured root, metadata and the Console peer without sending bytes
---
duration_ms: 1953.256427
type: 'test'
...
# Subtest: row253 P10 refuses unsafe metadata, wrong peers and an unsafe Python without claiming closure
ok 2 - row253 P10 refuses unsafe metadata, wrong peers and an unsafe Python without claiming closure
---
duration_ms: 29343.328577
type: 'test'
...
# Subtest: row253 acceptance rejects bad config and unsupported copies before talk
ok 3 - row253 acceptance rejects bad config and unsupported copies before talk
---
duration_ms: 1354.971037
type: 'test'
...
# Subtest: row253 stalled peer observation ends within its bound without leaving a reader
ok 4 - row253 stalled peer observation ends within its bound without leaving a reader
---
duration_ms: 3964.438002
type: 'test'
...
# Subtest: row253 P8 refuses both retired TCP and board listeners
ok 5 - row253 P8 refuses both retired TCP and board listeners
---
duration_ms: 3689.613255
type: 'test'
...
# Subtest: row253 C4 acceptance query inner reason holds under both sudo models
ok 6 - row253 C4 acceptance query inner reason holds under both sudo models
---
duration_ms: 10712.630086
type: 'test'
...
# Subtest: row253 C4 acceptance query outer reason discards stdout and names residual cleanup
ok 7 - row253 C4 acceptance query outer reason discards stdout and names residual cleanup
---
duration_ms: 14177.055814
type: 'test'
...
# Subtest: row253 C4 acceptance query overflow is output-limit in both models
ok 8 - row253 C4 acceptance query overflow is output-limit in both models
---
duration_ms: 492.274319
type: 'test'
...
# Subtest: row299 P10 timing copy preserves shipped bytes and isolates observer variables
ok 9 - row299 P10 timing copy preserves shipped bytes and isolates observer variables
---
duration_ms: 0.683633
type: 'test'
...
# Subtest: row299 P10 observers preserve stdout stderr status and the EXIT trap
ok 10 - row299 P10 observers preserve stdout stderr status and the EXIT trap
---
duration_ms: 3.307686
type: 'test'
...
# Subtest: row299 P10 observer records are complete and ordered
ok 11 - row299 P10 observer records are complete and ordered
---
duration_ms: 0.539265
type: 'test'
...
# Subtest: row253 C4 P10 inner reason holds under both sudo models
ok 12 - row253 C4 P10 inner reason holds under both sudo models
---
duration_ms: 11734.519359
type: 'test'
...
# {"fault":"inner","mode":"exec","baselineSeconds":1.8627637730000133,"faultSeconds":3.9948855329999935,"probeSeconds":2.25}
# {"fault":"inner","mode":"hop","baselineSeconds":1.8459824050000024,"faultSeconds":3.963717149000004,"probeSeconds":2.26}
# Subtest: row253 C4 P10 outer reason holds under both sudo models
ok 13 - row253 C4 P10 outer reason holds under both sudo models
---
duration_ms: 15259.754291
type: 'test'
...
# {"fault":"outer","mode":"exec","baselineSeconds":1.8736066859999991,"faultSeconds":5.7249899409999925,"probeSeconds":4}
# {"fault":"outer","mode":"hop","baselineSeconds":1.8894593350000068,"faultSeconds":5.709737833999999,"probeSeconds":4}
# Subtest: row253 C4 P10 overflow reason holds under both sudo models
ok 14 - row253 C4 P10 overflow reason holds under both sudo models
---
duration_ms: 3822.763403
type: 'test'
...
# Subtest: row 195 accept: every check passing exits 0, with each P mark and counts that match the lines
ok 15 - row 195 accept: every check passing exits 0, with each P mark and counts that match the lines
---
duration_ms: 1879.591109
type: 'test'
...
# Subtest: row 195 accept: exits 1 with each F check failing alone, and its line names it
ok 16 - row 195 accept: exits 1 with each F check failing alone, and its line names it
---
duration_ms: 20490.628667
type: 'test'
...
# Subtest: row 195 accept: F3 fails on exit 0 with no reply line, and its evidence takes talk's error
ok 17 - row 195 accept: F3 fails on exit 0 with no reply line, and its evidence takes talk's error
---
duration_ms: 3653.736213
type: 'test'
...
# Subtest: row 195 accept: F1 fails on a unit that isn't active or isn't User=mosaic
ok 18 - row 195 accept: F1 fails on a unit that isn't active or isn't User=mosaic
---
duration_ms: 3442.442361
type: 'test'
...
# Subtest: row 195 accept: F2 fails when healthz doesn't answer and when another pid holds the port
ok 19 - row 195 accept: F2 fails when healthz doesn't answer and when another pid holds the port
---
duration_ms: 3683.514446
type: 'test'
...
# Subtest: row 195 accept: F5 fails on unpriv_bwrap (enforce), on complain and on a trailing space
ok 20 - row 195 accept: F5 fails on unpriv_bwrap (enforce), on complain and on a trailing space
---
duration_ms: 8437.165336
type: 'test'
...
# Subtest: row 195 accept: F5 fails with no bwrap of mosaic's, and passes on comm alone
ok 21 - row 195 accept: F5 fails with no bwrap of mosaic's, and passes on comm alone
---
duration_ms: 3900.598202
type: 'test'
...
# Subtest: row 195 accept: F6 fails on a stub that prints nothing, on a path outside claude-<pin> and on a .. segment
ok 22 - row 195 accept: F6 fails on a stub that prints nothing, on a path outside claude-<pin> and on a .. segment
---
duration_ms: 4987.50038
type: 'test'
...
# Subtest: row 195 accept: F7 fails on two live PM launches, one for another business, and no launch.by
ok 23 - row 195 accept: F7 fails on two live PM launches, one for another business, and no launch.by
---
duration_ms: 5425.289834
type: 'test'
...
# Subtest: row 195 accept: F8 fails on 0640, on another owner and on a symlink, and never prints the credential
ok 24 - row 195 accept: F8 fails on 0640, on another owner and on a symlink, and never prints the credential
---
duration_ms: 5477.40542
type: 'test'
...
# Subtest: row 195 accept: F9 fails on another owner, a group-writable mode and a number for the flag
ok 25 - row 195 accept: F9 fails on another owner, a group-writable mode and a number for the flag
---
duration_ms: 5434.786414
type: 'test'
...
# Subtest: row 195 accept: F9 won't run --node as root off the pin path or with a writable directory above it
ok 26 - row 195 accept: F9 won't run --node as root off the pin path or with a writable directory above it
---
duration_ms: 5126.262984
type: 'test'
...
# Subtest: row 195 accept: F11 fails on one *.json under discord/ and passes on an empty directory
ok 27 - row 195 accept: F11 fails on one *.json under discord/ and passes on an empty directory
---
duration_ms: 3711.251951
type: 'test'
...
# Subtest: row 195 accept: each P check reports unnamed on its fault, and the exit stays 0
ok 28 - row 195 accept: each P check reports unnamed on its fault, and the exit stays 0
---
duration_ms: 16470.538016
type: 'test'
...
# Subtest: row 195 accept: P2 is unnamed with a supplementary group, and P5 names docker
ok 29 - row 195 accept: P2 is unnamed with a supplementary group, and P5 names docker
---
duration_ms: 3660.364965
type: 'test'
...
# Subtest: row 195 accept: P5 is closed with no jarvis account, and P2 with an empty authorized_keys
ok 30 - row 195 accept: P5 is closed with no jarvis account, and P2 with an empty authorized_keys
---
duration_ms: 1799.768335
type: 'test'
...
# Subtest: row 195 accept: P9 is unnamed once for each item missing
ok 31 - row 195 accept: P9 is unnamed once for each item missing
---
duration_ms: 9047.041702
type: 'test'
...
# Subtest: row253 accept: P10 fails its observation with another peer; P11 with the unit disabled
ok 32 - row253 accept: P10 fails its observation with another peer; P11 with the unit disabled
---
duration_ms: 3624.70672
type: 'test'
...
# Subtest: row 195 accept: every P check unnamed together still exits 0
ok 33 - row 195 accept: every P check unnamed together still exits 0
---
duration_ms: 1628.049695
type: 'test'
...
# Subtest: row 195 accept: a bad args file refuses with exit 2 before any check, each for its own reason
ok 34 - row 195 accept: a bad args file refuses with exit 2 before any check, each for its own reason
---
duration_ms: 96.211247
type: 'test'
...
# Subtest: row 195 accept: usage errors and a run without --root as a user exit 2
ok 35 - row 195 accept: usage errors and a run without --root as a user exit 2
---
duration_ms: 11.078071
type: 'test'
...
# Subtest: row 195 accept: every in-instance call goes through sudo -u mosaic -H env PATH=<node dir>:...
ok 36 - row 195 accept: every in-instance call goes through sudo -u mosaic -H env PATH=<node dir>:...
---
duration_ms: 1819.893166
type: 'test'
...
# Subtest: row 195 accept: the host check runs with --check and never --enforce
ok 37 - row 195 accept: the host check runs with --check and never --enforce
---
duration_ms: 1818.576075
type: 'test'
...
# Subtest: row276 legacy call inventory pins every production bound and the conversation contract
ok 38 - row276 legacy call inventory pins every production bound and the conversation contract
---
duration_ms: 0.367599
type: 'test'
...
# Subtest: row276 talk legacy inner timeout cleans both sudo models
ok 39 - row276 talk legacy inner timeout cleans both sudo models
---
duration_ms: 1643.944453
type: 'test'
...
# Subtest: row276 precheck legacy inner timeout cleans both sudo models
ok 40 - row276 precheck legacy inner timeout cleans both sudo models
---
duration_ms: 1647.187165
type: 'test'
...
# Subtest: row276 claude-version legacy inner timeout cleans both sudo models
ok 41 - row276 claude-version legacy inner timeout cleans both sudo models
---
duration_ms: 1658.311785
type: 'test'
...
# Subtest: row276 pm-list legacy inner timeout cleans both sudo models
ok 42 - row276 pm-list legacy inner timeout cleans both sudo models
---
duration_ms: 1662.34616
type: 'test'
...
# Subtest: row276 node-version legacy inner timeout cleans both sudo models
ok 43 - row276 node-version legacy inner timeout cleans both sudo models
---
duration_ms: 1691.506329
type: 'test'
...
# Subtest: row276 legacy streams and display status preserve failures without granting success
ok 44 - row276 legacy streams and display status preserve failures without granting success
---
duration_ms: 2558.787354
type: 'test'
...
# Subtest: row276 trailer grammar cannot make supervisor failure pass
ok 45 - row276 trailer grammar cannot make supervisor failure pass
---
duration_ms: 1998.18351
type: 'test'
...
# Subtest: row276 earlier forged trailer and appended zero remain failures
ok 46 - row276 earlier forged trailer and appended zero remain failures
---
duration_ms: 502.525144
type: 'test'
...
# Subtest: row276 precheck outer bound discards success status and fixture cleans residual
ok 47 - row276 precheck outer bound discards success status and fixture cleans residual
---
duration_ms: 2166.851271
type: 'test'
...
# Subtest: row276 case1 capture and legacy tools refuse unsafe system tools
ok 48 - row276 case1 capture and legacy tools refuse unsafe system tools
---
duration_ms: 74.697527
type: 'test'
...
# Subtest: row276 stderr retention is bounded and keeps the final diagnostic
ok 49 - row276 stderr retention is bounded and keeps the final diagnostic
---
duration_ms: 241.007102
type: 'test'
...
# Subtest: row276 version and PM checks refuse successful-looking stdout on supervisor failure
ok 50 - row276 version and PM checks refuse successful-looking stdout on supervisor failure
---
duration_ms: 16.132196
type: 'test'
...
# Subtest: row276 full acceptance keeps all five healthy calls in both sudo models
ok 51 - row276 full acceptance keeps all five healthy calls in both sudo models
---
duration_ms: 3685.474118
type: 'test'
...
# Subtest: row276 vanished pid stat read returns 3 with empty stderr in both scripts
ok 52 - row276 vanished pid stat read returns 3 with empty stderr in both scripts
---
duration_ms: 4.365639
type: 'test'
...
# Subtest: row276 legacy stdout snapshot preserves exact bytes on success and command failure
ok 53 - row276 legacy stdout snapshot preserves exact bytes on success and command failure
---
duration_ms: 3188.820303
type: 'test'
...
1..53
# tests 53
# suites 0
# pass 53
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 234980.293151
@@ -1 +0,0 @@
CLEAR
@@ -1,77 +0,0 @@
{
"label": "cli-whole",
"argv": [
"timeout",
"-k",
"10",
"5400",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/access-boot.test.mjs",
"packages/cli/tests/access.test.mjs",
"packages/cli/tests/app.test.mjs",
"packages/cli/tests/boot-status.test.mjs",
"packages/cli/tests/case1-accept.test.mjs",
"packages/cli/tests/case1-hostcheck.test.mjs",
"packages/cli/tests/case2-persona-import.test.mjs",
"packages/cli/tests/case2-unit.test.mjs",
"packages/cli/tests/channel-cli.test.mjs",
"packages/cli/tests/channel-recovery.test.mjs",
"packages/cli/tests/cli.test.mjs",
"packages/cli/tests/compactions-launch.test.mjs",
"packages/cli/tests/config.test.mjs",
"packages/cli/tests/credentials.test.mjs",
"packages/cli/tests/follow.test.mjs",
"packages/cli/tests/format.test.mjs",
"packages/cli/tests/gate-lane-auth.test.mjs",
"packages/cli/tests/gate-lane-fixtures.test.mjs",
"packages/cli/tests/gate-lane-image.test.mjs",
"packages/cli/tests/gate-lane-state.test.mjs",
"packages/cli/tests/gate-lane.test.mjs",
"packages/cli/tests/git-socket.test.mjs",
"packages/cli/tests/grants.test.mjs",
"packages/cli/tests/host.test.mjs",
"packages/cli/tests/hosts.test.mjs",
"packages/cli/tests/instances.test.mjs",
"packages/cli/tests/launch-account.test.mjs",
"packages/cli/tests/launch-limit-checks.test.mjs",
"packages/cli/tests/launch-limits.test.mjs",
"packages/cli/tests/launch-routes.test.mjs",
"packages/cli/tests/launcher.test.mjs",
"packages/cli/tests/lifecycle.test.mjs",
"packages/cli/tests/limits-tokens.test.mjs",
"packages/cli/tests/limits.test.mjs",
"packages/cli/tests/mark-read.test.mjs",
"packages/cli/tests/names.test.mjs",
"packages/cli/tests/notifier.test.mjs",
"packages/cli/tests/other-tree.test.mjs",
"packages/cli/tests/processing-cli.test.mjs",
"packages/cli/tests/project-name-repo.test.mjs",
"packages/cli/tests/project.test.mjs",
"packages/cli/tests/publish-socket.test.mjs",
"packages/cli/tests/session-clear.test.mjs",
"packages/cli/tests/session-launch.test.mjs",
"packages/cli/tests/stack-copy.test.mjs",
"packages/cli/tests/stack-instances.test.mjs",
"packages/cli/tests/stack-release-external.test.mjs",
"packages/cli/tests/stack-release.test.mjs",
"packages/cli/tests/stack-upgrade.test.mjs",
"packages/cli/tests/tester-http.test.mjs",
"packages/cli/tests/tester-reads.test.mjs",
"packages/cli/tests/tester-threads.test.mjs",
"packages/cli/tests/tester.test.mjs",
"packages/cli/tests/thread-cli.test.mjs",
"packages/cli/tests/thread-launch.test.mjs",
"packages/cli/tests/trackers-boot.test.mjs",
"packages/cli/tests/transport.test.mjs",
"packages/cli/tests/usage.test.mjs",
"packages/cli/tests/verbs.test.mjs"
],
"limit_seconds": 5400,
"tmpdir": "/mnt/storage/scratch/tmp/gebsaIr",
"started_utc": "2026-10-23T07:38:55Z",
"start_load": "1.91 2.18 2.19 1/6404 656161",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/cli-whole.log",
"expected_red": false
}
@@ -1,637 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:38:55Z",
"load": "1.91 2.18 2.19 4/6405 656162"
},
{
"wall_seconds": 5.001,
"utc": "2026-10-23T07:39:00Z",
"load": "3.52 2.51 2.29 20/6571 665258"
},
{
"wall_seconds": 10.001,
"utc": "2026-10-23T07:39:05Z",
"load": "4.36 2.70 2.36 17/6696 672370"
},
{
"wall_seconds": 15.001,
"utc": "2026-10-23T07:39:10Z",
"load": "5.05 2.88 2.41 32/6707 679808"
},
{
"wall_seconds": 20.001,
"utc": "2026-10-23T07:39:15Z",
"load": "5.77 3.06 2.48 20/6712 687650"
},
{
"wall_seconds": 25.002,
"utc": "2026-10-23T07:39:20Z",
"load": "6.59 3.28 2.55 21/6675 696103"
},
{
"wall_seconds": 30.002,
"utc": "2026-10-23T07:39:25Z",
"load": "6.78 3.37 2.58 13/6627 705121"
},
{
"wall_seconds": 35.002,
"utc": "2026-10-23T07:39:30Z",
"load": "6.56 3.38 2.59 4/6596 713973"
},
{
"wall_seconds": 40.003,
"utc": "2026-10-23T07:39:35Z",
"load": "6.59 3.44 2.62 4/6582 722361"
},
{
"wall_seconds": 45.003,
"utc": "2026-10-23T07:39:40Z",
"load": "6.71 3.52 2.64 5/6573 729968"
},
{
"wall_seconds": 50.003,
"utc": "2026-10-23T07:39:45Z",
"load": "6.81 3.59 2.67 9/6577 737845"
},
{
"wall_seconds": 55.003,
"utc": "2026-10-23T07:39:50Z",
"load": "6.67 3.62 2.69 6/6627 744813"
},
{
"wall_seconds": 60.004,
"utc": "2026-10-23T07:39:55Z",
"load": "7.01 3.74 2.73 4/6582 752028"
},
{
"wall_seconds": 65.004,
"utc": "2026-10-23T07:40:00Z",
"load": "7.17 3.83 2.76 5/6551 763533"
},
{
"wall_seconds": 70.004,
"utc": "2026-10-23T07:40:05Z",
"load": "7.08 3.86 2.78 5/6568 774263"
},
{
"wall_seconds": 75.004,
"utc": "2026-10-23T07:40:10Z",
"load": "6.99 3.90 2.80 4/6564 781529"
},
{
"wall_seconds": 80.004,
"utc": "2026-10-23T07:40:15Z",
"load": "6.91 3.93 2.82 4/6556 787135"
},
{
"wall_seconds": 85.005,
"utc": "2026-10-23T07:40:20Z",
"load": "6.68 3.93 2.82 5/6548 793267"
},
{
"wall_seconds": 90.005,
"utc": "2026-10-23T07:40:25Z",
"load": "6.46 3.94 2.83 2/6525 799740"
},
{
"wall_seconds": 95.005,
"utc": "2026-10-23T07:40:30Z",
"load": "6.19 3.92 2.83 3/6566 805494"
},
{
"wall_seconds": 100.005,
"utc": "2026-10-23T07:40:35Z",
"load": "7.05 4.14 2.91 4/6526 810900"
},
{
"wall_seconds": 105.006,
"utc": "2026-10-23T07:40:40Z",
"load": "6.57 4.09 2.90 3/6492 813663"
},
{
"wall_seconds": 110.006,
"utc": "2026-10-23T07:40:45Z",
"load": "6.12 4.03 2.89 6/6526 817202"
},
{
"wall_seconds": 115.006,
"utc": "2026-10-23T07:40:50Z",
"load": "5.71 3.98 2.88 4/6542 820365"
},
{
"wall_seconds": 120.006,
"utc": "2026-10-23T07:40:55Z",
"load": "5.49 3.97 2.88 3/6504 824801"
},
{
"wall_seconds": 125.006,
"utc": "2026-10-23T07:41:00Z",
"load": "5.13 3.92 2.87 5/6520 829672"
},
{
"wall_seconds": 130.007,
"utc": "2026-10-23T07:41:05Z",
"load": "4.96 3.90 2.87 5/6491 835347"
},
{
"wall_seconds": 135.007,
"utc": "2026-10-23T07:41:10Z",
"load": "4.81 3.89 2.87 6/6515 841325"
},
{
"wall_seconds": 140.007,
"utc": "2026-10-23T07:41:15Z",
"load": "4.66 3.87 2.87 3/6533 846943"
},
{
"wall_seconds": 145.007,
"utc": "2026-10-23T07:41:20Z",
"load": "4.53 3.86 2.87 6/6537 852457"
},
{
"wall_seconds": 150.008,
"utc": "2026-10-23T07:41:25Z",
"load": "4.81 3.93 2.90 5/6497 857183"
},
{
"wall_seconds": 155.008,
"utc": "2026-10-23T07:41:30Z",
"load": "4.74 3.93 2.91 9/6493 862111"
},
{
"wall_seconds": 160.008,
"utc": "2026-10-23T07:41:35Z",
"load": "4.52 3.89 2.90 3/6484 867180"
},
{
"wall_seconds": 165.008,
"utc": "2026-10-23T07:41:40Z",
"load": "4.88 3.98 2.93 3/6494 874705"
},
{
"wall_seconds": 170.009,
"utc": "2026-10-23T07:41:45Z",
"load": "4.57 3.93 2.92 5/6513 879949"
},
{
"wall_seconds": 175.009,
"utc": "2026-10-23T07:41:50Z",
"load": "4.36 3.90 2.92 3/6532 885364"
},
{
"wall_seconds": 180.009,
"utc": "2026-10-23T07:41:55Z",
"load": "4.09 3.85 2.91 4/6518 889649"
},
{
"wall_seconds": 185.009,
"utc": "2026-10-23T07:42:00Z",
"load": "4.33 3.90 2.93 3/6500 895045"
},
{
"wall_seconds": 190.01,
"utc": "2026-10-23T07:42:05Z",
"load": "4.22 3.89 2.93 5/6497 900591"
},
{
"wall_seconds": 195.01,
"utc": "2026-10-23T07:42:10Z",
"load": "4.28 3.91 2.94 6/6500 906203"
},
{
"wall_seconds": 200.01,
"utc": "2026-10-23T07:42:15Z",
"load": "4.18 3.89 2.94 3/6513 911214"
},
{
"wall_seconds": 205.01,
"utc": "2026-10-23T07:42:20Z",
"load": "4.00 3.86 2.94 3/6521 916524"
},
{
"wall_seconds": 210.011,
"utc": "2026-10-23T07:42:25Z",
"load": "4.56 3.98 2.98 4/6507 921377"
},
{
"wall_seconds": 215.011,
"utc": "2026-10-23T07:42:30Z",
"load": "4.84 4.04 3.01 2/6517 926031"
},
{
"wall_seconds": 220.011,
"utc": "2026-10-23T07:42:35Z",
"load": "4.61 4.01 3.00 2/6512 930921"
},
{
"wall_seconds": 225.011,
"utc": "2026-10-23T07:42:40Z",
"load": "4.72 4.04 3.02 5/6513 936830"
},
{
"wall_seconds": 230.011,
"utc": "2026-10-23T07:42:45Z",
"load": "5.07 4.13 3.05 6/6527 943593"
},
{
"wall_seconds": 235.012,
"utc": "2026-10-23T07:42:50Z",
"load": "4.90 4.11 3.05 4/6524 949131"
},
{
"wall_seconds": 240.012,
"utc": "2026-10-23T07:42:55Z",
"load": "4.75 4.09 3.05 3/6538 954091"
},
{
"wall_seconds": 245.012,
"utc": "2026-10-23T07:43:00Z",
"load": "4.53 4.05 3.04 4/6526 957569"
},
{
"wall_seconds": 250.012,
"utc": "2026-10-23T07:43:05Z",
"load": "4.49 4.05 3.05 4/6512 961428"
},
{
"wall_seconds": 255.013,
"utc": "2026-10-23T07:43:10Z",
"load": "4.21 4.00 3.04 2/6514 964580"
},
{
"wall_seconds": 260.013,
"utc": "2026-10-23T07:43:15Z",
"load": "4.03 3.97 3.03 3/6520 969453"
},
{
"wall_seconds": 265.013,
"utc": "2026-10-23T07:43:20Z",
"load": "3.95 3.95 3.03 2/6510 972206"
},
{
"wall_seconds": 270.013,
"utc": "2026-10-23T07:43:25Z",
"load": "3.71 3.90 3.02 4/6485 974717"
},
{
"wall_seconds": 275.013,
"utc": "2026-10-23T07:43:30Z",
"load": "3.49 3.85 3.01 2/6458 976947"
},
{
"wall_seconds": 280.014,
"utc": "2026-10-23T07:43:35Z",
"load": "3.29 3.81 3.00 2/6480 979354"
},
{
"wall_seconds": 285.014,
"utc": "2026-10-23T07:43:40Z",
"load": "3.11 3.76 2.99 2/6484 981777"
},
{
"wall_seconds": 290.014,
"utc": "2026-10-23T07:43:45Z",
"load": "2.94 3.71 2.98 9/6503 984183"
},
{
"wall_seconds": 295.014,
"utc": "2026-10-23T07:43:50Z",
"load": "2.86 3.68 2.97 2/6530 986646"
},
{
"wall_seconds": 300.015,
"utc": "2026-10-23T07:43:55Z",
"load": "2.72 3.64 2.96 2/6518 989821"
},
{
"wall_seconds": 305.015,
"utc": "2026-10-23T07:44:00Z",
"load": "2.66 3.61 2.95 2/6504 993303"
},
{
"wall_seconds": 310.015,
"utc": "2026-10-23T07:44:05Z",
"load": "2.77 3.62 2.96 3/6379 996998"
},
{
"wall_seconds": 315.015,
"utc": "2026-10-23T07:44:10Z",
"load": "2.78 3.61 2.96 3/6398 1000446"
},
{
"wall_seconds": 320.015,
"utc": "2026-10-23T07:44:15Z",
"load": "2.72 3.58 2.95 3/6378 1003966"
},
{
"wall_seconds": 325.016,
"utc": "2026-10-23T07:44:20Z",
"load": "2.90 3.61 2.97 1/6404 1007129"
},
{
"wall_seconds": 330.016,
"utc": "2026-10-23T07:44:25Z",
"load": "2.75 3.56 2.96 2/6357 1009536"
},
{
"wall_seconds": 335.016,
"utc": "2026-10-23T07:44:30Z",
"load": "2.69 3.54 2.95 3/6346 1011941"
},
{
"wall_seconds": 340.016,
"utc": "2026-10-23T07:44:35Z",
"load": "2.56 3.49 2.94 2/6359 1014274"
},
{
"wall_seconds": 345.017,
"utc": "2026-10-23T07:44:40Z",
"load": "2.43 3.45 2.93 2/6364 1016643"
},
{
"wall_seconds": 350.017,
"utc": "2026-10-23T07:44:45Z",
"load": "2.24 3.39 2.91 2/6385 1019039"
},
{
"wall_seconds": 355.017,
"utc": "2026-10-23T07:44:50Z",
"load": "2.14 3.35 2.90 2/6398 1021488"
},
{
"wall_seconds": 360.017,
"utc": "2026-10-23T07:44:55Z",
"load": "2.12 3.33 2.90 1/6372 1024145"
},
{
"wall_seconds": 365.018,
"utc": "2026-10-23T07:45:00Z",
"load": "2.03 3.29 2.89 2/6356 1026540"
},
{
"wall_seconds": 370.018,
"utc": "2026-10-23T07:45:05Z",
"load": "2.03 3.27 2.88 4/6367 1028881"
},
{
"wall_seconds": 375.018,
"utc": "2026-10-23T07:45:10Z",
"load": "2.03 3.25 2.88 4/6356 1031296"
},
{
"wall_seconds": 380.018,
"utc": "2026-10-23T07:45:15Z",
"load": "2.43 3.31 2.90 4/6364 1034002"
},
{
"wall_seconds": 385.019,
"utc": "2026-10-23T07:45:20Z",
"load": "2.47 3.31 2.90 4/6431 1037181"
},
{
"wall_seconds": 390.019,
"utc": "2026-10-23T07:45:25Z",
"load": "2.52 3.30 2.90 3/6366 1040453"
},
{
"wall_seconds": 395.019,
"utc": "2026-10-23T07:45:30Z",
"load": "2.71 3.33 2.91 2/6356 1043515"
},
{
"wall_seconds": 400.019,
"utc": "2026-10-23T07:45:35Z",
"load": "2.58 3.29 2.90 2/6353 1047043"
},
{
"wall_seconds": 405.019,
"utc": "2026-10-23T07:45:40Z",
"load": "2.61 3.29 2.90 3/6371 1050590"
},
{
"wall_seconds": 410.02,
"utc": "2026-10-23T07:45:45Z",
"load": "2.56 3.26 2.90 4/6371 1054393"
},
{
"wall_seconds": 415.02,
"utc": "2026-10-23T07:45:50Z",
"load": "2.44 3.23 2.89 2/6391 1057424"
},
{
"wall_seconds": 420.02,
"utc": "2026-10-23T07:45:55Z",
"load": "2.40 3.21 2.88 2/6381 1059953"
},
{
"wall_seconds": 425.02,
"utc": "2026-10-23T07:46:00Z",
"load": "2.53 3.22 2.89 6/6361 1062385"
},
{
"wall_seconds": 430.021,
"utc": "2026-10-23T07:46:05Z",
"load": "2.49 3.20 2.88 5/6347 1064852"
},
{
"wall_seconds": 435.021,
"utc": "2026-10-23T07:46:10Z",
"load": "2.37 3.16 2.87 4/6362 1067362"
},
{
"wall_seconds": 440.021,
"utc": "2026-10-23T07:46:15Z",
"load": "2.26 3.13 2.86 2/6373 1069948"
},
{
"wall_seconds": 445.021,
"utc": "2026-10-23T07:46:20Z",
"load": "2.16 3.09 2.85 2/6397 1072349"
},
{
"wall_seconds": 450.022,
"utc": "2026-10-23T07:46:25Z",
"load": "2.22 3.09 2.85 3/6359 1075002"
},
{
"wall_seconds": 455.022,
"utc": "2026-10-23T07:46:30Z",
"load": "2.21 3.07 2.85 2/6341 1077533"
},
{
"wall_seconds": 460.022,
"utc": "2026-10-23T07:46:35Z",
"load": "2.19 3.05 2.85 2/6351 1080042"
},
{
"wall_seconds": 465.022,
"utc": "2026-10-23T07:46:40Z",
"load": "2.26 3.05 2.85 2/6353 1084865"
},
{
"wall_seconds": 470.022,
"utc": "2026-10-23T07:46:45Z",
"load": "2.23 3.03 2.84 2/6375 1087473"
},
{
"wall_seconds": 475.023,
"utc": "2026-10-23T07:46:50Z",
"load": "2.30 3.03 2.84 5/6406 1090849"
},
{
"wall_seconds": 480.023,
"utc": "2026-10-23T07:46:55Z",
"load": "3.07 3.18 2.89 2/6380 1094664"
},
{
"wall_seconds": 485.023,
"utc": "2026-10-23T07:47:00Z",
"load": "3.07 3.18 2.89 4/6352 1098090"
},
{
"wall_seconds": 490.023,
"utc": "2026-10-23T07:47:05Z",
"load": "3.06 3.17 2.89 7/6377 1101587"
},
{
"wall_seconds": 495.024,
"utc": "2026-10-23T07:47:10Z",
"load": "3.06 3.17 2.89 6/6350 1104939"
},
{
"wall_seconds": 500.024,
"utc": "2026-10-23T07:47:15Z",
"load": "2.97 3.15 2.89 4/6368 1107224"
},
{
"wall_seconds": 505.024,
"utc": "2026-10-23T07:47:20Z",
"load": "2.89 3.13 2.88 2/6386 1109380"
},
{
"wall_seconds": 510.024,
"utc": "2026-10-23T07:47:25Z",
"load": "3.22 3.20 2.91 1/6387 1110174"
},
{
"wall_seconds": 515.024,
"utc": "2026-10-23T07:47:30Z",
"load": "3.12 3.18 2.90 4/6370 1111210"
},
{
"wall_seconds": 520.025,
"utc": "2026-10-23T07:47:35Z",
"load": "2.95 3.14 2.89 3/6330 1112228"
},
{
"wall_seconds": 525.025,
"utc": "2026-10-23T07:47:40Z",
"load": "2.72 3.09 2.88 1/6328 1112851"
},
{
"wall_seconds": 530.025,
"utc": "2026-10-23T07:47:45Z",
"load": "2.58 3.05 2.87 1/6357 1113559"
},
{
"wall_seconds": 535.025,
"utc": "2026-10-23T07:47:50Z",
"load": "2.45 3.02 2.86 1/6366 1114165"
},
{
"wall_seconds": 540.026,
"utc": "2026-10-23T07:47:55Z",
"load": "2.26 2.97 2.84 1/6356 1114925"
},
{
"wall_seconds": 545.026,
"utc": "2026-10-23T07:48:00Z",
"load": "2.16 2.94 2.83 3/6326 1115379"
},
{
"wall_seconds": 550.026,
"utc": "2026-10-23T07:48:05Z",
"load": "1.98 2.89 2.81 1/6330 1115933"
},
{
"wall_seconds": 555.026,
"utc": "2026-10-23T07:48:10Z",
"load": "1.90 2.86 2.80 5/6348 1117979"
},
{
"wall_seconds": 560.026,
"utc": "2026-10-23T07:48:15Z",
"load": "1.75 2.81 2.79 5/6352 1119958"
},
{
"wall_seconds": 565.027,
"utc": "2026-10-23T07:48:20Z",
"load": "1.69 2.78 2.78 3/6395 1121255"
},
{
"wall_seconds": 570.027,
"utc": "2026-10-23T07:48:25Z",
"load": "1.63 2.75 2.77 2/6344 1122878"
},
{
"wall_seconds": 575.027,
"utc": "2026-10-23T07:48:30Z",
"load": "1.58 2.72 2.76 2/6330 1125425"
},
{
"wall_seconds": 580.027,
"utc": "2026-10-23T07:48:35Z",
"load": "1.54 2.69 2.75 3/6307 1128035"
},
{
"wall_seconds": 585.028,
"utc": "2026-10-23T07:48:40Z",
"load": "1.81 2.73 2.76 3/6395 1131079"
},
{
"wall_seconds": 590.028,
"utc": "2026-10-23T07:48:45Z",
"load": "1.75 2.70 2.75 2/6324 1133629"
},
{
"wall_seconds": 595.028,
"utc": "2026-10-23T07:48:50Z",
"load": "1.77 2.69 2.75 2/6354 1135983"
},
{
"wall_seconds": 600.028,
"utc": "2026-10-23T07:48:55Z",
"load": "1.71 2.66 2.74 2/6317 1138250"
},
{
"wall_seconds": 605.029,
"utc": "2026-10-23T07:49:00Z",
"load": "1.65 2.63 2.73 2/6307 1140569"
},
{
"wall_seconds": 610.029,
"utc": "2026-10-23T07:49:05Z",
"load": "1.68 2.62 2.72 2/5871 1142432"
},
{
"wall_seconds": 615.029,
"utc": "2026-10-23T07:49:10Z",
"load": "1.70 2.61 2.72 2/5858 1144385"
},
{
"wall_seconds": 620.029,
"utc": "2026-10-23T07:49:15Z",
"load": "1.57 2.57 2.71 1/5860 1145308"
},
{
"wall_seconds": 625.03,
"utc": "2026-10-23T07:49:20Z",
"load": "1.60 2.56 2.70 2/5872 1147140"
},
{
"wall_seconds": 630.03,
"utc": "2026-10-23T07:49:25Z",
"load": "1.55 2.53 2.69 2/5844 1149434"
}
]
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,909 +0,0 @@
{
"grant": "sage-3268",
"m4_ruling": "sage-3273 / mos-1426",
"head": "ffa93b054f28852a75017928d8478bdf9046e717",
"manifest": "277ace0b4274970d5bd4c05cf8fe99aa1e7ebc469a719e4cefcb334a75d3865d",
"status": "GREEN",
"cli_file_list": [
"packages/cli/tests/access-boot.test.mjs",
"packages/cli/tests/access.test.mjs",
"packages/cli/tests/app.test.mjs",
"packages/cli/tests/boot-status.test.mjs",
"packages/cli/tests/case1-accept.test.mjs",
"packages/cli/tests/case1-hostcheck.test.mjs",
"packages/cli/tests/case2-persona-import.test.mjs",
"packages/cli/tests/case2-unit.test.mjs",
"packages/cli/tests/channel-cli.test.mjs",
"packages/cli/tests/channel-recovery.test.mjs",
"packages/cli/tests/cli.test.mjs",
"packages/cli/tests/compactions-launch.test.mjs",
"packages/cli/tests/config.test.mjs",
"packages/cli/tests/credentials.test.mjs",
"packages/cli/tests/follow.test.mjs",
"packages/cli/tests/format.test.mjs",
"packages/cli/tests/gate-lane-auth.test.mjs",
"packages/cli/tests/gate-lane-fixtures.test.mjs",
"packages/cli/tests/gate-lane-image.test.mjs",
"packages/cli/tests/gate-lane-state.test.mjs",
"packages/cli/tests/gate-lane.test.mjs",
"packages/cli/tests/git-socket.test.mjs",
"packages/cli/tests/grants.test.mjs",
"packages/cli/tests/host.test.mjs",
"packages/cli/tests/hosts.test.mjs",
"packages/cli/tests/instances.test.mjs",
"packages/cli/tests/launch-account.test.mjs",
"packages/cli/tests/launch-limit-checks.test.mjs",
"packages/cli/tests/launch-limits.test.mjs",
"packages/cli/tests/launch-routes.test.mjs",
"packages/cli/tests/launcher.test.mjs",
"packages/cli/tests/lifecycle.test.mjs",
"packages/cli/tests/limits-tokens.test.mjs",
"packages/cli/tests/limits.test.mjs",
"packages/cli/tests/mark-read.test.mjs",
"packages/cli/tests/names.test.mjs",
"packages/cli/tests/notifier.test.mjs",
"packages/cli/tests/other-tree.test.mjs",
"packages/cli/tests/processing-cli.test.mjs",
"packages/cli/tests/project-name-repo.test.mjs",
"packages/cli/tests/project.test.mjs",
"packages/cli/tests/publish-socket.test.mjs",
"packages/cli/tests/session-clear.test.mjs",
"packages/cli/tests/session-launch.test.mjs",
"packages/cli/tests/stack-copy.test.mjs",
"packages/cli/tests/stack-instances.test.mjs",
"packages/cli/tests/stack-release-external.test.mjs",
"packages/cli/tests/stack-release.test.mjs",
"packages/cli/tests/stack-upgrade.test.mjs",
"packages/cli/tests/tester-http.test.mjs",
"packages/cli/tests/tester-reads.test.mjs",
"packages/cli/tests/tester-threads.test.mjs",
"packages/cli/tests/tester.test.mjs",
"packages/cli/tests/thread-cli.test.mjs",
"packages/cli/tests/thread-launch.test.mjs",
"packages/cli/tests/trackers-boot.test.mjs",
"packages/cli/tests/transport.test.mjs",
"packages/cli/tests/usage.test.mjs",
"packages/cli/tests/verbs.test.mjs"
],
"cli_file_count": 59,
"stages": [
{
"label": "syntax-1",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case-p10-timing-fixture.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/g6MkUyY",
"started_utc": "2026-10-23T07:26:54Z",
"start_load": "1.05 1.69 2.00 5/6642 199026",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/syntax-1.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.032,
"finished_utc": "2026-10-23T07:26:54Z",
"end_load": "1.05 1.69 2.00 3/6641 199047",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "syntax-2",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gbr1O5v",
"started_utc": "2026-10-23T07:26:55Z",
"start_load": "1.05 1.69 2.00 2/6651 202505",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/syntax-2.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.032,
"finished_utc": "2026-10-23T07:26:55Z",
"end_load": "1.05 1.69 2.00 1/6651 202515",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "case1-whole-1",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/geSGqXZ",
"started_utc": "2026-10-23T07:26:57Z",
"start_load": "1.05 1.69 2.00 1/6640 205920",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/case1-whole-1.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 239.134,
"finished_utc": "2026-10-23T07:30:56Z",
"end_load": "3.41 2.47 2.22 1/6690 353962",
"counts": {
"tests": 53,
"pass": 53,
"fail": 0,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [
{
"fault": "inner",
"mode": "exec",
"baselineSeconds": 1.8914214159999974,
"faultSeconds": 3.974223306999993,
"probeSeconds": 2.25
},
{
"fault": "inner",
"mode": "hop",
"baselineSeconds": 1.8980776110000006,
"faultSeconds": 4.004310756999999,
"probeSeconds": 2.27
},
{
"fault": "outer",
"mode": "exec",
"baselineSeconds": 1.8725320299999875,
"faultSeconds": 5.715126132999998,
"probeSeconds": 4
},
{
"fault": "outer",
"mode": "hop",
"baselineSeconds": 1.8715896639999992,
"faultSeconds": 5.726812752999991,
"probeSeconds": 4
}
],
"skip_lines": [],
"external_timeout": false
},
{
"label": "case1-whole-2",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gd0qwWL",
"started_utc": "2026-10-23T07:30:57Z",
"start_load": "3.41 2.47 2.22 4/6666 357541",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/case1-whole-2.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 240.044,
"finished_utc": "2026-10-23T07:34:57Z",
"end_load": "2.00 2.32 2.22 1/6458 505199",
"counts": {
"tests": 53,
"pass": 53,
"fail": 0,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [
{
"fault": "inner",
"mode": "exec",
"baselineSeconds": 1.9894229939999932,
"faultSeconds": 4.213512103000001,
"probeSeconds": 2.29
},
{
"fault": "inner",
"mode": "hop",
"baselineSeconds": 2.056171266999998,
"faultSeconds": 4.169351735999997,
"probeSeconds": 2.28
},
{
"fault": "outer",
"mode": "exec",
"baselineSeconds": 1.9589971570000053,
"faultSeconds": 5.726783651999998,
"probeSeconds": 4
},
{
"fault": "outer",
"mode": "hop",
"baselineSeconds": 1.879084925999996,
"faultSeconds": 5.732443853999998,
"probeSeconds": 4.01
}
],
"skip_lines": [],
"external_timeout": false
},
{
"label": "case1-whole-3",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gdjuph7",
"started_utc": "2026-10-23T07:34:59Z",
"start_load": "2.08 2.33 2.22 4/6464 509071",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/case1-whole-3.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 235.011,
"finished_utc": "2026-10-23T07:38:54Z",
"end_load": "1.91 2.18 2.19 2/6403 652743",
"counts": {
"tests": 53,
"pass": 53,
"fail": 0,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [
{
"fault": "inner",
"mode": "exec",
"baselineSeconds": 1.8627637730000133,
"faultSeconds": 3.9948855329999935,
"probeSeconds": 2.25
},
{
"fault": "inner",
"mode": "hop",
"baselineSeconds": 1.8459824050000024,
"faultSeconds": 3.963717149000004,
"probeSeconds": 2.26
},
{
"fault": "outer",
"mode": "exec",
"baselineSeconds": 1.8736066859999991,
"faultSeconds": 5.7249899409999925,
"probeSeconds": 4
},
{
"fault": "outer",
"mode": "hop",
"baselineSeconds": 1.8894593350000068,
"faultSeconds": 5.709737833999999,
"probeSeconds": 4
}
],
"skip_lines": [],
"external_timeout": false
},
{
"label": "cli-whole",
"argv": [
"timeout",
"-k",
"10",
"5400",
"node",
"--test",
"--test-reporter=tap",
"packages/cli/tests/access-boot.test.mjs",
"packages/cli/tests/access.test.mjs",
"packages/cli/tests/app.test.mjs",
"packages/cli/tests/boot-status.test.mjs",
"packages/cli/tests/case1-accept.test.mjs",
"packages/cli/tests/case1-hostcheck.test.mjs",
"packages/cli/tests/case2-persona-import.test.mjs",
"packages/cli/tests/case2-unit.test.mjs",
"packages/cli/tests/channel-cli.test.mjs",
"packages/cli/tests/channel-recovery.test.mjs",
"packages/cli/tests/cli.test.mjs",
"packages/cli/tests/compactions-launch.test.mjs",
"packages/cli/tests/config.test.mjs",
"packages/cli/tests/credentials.test.mjs",
"packages/cli/tests/follow.test.mjs",
"packages/cli/tests/format.test.mjs",
"packages/cli/tests/gate-lane-auth.test.mjs",
"packages/cli/tests/gate-lane-fixtures.test.mjs",
"packages/cli/tests/gate-lane-image.test.mjs",
"packages/cli/tests/gate-lane-state.test.mjs",
"packages/cli/tests/gate-lane.test.mjs",
"packages/cli/tests/git-socket.test.mjs",
"packages/cli/tests/grants.test.mjs",
"packages/cli/tests/host.test.mjs",
"packages/cli/tests/hosts.test.mjs",
"packages/cli/tests/instances.test.mjs",
"packages/cli/tests/launch-account.test.mjs",
"packages/cli/tests/launch-limit-checks.test.mjs",
"packages/cli/tests/launch-limits.test.mjs",
"packages/cli/tests/launch-routes.test.mjs",
"packages/cli/tests/launcher.test.mjs",
"packages/cli/tests/lifecycle.test.mjs",
"packages/cli/tests/limits-tokens.test.mjs",
"packages/cli/tests/limits.test.mjs",
"packages/cli/tests/mark-read.test.mjs",
"packages/cli/tests/names.test.mjs",
"packages/cli/tests/notifier.test.mjs",
"packages/cli/tests/other-tree.test.mjs",
"packages/cli/tests/processing-cli.test.mjs",
"packages/cli/tests/project-name-repo.test.mjs",
"packages/cli/tests/project.test.mjs",
"packages/cli/tests/publish-socket.test.mjs",
"packages/cli/tests/session-clear.test.mjs",
"packages/cli/tests/session-launch.test.mjs",
"packages/cli/tests/stack-copy.test.mjs",
"packages/cli/tests/stack-instances.test.mjs",
"packages/cli/tests/stack-release-external.test.mjs",
"packages/cli/tests/stack-release.test.mjs",
"packages/cli/tests/stack-upgrade.test.mjs",
"packages/cli/tests/tester-http.test.mjs",
"packages/cli/tests/tester-reads.test.mjs",
"packages/cli/tests/tester-threads.test.mjs",
"packages/cli/tests/tester.test.mjs",
"packages/cli/tests/thread-cli.test.mjs",
"packages/cli/tests/thread-launch.test.mjs",
"packages/cli/tests/trackers-boot.test.mjs",
"packages/cli/tests/transport.test.mjs",
"packages/cli/tests/usage.test.mjs",
"packages/cli/tests/verbs.test.mjs"
],
"limit_seconds": 5400,
"tmpdir": "/mnt/storage/scratch/tmp/gebsaIr",
"started_utc": "2026-10-23T07:38:55Z",
"start_load": "1.91 2.18 2.19 1/6404 656161",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/cli-whole.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 631.848,
"finished_utc": "2026-10-23T07:49:27Z",
"end_load": "1.55 2.53 2.69 1/5811 1150227",
"counts": {
"tests": 917,
"pass": 917,
"fail": 0,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [
{
"fault": "inner",
"mode": "exec",
"baselineSeconds": 2.0945929310000064,
"faultSeconds": 4.18209504700001,
"probeSeconds": 2.27
},
{
"fault": "inner",
"mode": "hop",
"baselineSeconds": 1.9464092949999903,
"faultSeconds": 4.171354483000003,
"probeSeconds": 2.27
},
{
"fault": "outer",
"mode": "exec",
"baselineSeconds": 1.9332695270000113,
"faultSeconds": 5.785670190999998,
"probeSeconds": 4.01
},
{
"fault": "outer",
"mode": "hop",
"baselineSeconds": 1.8855918230000097,
"faultSeconds": 5.739914212000003,
"probeSeconds": 4.01
}
],
"skip_lines": [],
"external_timeout": false
},
{
"label": "M1-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gh8s2Og",
"started_utc": "2026-10-23T07:49:28Z",
"start_load": "1.51 2.50 2.68 3/5810 1153451",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M1-syntax.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.008,
"finished_utc": "2026-10-23T07:49:28Z",
"end_load": "1.51 2.50 2.68 1/5810 1153455",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "M1",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 inner reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gxjj9Vd",
"started_utc": "2026-10-23T07:49:30Z",
"start_load": "1.51 2.50 2.68 1/5816 1156782",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M1.log",
"expected_red": true,
"rc": 1,
"wall_seconds": 4.774,
"finished_utc": "2026-10-23T07:49:34Z",
"end_load": "1.47 2.48 2.67 2/5828 1159225",
"counts": {
"tests": 1,
"pass": 0,
"fail": 1,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [
{
"fault": "inner",
"mode": "exec",
"baselineSeconds": 1.764558389,
"faultSeconds": 2.8568522200000004,
"probeSeconds": 1.23
}
],
"skip_lines": [],
"external_timeout": false,
"killed": true,
"kill_test": "row253 C4 P10 inner reason holds under both sudo models",
"mutated_sha256": "83fc6e5d93d9dbe8c40995c4e1445a3b61312df3a988a7ad0f7b63c762d2bf3f"
},
{
"label": "M2-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gZ30EQX",
"started_utc": "2026-10-23T07:49:36Z",
"start_load": "1.47 2.48 2.67 1/5822 1162481",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M2-syntax.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.008,
"finished_utc": "2026-10-23T07:49:36Z",
"end_load": "1.47 2.48 2.67 1/5822 1162485",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "M2",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 inner reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gYr4G6o",
"started_utc": "2026-10-23T07:49:37Z",
"start_load": "1.47 2.48 2.67 1/5823 1165689",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M2.log",
"expected_red": true,
"rc": 1,
"wall_seconds": 6.768,
"finished_utc": "2026-10-23T07:49:44Z",
"end_load": "1.40 2.43 2.66 5/5879 1169357",
"counts": {
"tests": 1,
"pass": 0,
"fail": 1,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [
{
"fault": "inner",
"mode": "exec",
"baselineSeconds": 1.754618234,
"faultSeconds": 4.849417662,
"probeSeconds": 3.24
}
],
"skip_lines": [],
"external_timeout": false,
"killed": true,
"kill_test": "row253 C4 P10 inner reason holds under both sudo models",
"mutated_sha256": "269e550da358457cbc85df637f02c323bfc09c21cedea2bc9f4968bedd5c71a4"
},
{
"label": "M3-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gwCkjzX",
"started_utc": "2026-10-23T07:49:45Z",
"start_load": "1.40 2.43 2.66 2/5844 1172866",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M3-syntax.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.008,
"finished_utc": "2026-10-23T07:49:45Z",
"end_load": "1.40 2.43 2.66 2/5844 1172870",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "M3",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 outer reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/g6TrU8V",
"started_utc": "2026-10-23T07:49:46Z",
"start_load": "1.40 2.43 2.66 2/5868 1176268",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M3.log",
"expected_red": true,
"rc": 1,
"wall_seconds": 6.618,
"finished_utc": "2026-10-23T07:49:53Z",
"end_load": "1.41 2.40 2.64 2/5827 1179333",
"counts": {
"tests": 1,
"pass": 0,
"fail": 1,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [
{
"fault": "outer",
"mode": "exec",
"baselineSeconds": 1.7982556909999998,
"faultSeconds": 4.664919980999999,
"probeSeconds": 3.01
}
],
"skip_lines": [],
"external_timeout": false,
"killed": true,
"kill_test": "row253 C4 P10 outer reason holds under both sudo models",
"mutated_sha256": "21143aeb637ef864cdcb71086b3149c9817b5af752bc431e963c51a04f01b498"
},
{
"label": "M4-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"bash",
"-n",
"scripts/case1-accept.sh"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gRPd59t",
"started_utc": "2026-10-23T07:49:54Z",
"start_load": "1.41 2.40 2.64 3/5836 1182894",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M4-syntax.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.008,
"finished_utc": "2026-10-23T07:49:54Z",
"end_load": "1.41 2.40 2.64 3/5840 1182903",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "M4",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 outer reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gAKhO44",
"started_utc": "2026-10-23T07:49:56Z",
"start_load": "1.41 2.40 2.64 8/5839 1186447",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M4.log",
"expected_red": true,
"rc": 1,
"wall_seconds": 9.023,
"finished_utc": "2026-10-23T07:50:05Z",
"end_load": "1.65 2.42 2.65 2/5832 1193403",
"counts": {
"tests": 1,
"pass": 0,
"fail": 1,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [],
"skip_lines": [],
"external_timeout": false,
"guard_return_receipt": {
"ruling": "sage-3273 / mos-1426",
"configured_ms": 7000,
"named_command_returned": true,
"rc": 1,
"wall_seconds": 9.023,
"actual_refusal": "probe-inner-command",
"external_timeout": false,
"evidence": "named outer-reason ERR_ASSERTION in raw log after the unchanged safety guard returns; guard itself has no log channel"
},
"killed": true,
"kill_test": "row253 C4 P10 outer reason holds under both sudo models",
"mutated_sha256": "cde2e58596794ff7c185c46979e2f7abcb3032ec6903653b7043fe17ef54baee"
},
{
"label": "M5-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case-p10-timing-fixture.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/g8waDyO",
"started_utc": "2026-10-23T07:50:06Z",
"start_load": "1.65 2.42 2.65 2/5826 1197030",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M5-syntax.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.032,
"finished_utc": "2026-10-23T07:50:06Z",
"end_load": "1.65 2.42 2.65 2/5838 1197071",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "M5",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row253 C4 P10 inner reason holds under both sudo models$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gdAgQSv",
"started_utc": "2026-10-23T07:50:07Z",
"start_load": "1.65 2.42 2.65 2/5824 1200489",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M5.log",
"expected_red": true,
"rc": 1,
"wall_seconds": 5.816,
"finished_utc": "2026-10-23T07:50:13Z",
"end_load": "1.63 2.39 2.63 2/5844 1203280",
"counts": {
"tests": 1,
"pass": 0,
"fail": 1,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [],
"skip_lines": [],
"external_timeout": false,
"killed": true,
"kill_test": "row253 C4 P10 inner reason holds under both sudo models",
"mutated_sha256": "e8a42dc79c14ada3e3339b372af75f2b4688a43ec8748b4cf3acb8bec32a3a23"
},
{
"label": "M6-syntax",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case-p10-timing-fixture.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gD2IEb2",
"started_utc": "2026-10-23T07:50:15Z",
"start_load": "1.63 2.39 2.63 1/5845 1206646",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M6-syntax.log",
"expected_red": false,
"rc": 0,
"wall_seconds": 0.032,
"finished_utc": "2026-10-23T07:50:15Z",
"end_load": "1.63 2.39 2.63 2/5845 1206656",
"counts": {},
"metrics": [],
"skip_lines": [],
"external_timeout": false
},
{
"label": "M6",
"argv": [
"timeout",
"-k",
"10",
"1200",
"node",
"--test",
"--test-reporter=tap",
"--test-name-pattern",
"^row299 P10 observer records are complete and ordered$",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 1200,
"tmpdir": "/mnt/storage/scratch/tmp/gAZq1pv",
"started_utc": "2026-10-23T07:50:16Z",
"start_load": "1.63 2.39 2.63 2/5837 1210084",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/M6.log",
"expected_red": true,
"rc": 1,
"wall_seconds": 0.164,
"finished_utc": "2026-10-23T07:50:16Z",
"end_load": "1.63 2.39 2.63 1/5837 1210101",
"counts": {
"tests": 1,
"pass": 0,
"fail": 1,
"cancelled": 0,
"skipped": 0,
"todo": 0
},
"metrics": [],
"skip_lines": [],
"external_timeout": false,
"killed": true,
"kill_test": "row299 P10 observer records are complete and ordered",
"mutated_sha256": "a4256c6ffdc55c8047693e80114361d9c9ad97898fe58125299d967f5badf417"
}
],
"restores": [
{
"id": "M1",
"path": "scripts/case1-accept.sh",
"before_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"restored_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"git_status": "",
"identical": true
},
{
"id": "M2",
"path": "scripts/case1-accept.sh",
"before_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"restored_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"git_status": "",
"identical": true
},
{
"id": "M3",
"path": "scripts/case1-accept.sh",
"before_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"restored_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"git_status": "",
"identical": true
},
{
"id": "M4",
"path": "scripts/case1-accept.sh",
"before_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"restored_sha256": "89b45bb84e8365f32f08fd055c7db8a0259533f23fe7ab03f484acb25bee92c2",
"git_status": "",
"identical": true
},
{
"id": "M5",
"path": "packages/cli/tests/case-p10-timing-fixture.mjs",
"before_sha256": "7ac9d29281d4076bf2e00b7a07294cd4519d7ae9f97c4f6ddc1d22440c9b071a",
"restored_sha256": "7ac9d29281d4076bf2e00b7a07294cd4519d7ae9f97c4f6ddc1d22440c9b071a",
"git_status": "",
"identical": true
},
{
"id": "M6",
"path": "packages/cli/tests/case-p10-timing-fixture.mjs",
"before_sha256": "7ac9d29281d4076bf2e00b7a07294cd4519d7ae9f97c4f6ddc1d22440c9b071a",
"restored_sha256": "7ac9d29281d4076bf2e00b7a07294cd4519d7ae9f97c4f6ddc1d22440c9b071a",
"git_status": "",
"identical": true
}
],
"started_utc": "2026-10-23T07:26:52Z",
"finished_utc": "2026-10-23T07:50:16Z"
}
@@ -1,38 +0,0 @@
{
"utc": "2026-10-23T07:50:47Z",
"count": 0,
"matches": [],
"scope": "All recorded stage TMPDIRs by cwd or argv, and node/tee/FIFO commands with worktree cwd; controller ancestors excluded",
"all_matches_count": 4,
"preexisting_harness": [
{
"pid": 14082,
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196",
"cmd": "/usr/bin/node /mnt/storage/src/t3-comms/t3-code-agent-mcp/dist/cli.js ",
"started_utc": "2026-10-23T07:10:47.750000+00:00",
"predates_gate": true
},
{
"pid": 14243,
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196",
"cmd": "node /home/jwoltje/.npm/_npx/de2bd410102f5eda/node_modules/.bin/mcp-server-sequential-thinking ",
"started_utc": "2026-10-23T07:10:48.770000+00:00",
"predates_gate": true
},
{
"pid": 14282,
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196",
"cmd": "/usr/bin/node /home/jwoltje/.npm/_npx/15c61037b1978c83/node_modules/chrome-devtools-mcp/build/src/telemetry/watchdog/main.js --parent-pid=14259 --app-version=1.12.0 --os-type=3 ",
"started_utc": "2026-10-23T07:10:49.120000+00:00",
"predates_gate": true
},
{
"pid": 14383,
"cwd": "/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196",
"cmd": "node /home/jwoltje/.npm/_npx/9833c18b2d85bc59/node_modules/.bin/playwright-mcp ",
"started_utc": "2026-10-23T07:10:49.540000+00:00",
"predates_gate": true
}
],
"classification": "Four MCP harness processes predate the gate; zero gate-created residuals. No processes killed."
}
@@ -1 +0,0 @@
CLEAR
@@ -1,18 +0,0 @@
{
"label": "syntax-1",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case-p10-timing-fixture.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/g6MkUyY",
"started_utc": "2026-10-23T07:26:54Z",
"start_load": "1.05 1.69 2.00 5/6642 199026",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/syntax-1.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:26:54Z",
"load": "1.05 1.69 2.00 7/6643 199027"
}
]
Whitespace-only changes.
@@ -1 +0,0 @@
CLEAR
@@ -1,18 +0,0 @@
{
"label": "syntax-2",
"argv": [
"timeout",
"-k",
"10",
"120",
"node",
"--check",
"packages/cli/tests/case1-accept.test.mjs"
],
"limit_seconds": 120,
"tmpdir": "/mnt/storage/scratch/tmp/gbr1O5v",
"started_utc": "2026-10-23T07:26:55Z",
"start_load": "1.05 1.69 2.00 2/6651 202505",
"log": "/mnt/storage/scratch/tmp/gABO62Q/records/syntax-2.log",
"expected_red": false
}
@@ -1,7 +0,0 @@
[
{
"wall_seconds": 0.0,
"utc": "2026-10-23T07:26:55Z",
"load": "1.05 1.69 2.00 4/6652 202506"
}
]
Whitespace-only changes.
-104
View File
@@ -1,104 +0,0 @@
import os,sys,json,time,re,pathlib,subprocess,shlex,hashlib,signal
REPO=pathlib.Path('/home/jwoltje/.t3/worktrees/mosaic-stack/gander-row196')
ROOT=pathlib.Path(__file__).parent; OUT=ROOT/'records'; OUT.mkdir(exist_ok=True)
CASE='packages/cli/tests/case1-accept.test.mjs'
HELPER='packages/cli/tests/case-p10-timing-fixture.mjs'
HEAD='ffa93b054f28852a75017928d8478bdf9046e717'
DIGEST='277ace0b4274970d5bd4c05cf8fe99aa1e7ebc469a719e4cefcb334a75d3865d'
FILES=sorted(str(p.relative_to(REPO)) for p in (REPO/'packages/cli/tests').glob('*.test.mjs'))
PLAN=json.loads((REPO/'agents/gander/work/queue-299/MUTANT-PLAN.json').read_text())['mutants']
STATE={'grant':'sage-3268','m4_ruling':'sage-3273 / mos-1426','head':HEAD,'manifest':DIGEST,'status':'PREPARED','cli_file_list':FILES,'cli_file_count':len(FILES),'stages':[],'restores':[]}
def utc():return time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime())
def git(*args):return subprocess.check_output(['git',*args],cwd=REPO,text=True).strip()
def save(): (OUT/'results.json').write_text(json.dumps(STATE,indent=2)+'\n')
def stop(reason):
STATE['status']='STOP';STATE['reason']=reason;STATE['stopped_utc']=utc();save();print('STOP '+reason,flush=True);raise SystemExit(1)
def load(): return pathlib.Path('/proc/loadavg').read_text().strip()
def busy(label):
r=subprocess.run(['bash','/mnt/storage/scratch/sage-busy-now.sh'],capture_output=True,text=True)
(OUT/(label+'.busy.log')).write_text(r.stdout+r.stderr)
if r.returncode or r.stdout.strip().splitlines()[-1:]!=['CLEAR']:stop('busy refusal before '+label)
def parse_metrics(text):
result=[]
for line in text.splitlines():
m=re.match(r'^\s*#\s*(\{.*\})\s*$',line)
if m:
try:
item=json.loads(m[1])
if 'probeSeconds' in item:result.append(item)
except json.JSONDecodeError:pass
return result
def execute(label,args,limit,expected_red=False,syntax=False):
busy(label)
tmp=subprocess.check_output(['mktemp','-d','/mnt/storage/scratch/tmp/gXXXXXX'],text=True).strip()
env=os.environ.copy();env['TMPDIR']=tmp
argv=['timeout','-k','10',str(limit),*args]
meta={'label':label,'argv':argv,'limit_seconds':limit,'tmpdir':tmp,'started_utc':utc(),'start_load':load(),'log':str(OUT/(label+'.log')),'expected_red':expected_red}
(OUT/(label+'.command.json')).write_text(json.dumps(meta,indent=2)+'\n')
STATE['active']=meta;save();print('START '+json.dumps(meta),flush=True)
shell='set -o pipefail\n'+shlex.join(argv)+' 2>&1 | tee '+shlex.quote(meta['log'])
start=time.monotonic();samples=[];p=subprocess.Popen(['bash','-c',shell],cwd=REPO,env=env,start_new_session=True)
while True:
samples.append({'wall_seconds':round(time.monotonic()-start,3),'utc':utc(),'load':load()})
try:rc=p.wait(timeout=5);break
except subprocess.TimeoutExpired:
if time.monotonic()-start>limit+30:
os.killpg(p.pid,signal.SIGKILL);p.wait();stop('outer controller timeout '+label)
text=pathlib.Path(meta['log']).read_text();seconds=round(time.monotonic()-start,3)
counts={}
for key in ['tests','pass','fail','cancelled','skipped','todo']:
matches=re.findall(r'^# '+key+r' (\d+)\s*$',text,re.M)
if matches:counts[key]=int(matches[-1])
row={**meta,'rc':rc,'wall_seconds':seconds,'finished_utc':utc(),'end_load':load(),'counts':counts,'metrics':parse_metrics(text),'skip_lines':[s for s in text.splitlines() if '# SKIP' in s],'external_timeout':rc in (124,137)}
(OUT/(label+'.load.json')).write_text(json.dumps(samples,indent=2)+'\n')
STATE['stages'].append(row);STATE.pop('active',None);save();print('END '+json.dumps(row),flush=True)
if row['external_timeout']:stop('timeout '+label)
if not expected_red and rc!=0:stop('unexpected red '+label)
if not expected_red and not syntax:
if len(row['metrics'])!=4:stop('missing direct P10 diagnostics '+label)
for m in row['metrics']:
lo,hi=(1.25,2.75) if m['fault']=='inner' else (3.25,4.75)
if not lo<=m['probeSeconds']<hi:stop('band overshoot '+label)
return row,text
save()
if len(sys.argv)<2 or sys.argv[1]!='run':sys.exit(0)
if git('rev-parse','HEAD')!=HEAD or git('status','--porcelain'):stop('candidate/tree mismatch')
manifest=(REPO/'agents/gander/work/queue-299/MANIFEST.sha256').read_bytes()
if hashlib.sha256(manifest).hexdigest()!=DIGEST:stop('manifest mismatch')
for m in PLAN:
data=(REPO/m['path']).read_text()
if hashlib.sha256(data.encode()).hexdigest()!=m['source_sha256']:stop('source sha mismatch '+m['id'])
if m.get('scope_begin'):data=data[data.index(m['scope_begin']):data.index(m['scope_end'])]
if data.count(m['old'])!=1:stop('nonunique target '+m['id'])
STATE['status']='RUNNING';STATE['started_utc']=utc();save()
print('PREAMBLE '+json.dumps({'head':HEAD,'manifest':DIGEST,'source':'e6751ecab','case_limit':1200,'cli_limit':5400,'cli_file_count':len(FILES),'cli_files':FILES,'ambient_load_is_target_only':True}),flush=True)
for i,path in enumerate([HELPER,CASE]):execute('syntax-'+str(i+1),['node','--check',path],120,syntax=True)
for i in range(1,4):execute('case1-whole-'+str(i),['node','--test','--test-reporter=tap',CASE],1200)
execute('cli-whole',['node','--test','--test-reporter=tap',*FILES],5400)
for m in PLAN:
original=(REPO/m['path']).read_bytes(); before=hashlib.sha256(original).hexdigest();text=original.decode()
if m.get('scope_begin'):
start=text.index(m['scope_begin']);end=text.index(m['scope_end']);part=text[start:end];changed=text[:start]+part.replace(m['old'],m['new'],1)+text[end:]
else:changed=text.replace(m['old'],m['new'],1)
row=None;output=''
try:
(REPO/m['path']).write_text(changed)
ext=m['path'].rsplit('.',1)[-1];syntax=['bash','-n',m['path']] if ext=='sh' else ['node','--check',m['path']]
execute(m['id']+'-syntax',syntax,120,syntax=True)
row,output=execute(m['id'],['node','--test','--test-reporter=tap','--test-name-pattern','^'+m['killer']+'$',CASE],1200,expected_red=True)
finally:
(REPO/m['path']).write_bytes(original)
restored=hashlib.sha256((REPO/m['path']).read_bytes()).hexdigest();status=git('status','--porcelain')
STATE['restores'].append({'id':m['id'],'path':m['path'],'before_sha256':before,'restored_sha256':restored,'git_status':status,'identical':before==restored});save()
if before!=restored or status:stop('restore drift '+m['id'])
if row is None:stop('no result '+m['id'])
if row['rc']==0:stop('survivor '+m['id'])
named=bool(re.search(r'^not ok \d+ - '+re.escape(m['killer'])+r'\s*$',output,re.M))
assertion='ERR_ASSERTION' in output
if not named or not assertion:stop('wrong failure '+m['id'])
if m['id'] in ['M1','M2','M3'] and not ('direct probe ' in output and row['metrics']):stop('wrong timing kill '+m['id'])
if m['id']=='M4':
if 'probe-outer-timeout' not in output or 'probe-inner-command' not in output:stop('wrong outer-reason failure M4')
row['guard_return_receipt']={'ruling':'sage-3273 / mos-1426','configured_ms':7000,'named_command_returned':True,'rc':row['rc'],'wall_seconds':row['wall_seconds'],'actual_refusal':'probe-inner-command','external_timeout':False,'evidence':'named outer-reason ERR_ASSERTION in raw log after the unchanged safety guard returns; guard itself has no log channel'}
row['killed']=True;row['kill_test']=m['killer'];row['mutated_sha256']=hashlib.sha256(changed.encode()).hexdigest();save()
STATE['status']='GREEN';STATE['finished_utc']=utc();save();print('GREEN all whole stages and M1-M6',flush=True)
@@ -1,111 +0,0 @@
# Row 302 (#1809): assertion preservation
Base 0e30a85fa. `git diff 0e30a85fa -- 'packages/*/tests/*'` on an existing file changes four lines
and nothing else. Each one is ruled by Mos (mos-1414, amended by mos-1415 and mos-1416, relayed in
sage-3206, sage-3209 and sage-3210). No assertion is removed or loosened. Each one now pins the new
code or exit for the same call.
## 1. packages/bus/tests/threads.test.mjs:394 (mos-1414 a)
Old:
```
assert.throws(() => call('a', 'message.receive'), { code: 'not-holder' });
```
New:
```
assert.throws(() => call('a', 'message.receive'), { code: 'launcher-released' });
```
:392 (threadIdle's own second refusal, not-holder) and :395 (the pending check) are unchanged.
## 2. packages/harness/tests/runner.test.mjs:771 (mos-1415)
Old:
```
assert.equal(out.code, EXIT.session, out.stderr);
```
New:
```
assert.equal(out.code, 0, out.stderr);
```
out.stderr stays as the message.
## 3. packages/harness/tests/runner.test.mjs:772 (mos-1415)
Old:
```
assert.match(out.stderr, new RegExp(`runner: landing turn 1 for decision ${d1.id} \\(vikunja:1/2\\): ok\n[\\s\\S]*runner: session stopped working: not-holder\n`));
```
New:
```
assert.match(out.stderr, new RegExp(`runner: landing turn 1 for decision ${d1.id} \\(vikunja:1/2\\): ok\n[\\s\\S]*runner: session released by the launcher\n`));
```
Only the last line of the pattern changes. The landing-turn part is the same, word for word.
## 4. packages/bus/tests/land.test.mjs:464 (mos-1416)
Old:
```
assert.throws(() => w.call('merge-gate', 'message.receive'), /not-holder/);
```
New:
```
assert.throws(() => w.call('merge-gate', 'message.receive'), /launcher-released/);
```
:457, :463 and :466 are unchanged.
## The not-holder grep, rerun on the build (mos-1414)
`git grep -n "not-holder\|session stopped working\|session-invalid"` over packages/cli, seat and harness
tests and scripts/, outside the new files:
- runner.test.mjs:558, `session stopped working: unauthenticated`. Not a release. Stays.
- runner.test.mjs:628 (a comment) and :647, the limit stop. The limit revoke isn't threadIdle or
landRelease, so it stays not-holder and exit 22 (Dewey Q3).
- session.test.mjs:116, a list of end reasons. No call.
In packages/bus/tests, only end-launch, land and threads call threadIdle or landRelease. Their other
not-holder pins: end-launch:198, threads:383-385 and :392, land:457 and :463 are the ops' own refusals.
threads:493 follows assistant.stop. threads:416 releases a2-run as the test's last line. The fix reaches
none of them, so no hit goes to Mos.
## 5. packages/bus/tests/launcher-released.test.mjs:89, a new test's own line (d6, sage-3294, Mos ruling sage-3293)
This file is new in row 302, so nothing at the base changes. The line changed between the pushed tests
commit f799e8b15 and d6, after the first gate run went red on it (gizmoduck-0388). It's recorded here
because the change narrows what the line counts.
Old:
```
assert.equal(store.get('SELECT count(*) AS n FROM deliveries WHERE message=?', later.id).n, 0, 'nothing delivered to the released run');
```
New:
```
assert.equal(store.get('SELECT count(*) AS n FROM deliveries WHERE message=? AND holder_run=?', later.id, 'a-run').n, 0, 'nothing delivered to the released run');
assert.deepEqual(store.all('SELECT op, holder_run FROM deliveries WHERE message=?', later.id).map((r) => ({ ...r })), [{ op: 'routed', holder_run: null }]);
```
The old line counted every delivery row for the message. `#route` (broker.mjs:6482) writes one routed
row for each message, and `#recipient` (:832-834) gives it holder_run null when no run holds the role.
After threadIdle no run holds thread A, so the count was 1, with no row for a-run. The first new line
keeps the claim it was meant to make: no row names the released run. The second pins the whole set,
one routed row held by nobody. That is tighter than the old line on everything except the null-holder
row, which it requires.
-444
View File
@@ -1,444 +0,0 @@
# Row 302 (#1809, Vikunja 588): the idle-stop race
Owner Gizmoduck. Reviewer Dewey. Gate owner Sage. Brief:
docs/plans/2026-10-23_idle-stop-race-row.md, "Brief: the idle-stop race (Vikunja 588)". Base 0e30a85fa.
This is the design, written static only. Nothing gets built until Dewey approves it (sage-3200).
## The race, as the code has it at 0e30a85fa
- `packages/cli/src/launcher.mjs:703-717`. The idle tick calls the `threadIdle` op. On `released` it adds
the run to `stopping`, records `thread-idle`, and only then sends SIGTERM (:716).
- `packages/bus/src/broker.mjs:1044-1057`. `threadIdle` releases the claim in the same synchronous call
(`#claimEnd(..., 'release', null)`, :1055). The comment at :1040-1043 says the order is deliberate:
row 121 r2, Dewey's F3 in 28591.
- `broker.mjs:1002-1008`. `#agent` is the only place a thread run's own call gets `not-holder`, because
its session's latest claim row isn't a `claim` of its generation. `message.receive` (:5586-5591) and
`state` (:5805-5807) both go through it, and so do `message.send` and `message.read`.
- `packages/harness/src/runner.mjs:55`. `SESSION_GONE` holds `unauthenticated`, `not-holder` and
`run-ended`. Four sites set `code = EXIT.session` (22) on any of them, without checking `stopping`:
the landing `state` (:500-506), `message.receive` (:526-531), the turn's `state` (:545-552) and the
reply (:575-582).
- `packages/seat/src/session.mjs:340` maps 22 to `session-invalid`.
So if a runner call reaches the broker after the release and before SIGTERM sets `stopping`, the run
exits 22 by itself and ends `session-invalid`. A call already in flight when the release lands counts
too. Row 292's diagnostic saw this once in about 100 idle stops. The clear test's run r846b8d083502 logged
`not-holder` and then `exiting 22`.
## Design: a distinct answer for a run the idle stop released (Mos's suggestion, adopted)
### Broker (`packages/bus/src/broker.mjs`)
1. Add a new in-memory set, `#idled`, keyed `business:run`, next to `#ended`, `#received` and `#stops`.
`threadIdle` adds the run's key in the same synchronous call that releases it, and only when it
returns `{released:true}`. Release and mark happen together, so no call can be answered between them.
2. In `#agent`, the refusal becomes
`fail(this.#idled.has(s.business + ':' + s.run) ? 'idle-released' : 'not-holder')`. Nothing else in
`#agent` changes. A run the idle stop released now gets `idle-released` at every call after the
release, whether it's a receive, `state`, a send or a read, and whether or not another run has
claimed the session since. Every other path that takes a claim away still answers `not-holder`:
- `assistant.stop` (:5975), `instance.end` (:6009), the chief lifecycle revoke (:4682) and
`role.revoke` (:5230, :5235)
- the session clear (:1146)
- the limit stop (`#limitStop`, :4842-4855). It releases a thread claim and then refuses
`not-holder` on purpose, so that the run exits 22.
- another run's newer generation, where the run wasn't idle-released
3. `endLaunch` (:1300) drops the key along with `#ended.add`. After the end, the run's caps are gone and
its calls answer `unauthenticated`, as they do today. The set lives only in memory, like `#runs`. A
broker that restarts loses `#runs` too, so an old run's calls answer `unauthenticated` there either
way.
4. `threadIdle`'s own refusals don't change. A second `threadIdle` on a released run is still
`not-holder` (threads.test:392). The answer comes from the `#agent` path only, for the run's own
calls.
Why a new code and not a flag on `not-holder`: the wire carries only `error: <code>`
(server.mjs:96-160), and the client accepts only `^[a-z-]{1,64}$` (client.mjs:42-43). A new code changes
neither of them. Tools and docs that switch on `not-holder` keep their meaning, because `not-holder`
still means "your claim was taken away".
### Runner (`packages/harness/src/runner.mjs`)
5. A new constant, `IDLE_RELEASED = "idle-released"`. It is not added to `SESSION_GONE`. At each of the
four sites, `idle-released` is checked before `SESSION_GONE`. The runner logs
`runner: session released by the launcher's idle stop`, leaves `code` at `EXIT.stopped` (0), sets a
local `released`, and leaves the loop the same way the site does for `SESSION_GONE` today.
6. The `role.release` at exit (:589-595) is skipped when `released`. The claim is already released, so
the call would only be refused and logged.
7. If the runner didn't handle the code, the receive loop would count `idle-released` as an
unreachable broker and retry (:532-537). The run would then end at SIGTERM (0), or after 30 polls
(23). Every site handles it so that neither of those decides how the run ends.
How this meets mos-1411 condition 1: `unauthenticated` (the caps went at the end), `run-ended`, and every
`not-holder` that isn't an idle release still exit 22 and end `session-invalid`. Only the broker's own
record that `threadIdle` released this run maps to `stopped/0`. The launcher's `stopping` set and SIGTERM
play no part in the mapping. That also covers a poll that lands before the signal, and a call that was
in flight when the release landed.
### Launcher and session.mjs
8. No change. The runner exits 0 by itself, and SIGTERM's start-time check (:716) then finds no process,
which the code already handles. `endReason(0)` is `stopped`.
## Tests
### The forcing test (mos-1411 condition 2): new file `packages/cli/tests/idle-stop-race.test.mjs`
This is a thread launch on the same fixture shape as thread-launch.test.mjs (`start(t, prepared, { ops })`
replaces launch ops, :78-101), with `sessionDefaults.pollInterval` set to 100. The test replaces the
`threadIdle` op:
```js
threadIdle: async (m) => {
const r = runtime.threadIdle(m.record);
if (r.released) window.set(m.record.run, await held(m.record.run)); // returns only after the runner's own exit, or 20 s
return r;
}
```
`held(run)` waits for two things, in order. First, an `action.refused` event whose actor is `run` and
whose seq is after the release's `thread_claims` row. That proves a runner call reached the broker inside
the window. Second, the runner's own exit (the run's `runner: exiting N` line in runner.log, or its pid
gone), with no SIGTERM sent. The launcher sends SIGTERM only after the op returns, so the window stays
open until the runner has decided how it ends. The test then asserts all of the following:
- `held` saw a refusal from the run after the release, and the runner exited before the op returned.
- The refusal's code is `idle-released`.
- The run's launch `end` event is `['stopped', 0, null]`.
- runner.log has the idle-released line and no `session stopped working:` line.
Against the code today, the refusal is `not-holder`, the runner exits 22 inside the window, and the end
is `['session-invalid', 22, null]`. The test fails, and fails every time, not at some rate: the
window is held open until a call has landed in it. If the runner fix is dropped, the runner retries and
doesn't exit inside the window, so `held` times out and the "exited before the op returned" assertion
fails. If the broker fix is dropped, the end is 22.
A control test in the same file: after an idle release, a `role.revoke` the human approved on another
thread's run (or `assistant.stop`) still ends that run `['session-invalid', 22, null]`. That shows a
real not-holder still exits 22.
### Bus: new tests in `packages/bus/tests/idle-release.test.mjs` (a new file, so no existing assertion moves)
- After `threadIdle` releases a-run, a-run's `message.receive`, `state`, `message.send` and
`message.read` each refuse `idle-released`. Each writes an `action.refused` event with code
`idle-released`, and none of them delivers a message or writes a receipt.
- `not-holder` still comes back for: a run released by `assistant.stop`, a run released by a session
clear, a limit stop (stop then receive), a run whose session another run claimed without any idle
release, and a second `threadIdle` on a released run. After `endLaunch`, the idle-released run's
calls get `unauthenticated`, as today (its caps go at :1310-1311).
- A role run's `role.release` followed by its own receive still gets `not-holder` (no idle).
### Harness: no new runner.test case
runner.test.mjs's `setup` (:105) binds role runs only, and its claims sit in `role_claims` (:876), so it
can't reach `threadIdle`. The runner's own exit at receive is covered by the cli forcing test above,
which runs the real runner. The forcing test reaches only the site that lands in the window, which in
practice is the receive poll. The landing `state`, the turn's `state` and the reply sites get the same
four lines, but no test forces each one. Q4 asks whether Dewey wants a per-site case. The existing 22
tests (:539-560, :630-647, :772) stay unchanged and pass unchanged.
## The one existing assertion that changes (goes to Mos through Sage, per the brief)
`packages/bus/tests/threads.test.mjs:394`,
`assert.throws(() => call('a', 'message.receive'), { code: 'not-holder' })`. This is a receive by the run
that `threadIdle` released at :388, so under this design it answers `idle-released`. The assertion is
changed, not loosened: the new pin is `{ code: 'idle-released' }`, and the property right below it
(:395, the message stays `pending` for the next holder) stays. I've found no other existing assertion
that pins `not-holder` for an idle-released run's own call. The build reruns
`git grep -n "not-holder" 'packages/*/tests/*'` against every idle path before in-review, and names any
other hit for Mos first.
## Docs
- packages/bus/README.md:320-326 (threadIdle). Add: after a release, the run's own calls answer
`idle-released`, not `not-holder`. Also say why.
- packages/harness/README.md:295-302, the exit table. Row 0 becomes "stopped, by a signal, or because the
launcher's idle stop released the session (`idle-released`)". Row 22 is unchanged.
- packages/bus/README.md:207 (`assistant.stop`): no change. It still gives `not-holder`.
## Open questions for Dewey
- Q1. `landRelease` (broker.mjs:4144-4165, launcher.mjs:876-889) has the same shape for a role run's
land-relaunch: it releases, then the launcher sends SIGTERM, so a poll in between ends the run 22. I
recommend folding it in. That means one line in `landRelease` (add to `#idled` on release), one bus
assertion, and one cli forcing case like the one above. It falls outside this brief's words, so it
needs Sage's yes. If the answer is no, I'll write it up as a follow-up row with the same evidence.
- Q2. The code name `idle-released`. It names the cause, and if Q1 is yes it covers land-relaunch too,
since that is also a release made by the launcher. A more general name like `launcher-released` would
fit both. I prefer `released-by-launcher` only if Q1 is yes. Dewey picks.
- Q3. A limit stop on a run that was already idle-released. `#limitStop` (:4842-4855) finds no claim to
end and refuses `not-holder`, so the run ends 22. I'd leave that alone: a limit hit is a real stop and
ends session-invalid, as it does today. It's possible only if the limit checker answers inside the
window.
- Q4. Per-site coverage in the runner. Only the receive site is forced. I can add a cli case per site
(hold the window until the run's landing `state`, or a turn's `state`, lands in it), at about one
fixture each. I'd add them only if Dewey asks, since all four sites share one helper in the build.
## Gate (brief)
Dewey approves this design, then the manifest. Runs: the new forcing test, then
compactions-launch.test.mjs whole, then the bus, cli and harness suites whole, then every
`scripts/test-*.sh`. The mos-1411 point 4 rerun rule doesn't apply to this row's own gate.
Mutants. Each one must die on the forcing test, with the bus test also named where it applies:
- M1. `threadIdle` doesn't add to `#idled`. Dies on the forcing test (end 22) and the bus test.
- M2. `#agent` ignores `#idled`. Same deaths as M1.
- M3. The runner drops the `idle-released` branch at receive. Dies on the forcing test (no exit inside
the window).
- M4. The runner maps `idle-released` to `EXIT.session`. Dies on the forcing test (end 22).
- M5. `#claimEnd` marks every release, not just threadIdle's. Dies on the bus not-holder controls and
the cli control.
- M6. `endLaunch` doesn't drop the key. This is not a correctness mutant: caps are gone, so the answer
is `unauthenticated` either way. I'll drop it unless Dewey wants an assertion on it, and record it as
an equivalent mutant.
Limits will be set in the run plan after the design round (mos-1275: `timeout -k 10` at three times or
more the longest run).
## After Dewey's d1 review (dewey-0875, 05:32Z): APPROVE on D1, folded here before any build
D1 (required). role.claim's thread branch (broker.mjs:5154-5173) doesn't go through `#agent` and
refuses only `run-revoked`, the session fence and `thread-already-held`. So an idle-released run could
claim its free session again. Its key would still be in `#idled`, and a later real not-holder on that
claim would answer `idle-released` and exit 0. Fix: the thread branch of role.claim refuses
`idle-released` for a run in `#idled`, before the insert. The key stays, because the run's claim is over.
Bus assertion: after threadIdle releases a-run, a-run's role.claim refuses `idle-released`, and no
thread_claims row is added. Mutant M7: drop that check. It dies on that assertion.
Correction to "Harness: no new runner.test case". That's true for threadIdle only. runner.test reaches
landRelease, which is a role-run path: :742-772 releases coder-run with `ctx.broker.landRelease` and no
launcher, and pins `out.code === EXIT.session` (:771) and `session stopped working: not-holder` (:772).
If Q1 is yes, those two lines change (to stopped/0 and the released line). They go to Mos through Sage
with threads.test:394, and runner.test:742-772 then serves as the land-relaunch forcing case. No launcher means no
SIGTERM, so the receive always lands after the release. The cli case for land-relaunch is dropped. If Q1
is no, the follow-up row cites runner.test:771-772 as its evidence.
Q2. The code is `launcher-released` if Q1 is yes, and `idle-released` if Q1 is no. Every name in this
file reads that way.
Q3. Agreed. A limit stop on an idled run stays not-holder and exits 22.
Q4. No per-site cases. Both ops return `released:false` while a delivered message is unread
(threadIdle via `t.unread`, landRelease via its count). The runner reads only after the reply
(runner.mjs:575-580), so a run can't be released mid-turn. landRelease keeps a run that hasn't received
yet (`landing:true`), and thread runs have no landing. So only the receive site can see the code. All
four sites keep the shared helper, and the three unreachable ones get a one-line comment saying why.
N1. The cli control must reach the runner before any launcher signal. It uses a role.revoke on the run
(no launcher stop), or holds the signal the same way the forcing test does. assistant.stop gets checked
first in case it goes through a launcher stop. It also asserts the run's runner.log has
`session stopped working: not-holder` and `exiting 22`.
N2. The control keeps "after an idle release", so `#idled` isn't empty when M5 runs.
N3. M6 is equivalent. The key drop in endLaunch stays, so the set doesn't grow.
N4. The other-pin grep also covers runner.test `session stopped working`. :558 (unauthenticated) and
:647 (revoke) stay, and :772 changes only under Q1.
Docs: if Q1 is yes, landRelease joins the bus README line and the harness exit-table row 0.
## Round d2 (sage-3204, 05:32Z)
Line numbers. Sage's check against 0e30a85fa is right, and the references above are now corrected. The
second threadIdle not-holder pin is threads.test:392 and stays. The receive pin that changes is :394,
and the pending check is :395 and stays. The idle release is at :388.
Sage asked for a grep of the land-relaunch tests for a not-holder pin on the relaunched run's own call.
`git grep -l "landRelease\|land-relaunch" 'packages/*/tests/*'` lists 8 files. In those files,
`not-holder|session stopped working|EXIT.session|session-invalid` hits only land.test.mjs and
runner.test.mjs:
- land.test.mjs:464, `assert.throws(() => w.call('merge-gate', 'message.receive'), /not-holder/)`. This is
the released run's own receive after `landRelease` released it (:458). Under Q1 yes, it answers
`launcher-released`, and the regex fails. That's a third old-test change for Mos through Sage. The new
pin is `/launcher-released/`.
- land.test.mjs:457 (a non-holder run's landRelease) and :463 (a second landRelease) are landRelease's
own refusals. They stay not-holder, the same as threads.test:392.
- runner.test.mjs:771-772 change under Q1, as in the section above. runner.test.mjs:548, :557-558 and
:646-647 are unauthenticated, unauthenticated and a limit stop. They stay.
- The six cli files have no hit.
So under Q1 yes, the Mos package is threads.test:394, land.test:464 and runner.test:771-772. Under Q1 no,
it's threads.test:394 alone. Nothing gets built until Mos rules and Sage gives the go.
## Round d3: as built (after mos-1414/1415/1416 and sage-3220)
Q1 is yes, so the code is `launcher-released` everywhere. The broker set is `#launcherReleased`, not
`#idled`. Every `idle-released` above reads `launcher-released`.
### Correction to d1: message.send doesn't go through `#agent`
d1 said `message.send` and `message.read` both go through `#agent`. `message.read` does. `message.send`
doesn't. So a released run's send isn't refused `launcher-released`. Only `message.receive`, `state`,
`message.read` and `role.claim` answer it, and the bus test asserts exactly those four. That narrows
what Dewey approved in d1, so I'm sending it to Dewey directly (sage-3220).
### Broker (packages/bus/src/broker.mjs)
- `#launcherReleased = new Set()`, keyed `business:run`, next to `#stops`, with a comment.
- threadIdle and landRelease add the key after their release transaction.
- `#agent` refuses `launcher-released` for a run in the set, and `not-holder` otherwise.
- role.claim (D1) refuses `launcher-released` right after the `agent-required` check, before the thread
and role branches. So it covers landRelease's role runs as well as thread runs.
- endLaunch deletes the key after `#ended.add(key)`.
- Q3 needs no code. A limit stop runs `#limitStop` (broker.mjs:4482) before any `#agent` check, and it
fails `not-holder` itself (:4862), so a limit stop after a launcher release still exits 22.
### Runner (packages/harness/src/runner.mjs)
- `const LAUNCHER_RELEASED = "launcher-released"`.
- The shared helper `ended(err, say = true)`. For `launcher-released`, it logs
`runner: session released by the launcher`, sets `released` and leaves the exit code at
`EXIT.stopped`. For the SESSION_GONE codes it keeps the old behaviour (`EXIT.session`, and the log
line unless `say` is false).
- It's used at the landing state check, receive, the turn state check and the reply. The reply site
passes `say = false`, so its logging is the same as before. The three sites that can't see the code
(Q4) carry a comment saying why.
- At exit, the final `role.release` is skipped when `released`, because the launcher already released.
### Tests as built
- `packages/cli/tests/idle-stop-race.test.mjs`. This is the threadIdle forcing case. Inside the first
released run's held threadIdle op, the human's `assistant.stop` revokes the other thread's holder
(N1: no launcher signal can come while the op is held, launcher.mjs:662-663). The op waits for both
runners' verdicts and end events. The idle run logs `session released by the launcher`, ends
`["stopped", 0, null]` before its thread-idle line, and has `exiting 0` and no `session stopped working`.
The control logs `session stopped working: not-holder`, ends `["session-invalid", 22, null]` and
has `exiting 22`. The Store shows `launcher-released` and no `not-holder` refusals for the idle run,
and `not-holder` for the control.
- `packages/bus/tests/launcher-released.test.mjs` (renamed from idle-release.test.mjs). It has three
tests. (1) threadIdle: receive, state, read and role.claim refuse `launcher-released`, role.claim adds
no thread_claims row, the four refusals are logged, nothing is delivered, threadIdle's own second
refusal stays not-holder, and after endLaunch the answer is unauthenticated. (2) The control (N2:
after an idle release): assistant.stop's run answers not-holder and run-revoked, pm's own role.release
answers not-holder, and a new holder for the released thread doesn't change the released run's answer.
(3) landRelease: receive and state refuse `launcher-released`, role.claim refuses and adds no
role_claims row, landRelease's own second refusal stays not-holder, and coder's own role.release
answers not-holder.
- runner.test.mjs:742-772 is the land-relaunch forcing case (mos-1415). There's no cli land-relaunch case.
- The four old lines Mos ruled are in ASSERTION-PRESERVATION.md. The diff on old test files is those four
lines and nothing else.
### Docs
The bus README's threadIdle paragraph names `launcher-released`, the four calls that answer it,
landRelease, and that every other lost claim stays not-holder. The cli README's land-relaunch paragraph
says calls between the release and the signal refuse `launcher-released` and the runner exits 0. The
harness README's exit table row 0 names the launcher release.
### Red first (mos-1415)
There are two commits. The first holds only the tests and the four ruled pin edits. The second holds the
fix (broker.mjs, runner.mjs) and the READMEs. The gate's first stage runs on the tests-only commit, and
these two must fail there:
- idle-stop-race.test.mjs: the idle run ends `["session-invalid", 22, null]`, or its verdict is
`session stopped working: not-holder`, whichever lands first.
- runner.test.mjs, the case at :742: out.code is 22, not 0.
The bus test files and threads.test:394 and land.test:464 fail there too, and the packet records them.
The red run doesn't count as the gate.
### Mutants (each run against the fix commit, restored and checked by sha256 after)
- M1. threadIdle doesn't add the key. Dies: idle-stop-race (end 22), launcher-released.test test 1,
threads.test:394.
- M2. `#agent` ignores the set. Dies: the same as M1, plus launcher-released.test test 3,
land.test:464 and runner.test:771.
- M3. The runner's helper drops the `launcher-released` branch. Dies: idle-stop-race (the run doesn't
exit in the window, so `window.idle` is null) and runner.test:771-772.
- M4. The runner maps `launcher-released` to `EXIT.session`. Dies: idle-stop-race (end 22) and
runner.test:771.
- M5. `#agent` answers `launcher-released` for every lost claim. Dies: the idle-stop-race control
(verdict and end 22), launcher-released.test test 2, and test 3's coder line.
- M6. endLaunch doesn't drop the key. Equivalent (N3), not run.
- M7. role.claim drops the D1 check. Dies: launcher-released.test tests 1 and 3 (the claim succeeds).
- M8. landRelease doesn't add the key. Dies: runner.test:771-772, land.test:464 and
launcher-released.test test 3.
### Run plan (mos-1275 limits, `timeout -k 10`)
1. idle-stop-race.test.mjs alone, 600 s. Then runner.test.mjs whole, 900 s.
2. compactions-launch.test.mjs whole, 600 s.
3. The bus, harness and cli suites whole: bus 1200 s, harness 1200 s, cli 2100 s. 292's cli suite took
630 s.
4. Every scripts/test-*.sh, 900 s each.
5. M1-M5, M7 and M8, each on its named files at the limits above.
TMPDIR comes from `mktemp -d /mnt/storage/scratch/tmp/gXXX`. Every run is slot work and starts only on a
CLEAR from Sage.
## Round d4: Dewey's early static read (dewey-0878, 05:47Z)
C1. The d3 "correction" about message.send was wrong, and d1 was right. `message.send` calls
`#consumeAuthority` (broker.mjs:5506), which calls `#checkAuthority`, which calls `#agent` (:3749).
So a released run's send refuses `launcher-released`, and so does every verb that reaches `#agent`. There
are 29 call sites, including role.release and every authority check. role.claim refuses it before the
claim (D1). I misread the send path in d3, and no code depended on that reading. The runner's reply site
already handles the code. The bus README now says "every call that needs the claim", not a list of four.
Bus test 1 adds a message.send refusal, so the refused list is five `launcher-released`.
N1. Nothing killed a mutant that drops `&& !released` at runner exit (runner.mjs:596). That run calls
role.release, logs `runner: role.release: launcher-released` and still exits 0. idle-stop-race now
asserts the idle run's runner.log has no `runner: role.release:` line.
- M9. Drop `&& !released` at runner.mjs:596. It dies on idle-stop-race (the new doesNotMatch).
N2. idle-stop-race waits for the whole held window (`"revoked" in window`), then asserts
`window.control` is non-null with a message. If the other thread's run isn't holding when A's first
release lands, the test now fails with that message instead of a bare "timed out waiting".
The mutants to run are M1-M5, M7, M8 and M9. These test edits are in a third commit, after the fix.
ad9fa9f16 stays the red-first commit for the two forcing cases mos-1415 names.
## Round d5: red-first reordered (sage-3225, 05:49Z)
Sage pointed out that 8cf2c6d54 changed idle-stop-race.test.mjs and launcher-released.test.mjs after
ad9fa9f16. So a red run on ad9fa9f16 would test older copies than the ones that land. I took the first of
Sage's two options and reordered the commits locally, before any push. The order is now:
1. Tests: the final test files and this packet, over unfixed product files.
2. The fix: broker.mjs, runner.mjs and the three READMEs.
ad9fa9f16, 6e5f782ae and 8cf2c6d54 are superseded and were never pushed. The old tip is kept locally as
gizmoduck/row302-pre-reorder. The fix commit's tree matches 8cf2c6d54's except for this BUILD.md note.
The "third commit" in d4 now lives in these two commits.
The red run uses the tests commit as it stands, with these test blobs (identical in the fix commit):
| Blob | File |
| --- | --- |
| 52343932b231691ba2b4fc117547ea7f6f504704 | packages/bus/tests/land.test.mjs |
| 6c83c9ede41247fd50d40eeac3e8a16a75efacbf | 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 |
The red run checks these blobs with `git rev-parse HEAD:<path>` before it starts.
## Round d6: the first gate run's red in launcher-released.test.mjs:89 (gizmoduck-0388, sage-3294)
The slot opened at 08:15Z (sage-3289). The gate tree was 649ec67ab, a local merge of 64f6558ee onto
origin/refactor 1ac655005. The red stage on f799e8b15 passed: seven expected reds, with the pins at
threads.test.mjs:394, land.test.mjs:464 and runner.test.mjs:771 (:772 sits behind :771 in one test).
On 649ec67ab, idle-stop-race 1/1, runner.test 40/40 and compactions-launch 5/5 went green. The bus
suite then had 875 of 876 pass. The one red was this row's own test, at launcher-released.test.mjs:89,
1 !== 0. The gate stopped there, and the red went to Sage before any fix or rerun.
The test was wrong. `#route` (broker.mjs:6482) writes one routed delivery row for every message.
After threadIdle no run holds thread A, so `#recipient` (:832-834) returns null and `#delivery`
(:6612) writes holder_run null. The line counted every row for the message. Nothing was delivered to
a-run. ASSERTION-PRESERVATION.md entry 5 has the old and new lines.
The fix narrows the count to rows for a-run and adds the line Sage made mandatory: the message has
exactly one row, routed, holder_run null. bus rows come from node:sqlite with a null prototype, and the
tests use assert/strict, so the second line spreads each row before deepEqual. That is the idiom in
sessions.test.mjs:385 and session-clear.test.mjs:564. Sage's draft compared store.all directly, which
would fail on the prototype alone.
Packaging (sage-3294): this is a third commit on gizmoduck/row302 after the pushed f799e8b15 and
64f6558ee. It touches only that test line, this note and ASSERTION-PRESERVATION.md. It goes out as a
fast-forward push in a gap Sage names, after Mos rules (sage-3293). Then:
1. The red run uses the final test files over f799e8b15's product: f799e8b15 checked out detached, with
the five test files from the new tip checked out on top. The script checks the new blobs first.
2. The whole gate runs again on a fresh merge of the new tip onto origin/refactor.
Dewey reviews the delta. The first run's logs stay in gizmo-302-out/gate-run1/.
-112
View File
@@ -1,112 +0,0 @@
# 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.
@@ -1,57 +0,0 @@
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
@@ -1,187 +0,0 @@
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
@@ -1,47 +0,0 @@
#!/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")
@@ -1,147 +0,0 @@
#!/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")"
-82
View File
@@ -1,82 +0,0 @@
# Row 305 (#1812, Vikunja 591): shell suites remove the compose network they create
Owner Gizmoduck. Reviewer Filbert. Gate owner Sage. Brief:
docs/plans/2026-10-23_gate-env-rows.md, "Brief: shell suites remove the compose network they create
(Vikunja 591)", at c16e943b9. Base c16e943b9. Mos approved the change in mos-1442 point 2. Mos approved
the two new checks in mos-1445 under mos-1272, adding the presence half.
## The leak, as the code has it at c16e943b9
- `packages/processing-control/src/containers.mjs:16-19`. `containerArgs` builds
`docker compose run --rm ...`. `--rm` removes the container. The project's `<project>_default`
network stays.
- `compose.yaml` has no top-level `name:`, so compose names the project after the checkout
directory. Every gate worktree left one network. By 10-23 they had used up Docker's address pools.
## Does COMPOSE_PROJECT_NAME reach compose? Yes, on every path the two suites take
- Task path. `scripts/run-task.sh:29` execs `node scripts/mosaic-task.mjs`. Nothing scrubs the env
before that: `scripts/common.sh` has no `env -i`, no `unset` and no COMPOSE. `mosaic-task.mjs:326`
sets `spawnEnv = { ...process.env }`, `:405` passes `env: spawnEnv` to `runContainer`, and
`containers.mjs:25` passes those options to `spawnSync('docker', ...)`.
- test-release. `release.sh activate` calls `health_check`, and `health_check` calls `run-task.sh`
at `:54`, which is the task path above. `env MOSAIC_MOCK_RESPONSE=...` adds to the env and keeps
the rest. The suite calls only `status`, `activate` and `rollback`, so `release.sh:122`
`compose build` is off its path.
- test-task seat cases (`:240`, `:315-351`). `agent.sh:209` execs
`packages/processing-control/src/container-cli.mjs`, and `container-cli.mjs:16` calls
`runContainer` with `env: process.env`.
- `build.sh:13`, `release.sh:122` and `verify.sh:40` also run compose. Neither suite calls them.
## Change (scripts/test-release.sh, scripts/test-task.sh only)
- After `SANDBOX="$(mktemp -d)"`, export
`COMPOSE_PROJECT_NAME=mosaic-test-<release|task>-<id>`. `<id>` is the sandbox name after its last
dot, lowercased, alphanumeric only.
- `remove_compose_network` runs `docker network rm "${COMPOSE_PROJECT_NAME}_default"`:
- If there's no docker binary, it returns 0.
- If the error says `not found` or `No such network`, it returns 0.
- On any other failure it prints one stderr line naming the network, then returns 0. That
includes a daemon that is down. Sage kept that line in sage-3367 (a).
- Each existing EXIT trap keeps everything it did and gains `; remove_compose_network` at the end.
The trap's own exit status doesn't change the script's.
- One new check per suite, just before the summary. That is after the last Docker step whether or
not the live cases ran. Both halves sit inside a `docker info` branch:
- the network is present under the run's project name before the explicit
`remove_compose_network` (this proves the export reached compose);
- after the remove, it is absent.
A failing `docker network ls` fails the check. Without the daemon, the check prints a skip line.
- No `docker compose down`, and no other network is touched. No product file changes.
Commits: 541dee2b7 (draft), 3bce852d5 (presence half, mos-1445).
## Gate (Sage's slot, in a gap)
- Before the first run, run `docker network rm` on a name that was never created and record the
daemon's exact wording (sage-3367 b). If the wording matches neither pattern, stop and report to
Sage.
- Each suite runs whole from a gate worktree, under `timeout -k 10 900`. That is far more than
3x the row 302 gate's walls: test-release 3 s, test-task 16 s (mos-1275).
- TMPDIR comes from `mktemp -d /mnt/storage/scratch/tmp/gXXX`.
- Before and after each run, record `docker network ls` filtered to `mosaic-test-`. The run's
network must be absent after.
- Grep `^skip` and name every skip.
- A run killed by the timeout's SIGKILL skips the EXIT trap and leaks its one network. The name is
per-run under `mosaic-test-`, so the gate's after-listing finds it and removes it by its exact name
(Filbert N1; no code change).
- If `docker info` works but there is no network to find, that's a first-run red. It goes to Sage
for Mos, unfixed (mos-1445).
## Mutants (mos-1445)
- (a) Drop the export. The new check must go red, because compose uses the directory's project and
nothing exists under the run's name.
- (b) Make the function's `docker network rm` a no-op. The new check must go red, because the
network is still present after the remove.
- (c) Drop `remove_compose_network` from the trap. This one is a known survivor: the explicit call
covers the normal path, and the trap covers early exits.
Each mutant runs on an isolated copy of the file. Restores are checked by sha256. After each mutant, the network it
leaves is removed by its exact name (mos-1438). Mutant (a) leaves the worktree directory's
`<dir>_default`, and mutant (b) leaves the run's `${COMPOSE_PROJECT_NAME}_default`.
@@ -1,88 +0,0 @@
start 2026-10-23T11:14:01Z HEAD 8ddba89b7 refactor b99ca86b9 docker 29.7.2
== wording
rc=1 stderr: Error response from daemon: network mosaic-test-absent-46829331_default not found
exit status 1
== green
TMPDIR /mnt/storage/scratch/tmp/gIj4
nets[before test-task]:
test-task rc=0 wall 16 s :: selftest: 92 passed, 0 failed
OK compose network made under the run's project and removed after the run
skip: skip live provider cases (row 244: no provider call in the gate)
skip: skip live provider cases (row 244: no provider call in the gate)
nets[after test-task]:
TMPDIR /mnt/storage/scratch/tmp/gDYF
nets[before test-release]:
test-release rc=0 wall 4 s :: selftest: 15 passed, 0 failed
OK compose network made under the run's project and removed after the run
nets[after test-release]:
== mutants
Ma scripts/test-task.sh | 2 +-
TMPDIR /mnt/storage/scratch/tmp/g6SN
nets[before Ma-task]:
Ma-task rc=1 wall 16 s :: selftest: 91 passed, 1 failed
FAIL compose network made under the run's project and removed after the run
red: FAIL compose network made under the run's project and removed after the run
skip: skip live provider cases (row 244: no provider call in the gate)
skip: skip live provider cases (row 244: no provider call in the gate)
nets[after Ma-task]: gizmo-305_default
restore ok scripts/test-task.sh
Ma-task KILLED
cleaned gizmo-305_default
nets[after cleanup Ma-task]:
Ma scripts/test-release.sh | 2 +-
TMPDIR /mnt/storage/scratch/tmp/g48Q
nets[before Ma-release]:
Ma-release rc=1 wall 3 s :: selftest: 14 passed, 1 failed
FAIL compose network made under the run's project and removed after the run
red: FAIL compose network made under the run's project and removed after the run
nets[after Ma-release]: gizmo-305_default
restore ok scripts/test-release.sh
Ma-release KILLED
cleaned gizmo-305_default
nets[after cleanup Ma-release]:
Mb scripts/test-task.sh | 2 +-
TMPDIR /mnt/storage/scratch/tmp/gcm1
nets[before Mb-task]:
Mb-task rc=1 wall 15 s :: selftest: 91 passed, 1 failed
FAIL compose network made under the run's project and removed after the run
red: FAIL compose network made under the run's project and removed after the run
skip: skip live provider cases (row 244: no provider call in the gate)
skip: skip live provider cases (row 244: no provider call in the gate)
nets[after Mb-task]: mosaic-test-task-pf33rz8tic_default
restore ok scripts/test-task.sh
Mb-task KILLED
cleaned mosaic-test-task-pf33rz8tic_default
nets[after cleanup Mb-task]:
Mb scripts/test-release.sh | 2 +-
TMPDIR /mnt/storage/scratch/tmp/gSxg
nets[before Mb-release]:
Mb-release rc=1 wall 3 s :: selftest: 14 passed, 1 failed
FAIL compose network made under the run's project and removed after the run
red: FAIL compose network made under the run's project and removed after the run
nets[after Mb-release]: mosaic-test-release-db4p70csnf_default
restore ok scripts/test-release.sh
Mb-release KILLED
cleaned mosaic-test-release-db4p70csnf_default
nets[after cleanup Mb-release]:
Mc scripts/test-task.sh | 2 +-
TMPDIR /mnt/storage/scratch/tmp/g6WJ
nets[before Mc-task]:
Mc-task rc=0 wall 16 s :: selftest: 92 passed, 0 failed
OK compose network made under the run's project and removed after the run
skip: skip live provider cases (row 244: no provider call in the gate)
skip: skip live provider cases (row 244: no provider call in the gate)
nets[after Mc-task]:
restore ok scripts/test-task.sh
Mc-task survived (known)
nets[after cleanup Mc-task]:
Mc scripts/test-release.sh | 2 +-
TMPDIR /mnt/storage/scratch/tmp/g2jz
nets[before Mc-release]:
Mc-release rc=0 wall 3 s :: selftest: 15 passed, 0 failed
OK compose network made under the run's project and removed after the run
nets[after Mc-release]:
restore ok scripts/test-release.sh
Mc-release survived (known)
nets[after cleanup Mc-release]:
tree clean after mutants
end 2026-10-23T11:15:17Z
@@ -1,60 +0,0 @@
#!/usr/bin/env bash
# Row 305 gate (sage-3374): wording, both suites whole, mutants a/b/c with exact-name cleanup.
set -uo pipefail
WT=/mnt/storage/scratch/gizmo-305
OUT=/mnt/storage/scratch/gizmo-305-out/gate
mkdir -p "$OUT"
cd "$WT" || exit 9
[ "$(git rev-parse HEAD)" = 8ddba89b7442f09fc71cf24d7f250e40a7f60fdf ] || { echo "HEAD drift"; exit 9; }
[ -z "$(git status --porcelain)" ] || { echo "dirty tree"; exit 9; }
[ -L node_modules ] || ln -s /mnt/storage/src/mosaic-stack/node_modules node_modules
[ -L node_modules ] || { echo "no node_modules link"; exit 8; }
DIRNET=gizmo-305_default
nets() { echo " nets[$1]: $(docker network ls --format '{{.Name}}' | grep -E '^(mosaic-test-|gizmo-305_)' | tr '\n' ' ')"; }
newtmp() { export TMPDIR="$(mktemp -d /mnt/storage/scratch/tmp/gXXX)"; echo " TMPDIR $TMPDIR"; }
run() { # name script
local name=$1 s=$2; newtmp; nets "before $name"
local t0=$SECONDS
timeout -k 10 900 "$s" > "$OUT/$name.log" 2>&1; local rc=$?
echo "$name rc=$rc wall $((SECONDS-t0)) s :: $(grep -E '^selftest:' "$OUT/$name.log")"
[ $rc -eq 124 ] || [ $rc -eq 137 ] && echo "SHELL-PHASE TIMEOUT (mos-1275): to Mos unplaced"
grep -E 'compose network' "$OUT/$name.log" | sed 's/^/ /'
grep -E '^FAIL|could not remove' "$OUT/$name.log" | sed 's/^/ red: /'
grep -E '^skip' "$OUT/$name.log" | sed 's/^/ skip: /'
nets "after $name"
LASTRC=$rc
}
echo "start $(date -u +%FT%TZ) HEAD $(git rev-parse --short HEAD) refactor $(git rev-parse --short origin/refactor) docker $(docker version --format '{{.Server.Version}}')"
echo "== wording"
ABS="mosaic-test-absent-$RANDOM$RANDOM"_default
docker network rm "$ABS" >/dev/null 2>"$OUT/absent.txt"; echo " rc=$? stderr: $(cat "$OUT/absent.txt")"
grep -qE 'not found|No such network' "$OUT/absent.txt" || { echo "STOP: wording matches neither pattern"; exit 3; }
echo "== green"
for s in task release; do run "test-$s" "scripts/test-$s.sh"; [ $LASTRC -eq 0 ] || { echo "STOP: red on green run"; exit 4; }; done
nets "after green" | grep -qE 'mosaic-test-|gizmo-305_' && { echo "STOP: network left after green"; exit 5; }
echo "== mutants"
mut() { # tag python-edit expected(red|green)
local tag=$1 edit=$2 want=$3
for s in task release; do
local f="scripts/test-$s.sh" sum; sum=$(sha256sum "$f" | cut -d' ' -f1)
cp -p "$f" "$OUT/$s.orig"
python3 -B -c "$edit" "$f" || { echo "mutant $tag edit failed"; exit 6; }
git diff --stat -- "$f" | head -1 | sed "s/^/ M$tag /"
run "M$tag-$s" "$f"
cp -p "$OUT/$s.orig" "$f"
[ "$(sha256sum "$f" | cut -d' ' -f1)" = "$sum" ] && echo " restore ok $f" || { echo "RESTORE MISMATCH $f"; exit 7; }
if [ "$want" = red ]; then grep -q '^FAIL.*compose network' "$OUT/M$tag-$s.log" && echo " M$tag-$s KILLED" || echo " M$tag-$s SURVIVED (unexpected)"
else grep -q '^OK.*compose network' "$OUT/M$tag-$s.log" && echo " M$tag-$s survived (known)" || echo " M$tag-$s unexpected red"; fi
# exact-name cleanup (mos-1438)
for n in $(docker network ls --format '{{.Name}}' | grep -E '^(mosaic-test-(task|release)-[a-z0-9]+_default|gizmo-305_default)$'); do
docker network rm "$n" >/dev/null && echo " cleaned $n"
done
nets "after cleanup M$tag-$s"
done
}
E='import sys;p=sys.argv[1];s=open(p).read();o=%s;n=%s;assert s.count(o)==1;open(p,"w").write(s.replace(o,n))'
mut a "$(printf "$E" "'export COMPOSE_PROJECT_NAME='" "'COMPOSE_PROJECT_NAME='")" red
mut b "$(printf "$E" "'err=\"\$(docker network rm \"\$net\" 2>&1 >/dev/null)\" && return 0'" "'err=\"\" && return 0'")" red
mut c "$(printf "$E" "'; remove_compose_network'\"'\"' EXIT'" "''\"'\"' EXIT'")" green
[ -z "$(git status --porcelain | grep -v '^?? node_modules$')" ] && echo "tree clean after mutants" || { echo "TREE DIRTY"; git status --porcelain; }
echo "end $(date -u +%FT%TZ)"
-180
View File
@@ -1,180 +0,0 @@
# Row 307 (#1814, Vikunja 598): move row 270's pi compaction reading behind the harness kind
Owner Gizmoduck. Reviewer Duckworth. Gate owner Sage. Brief:
docs/plans/2026-10-23_harness-kind-compactions.md. Base 1e629c892. Design: DESIGN.md beside this file,
approved (static) by Duckworth on 67daf6403 (duckworth-0280), with C1, C2, N1 and N2 folded in at
cb048b93c. Mos ruled go on the four old-test edits in mos-1459, with the bounds below.
## Commits
1. 1f6db1589, red first. The two new test files and capture.mjs. Its product files are base's:
`git diff --stat 1e629c892 1f6db1589` lists only this packet, capture.mjs and the two tests.
2. 44104adb1, the build. The product files and the four old-test edits.
## What the build does
- `packages/plugins/src/kinds.mjs:52-57`: the harness kind's exports end in `"compactions"`, and the
comment gains its contract line. `interfaceVersion` stays 1 (DESIGN.md "interfaceVersion stays 1").
- New `packages/plugins/harness/pi/compactions.mjs`: base's `scanPi`, `readRange`, `digest`, `STREAM`,
`TAIL`, the chunk size, `PI_VERSION` and `claudeHistory`, unchanged in behaviour, plus the export.
`scanPi` is no longer exported and takes no defaults: its one caller passes all four arguments.
- `pi/index.mjs` re-exports it. `claude-code/index.mjs` answers harness-unsupported with version null.
- `packages/seat/src/compactions.mjs`: keeps the ledger. `readLedger` sets `unsupported` on
`r.reason === "harness-unsupported"` only (:113). `checkAnswer` (:147-164) refuses an answer out of
contract. `collectCompactions(store, { name, compactions }, opts)` (:174-205) calls the export, checks
it, and writes the same lines in the same order as base.
- `packages/cli/src/launcher.mjs`: the `compactions` closure takes the loaded module and calls the
export directly, with the N1 comment on why it skips `call()`. Both call sites pass `harness`.
- `packages/plugins/README.md`: the Harness section gains the `compactions` bullet.
## Old-test edits (mos-1459 bounds)
| File | Edit | Bound |
| --- | --- | --- |
| plugins/tests/kinds.test.mjs | `"compactions"` appended to the pinned list | :17-21, append only |
| seat/tests/compactions.test.mjs | two module imports; `collect` passes `{ name, compactions }` | :11/:21, helper only |
| seat/tests/compactions-budget.test.mjs | pi import; `collect` passes `{ name, compactions }` | :13/:24-25, helper only |
| cli/tests/compactions-launch.test.mjs | pi import; base :344's call (now :345) passes `{ name: "pi", compactions: pi }` | call only, `.count === 1` kept |
No call or expected value in those files changed. harness.test.mjs, cli helpers.mjs:133-151,
launch-routes.test.mjs:17-23 and launcher.test.mjs:694-697 are unedited.
## New tests
- `packages/seat/tests/compactions-ledger.test.mjs`:
- FIXTURES: seven ledgers row 270's code writes (known, store-incomplete, store-unreadable,
not-collected, harness-unsupported from claude-code, harness-unsupported from Claude history, and
torn), each with its streams, projects and steps. Per fixture, test A reads `compactionCount` and
test B runs one collection through `{ name: "pi", compactions: pi.compactions }`.
- Test B runs over the fixture's own streams, not an empty session as DESIGN.md:189 says. Over an
empty session every fixture with a cursor would go store-incomplete (the stream went away), so
"the others go known" could not hold. The expected answers: known stays known (1), store-unreadable
goes known with 0 (the cursor is at the end), not-collected goes known with 1, and
store-incomplete, torn and both harness-unsupported fixtures stay unknown.
- The malformed-answer test (17 answers, plus a module that throws, over a fresh store and over the
known fixture) and the argument test (exact keys; core passes a copy of the cursors).
- `packages/plugins/tests/harness-compactions.test.mjs`: CASES plain, budget (100 bytes), cap (1
stream of 2), shrank and header against pi; pi's `first` with and without Claude history;
claude-code; and a module re-exporting every pi export but `compactions`, refused `missing-export`.
- capture.mjs reads both capture blocks from the test files. It replays each fixture with base's
`collectCompactions(store, "<name>", ...)` and compares the ledger byte for byte, and it runs base's
`scanPi` per case and compares the answer under base's reason order (:301 at base) and
`PI_VERSION`. It prints base's `compactionCount` per fixture: that is the before half.
## Expected red on 1f6db1589
- seat compactions-ledger: the seven test A pass (the ledger rules are base's). Test B fails for known,
store-unreadable and not-collected: base takes the object as a harness that isn't pi and writes
harness-unsupported. Test B passes on base for the other four, whose expected answer is unknown with
the same reason. The malformed-answer and argument tests fail: base never calls the module.
Correction after the run: test B fails on base for claude-history too, so the reds are known,
store-unreadable, not-collected and claude-history. On base the object harness takes :304, which
writes `collected` without a scan, so the count stays null. Pi on the tip scans on a later
collection, finds c1 and answers 1, still unknown with harness-unsupported. The test is right and
this list was wrong (Duckworth agreed, duckworth-0287).
- plugins harness-compactions: the five CASES, the `first` test and the claude-code test fail with a
TypeError (`compactions` isn't exported on base). The missing-export test fails: base's loader loads
the module.
- harness.test.mjs:192 is already red on base. That's the brief's starting point.
## Run plan (mos-1275, `timeout -k 10`)
All on a CLEAR from Sage. TMPDIR comes from `mktemp -d /mnt/storage/scratch/tmp/gXXX`. Gate worktrees
under /mnt/storage/scratch, node_modules linked right after `git worktree add`, pipefail and tee.
| Run | Longest recorded | LIMIT |
| --- | --- | --- |
| capture.mjs on a 1f6db1589 worktree (base and candidate both it) | none | 120 s |
| red first: the two new files on 1f6db1589, each whole | none (seat suite 7 s) | 300 s |
| the touched test files whole on 44104adb1, one at a time | compactions-launch alone: none; other files 15 s | 600 s |
| bus suite | 25 s (270 r5) | 900 s |
| cli suite | 682 s (270 r5) | 2100 s |
| plugins suite | none recorded | 900 s |
| webui suite | 58.2 s (294) | 600 s |
| business suite | none recorded | 900 s |
| seat suite whole, `node --test tests/` (Duckworth C1) | 7 s (270 r5) | 600 s |
| each scripts/test-*.sh | 42 s (test-foundation) | 900 s |
| each mutant, its kill files whole | 1 s (264a probes) | 300 s |
- In the cli run, compactions-launch's T3 tests (base :206, and :305 with the :344 edit; :207, :306
and :345 after the import line) must show as run, not skipped on `sandboxProblem()` (base :36, now
:37). The report names every skip (Duckworth C2).
- Plugins must have zero failures.
- A timeout with no failed test is a hang and goes to Sage. A timeout in the shell phase goes to Mos
unplaced. A first-run red in a new 307 test is placed and reported after (mos-1272). A red in an old
test goes to Sage, unfixed.
## Mutants
Each on an isolated copy of the file, restore checked by sha256, only on a green base.
| # | Change | Kill files |
| --- | --- | --- |
| M1 | `readLedger`: `if (r.harness !== "pi" \|\| r.reason === "harness-unsupported")` restored | plugins harness.test.mjs (:192) |
| M2 | pi `compactions` drops the `first && claudeHistory(store)` branch | seat compactions-budget.test.mjs (base :86, now :87), plugins harness-compactions.test.mjs |
| M3 | `readLedger` never sets `unsupported` | seat compactions-ledger.test.mjs, seat compactions.test.mjs (base :197, now :199) |
| M4 | `collectCompactions` skips `checkAnswer` | seat compactions-ledger.test.mjs |
## Runs
Sage's CLEARs: sage-3455 for steps 1-3, sage-3465 for steps 4-6. Gate worktrees at
/mnt/storage/scratch/g307-base (1f6db1589), g307-tip and g307-mut (1f00d4f91), with node_modules
linked. TMPDIR was /mnt/storage/scratch/tmp/gTIK. Outputs went to /mnt/storage/scratch/gizmo-307-out/s1 and s2.
### Steps 1-3 (13:31:21Z-13:31:36Z, then the capture rerun at 13:32Z)
- capture.mjs crashed with ENOENT on its first run. Base `sessionStore` (session.mjs:78
`privateDirs`, called from :117) makes its directories one level at a time, and :44 passed a
per-fixture root that didn't exist yet. The fix is one line before :44,
`` mkdirSync(join(root, `f-${name}`)) ``. A copy with that line, run on g307-base as both base and
candidate, exited rc 0 and printed `all match`: 7 ledgers byte for byte, 7 base counts and 5 scans.
Base counts: known 1 known; store-incomplete, store-unreadable and not-collected null, unknown
with their own reason; claude-code and claude-history null, harness-unsupported; torn 1,
store-incomplete.
- Red first on 1f6db1589, both rc 1. Seat compactions-ledger: 9 pass, 7 fail (the corrected list
above, plus the malformed-answer and argument tests). Plugins harness-compactions: 0 pass, 8 fail.
Seven fail with `TypeError: pi.compactions is not a function` or `claude.compactions is not a
function`. The missing-export test fails because base loads the module.
- Touched files whole on 1f00d4f91, all rc 0: compactions-ledger 16/16, harness-compactions 8/8,
kinds 5/5, harness 9/9 (:192 green), compactions 20/20, compactions-budget 10/10,
compactions-launch 5/5 with 0 skipped.
### Steps 4-6 (14:00:10Z-14:14:00Z, on 1f00d4f91)
| Run | rc | Time | Result |
| --- | --- | --- | --- |
| bus | 0 | 24 s | 890 pass, 0 fail, 0 skipped |
| cli | 0 | 631 s | 927 pass, 0 fail, 0 skipped; T3 :207, :306, :345 ran |
| plugins | 0 | 0 s | 119 pass, 0 fail, 0 skipped |
| webui | 0 | 57 s | 374 pass, 0 fail, 1 skipped (below) |
| business | 0 | 2 s | 231 pass, 0 fail, 0 skipped |
| seat | 0 | 7 s | 218 pass, 0 fail, 0 skipped |
| test-auth | 0 | 0 s | 15 passed, 0 failed |
| test-conductor | 0 | 7 s | |
| test-config | 0 | 3 s | |
| test-discord | 0 | 7 s | |
| test-extension-package | 0 | 2 s | |
| test-foundation | 0 | 39 s | |
| test-land-work | 0 | 12 s | |
| test-queue | 0 | 20 s | one skip (below) |
| test-release | 0 | 3 s | 15 passed, 0 failed |
| test-task | 0 | 14 s | 92 passed, 0 failed, two skips (below) |
Skips:
- webui: "rebuilding from the source gives the same bytes" needs the pinned esbuild. 307 doesn't
touch the editor.
- test-queue: "queue verify and render --check", because the gate worktree isn't the queue's
canonical root.
- test-task: "live provider cases" twice (row 244, no provider call in the gate).
Mutants ran in g307-mut. Each restore matched its sha256, and the tree was clean after M4.
| # | Killed by |
| --- | --- |
| M1 | plugins harness.test.mjs:192 |
| M2 | seat compactions-budget.test.mjs:87 and :104; plugins harness-compactions.test.mjs:47 |
| M3 | seat compactions-ledger.test.mjs:123 (test B, claude-code and claude-history); seat compactions.test.mjs:199 |
| M4 | seat compactions-ledger.test.mjs:151 (the malformed-answer test) |
There were no reds, so nothing was placed under mos-1272. The sweep found no node or chromium left in
my cwds.
-241
View File
@@ -1,241 +0,0 @@
# Row 307 (#1814, Vikunja 598): row 270's pi compaction reading moves behind the harness kind
Owner Gizmoduck. Reviewer Duckworth. Gate owner Sage. Brief:
`docs/plans/2026-10-23_harness-kind-compactions.md` at 1e629c892, which is the base. Mos ruled the
move in mos-1455 item 3 and declined an EXCEPT entry.
## What is red, as the code has it at 1e629c892
`packages/plugins/tests/harness.test.mjs:192` greps core sources for a quoted harness name. It finds
three lines in `packages/seat/src/compactions.mjs`:
- `:232` in `readLedger`: `if (r.harness !== "pi" || r.reason === "harness-unsupported") unsupported = true;`
- `:283` and `:287` in `collectCompactions`: the `harness === "pi"` branches.
Everything else row 270 put in that file is either harness-free (the ledger, the budget and stream
settings, `storeDir`, `compactionCount`) or pi-only (`scanPi`, `PI_VERSION`, `claudeHistory`, and
the helpers only `scanPi` uses: `readRange`, `digest`, `STREAM`, `TAIL`).
## The new export: `compactions`
`packages/plugins/src/kinds.mjs:54` appends `"compactions"` to the harness kind's exports, so the
loader refuses a module without it (`loader.mjs:61-66`, code `missing-export`).
```
compactions({ store, cursors, budget, streams, first })
-> { found, cursors, known, reason, version }
```
Arguments, all from core:
- `store` is `{ session, projects }`, the two native store directories `sessionStore` makes. The
module never gets `store.dir`, the directory that holds the ledger.
- `cursors` is a copy of the ledger's cursor map, `{ [stream]: { bytes, tail } }`.
- `budget` and `streams` are `readBudget(...)` and `readStreams(...)`, as the launcher passes them
now (`launcher.mjs:299`, `:305`). Core keeps both readers and their defaults.
- `first` is true when the store has no ledger yet (today's `!prior`).
The answer:
- `found`: `[{ entry, completedAt, stream }]`, the compactions read past the cursors. `entry` is a
non-empty string, `completedAt` a string or null, `stream` a non-empty string.
- `cursors`: `{ [stream]: { bytes, tail } }` for each stream the module read. `bytes` is a safe
integer of 0 or more and `tail` 64 lowercase hex.
- `reason`: null, `store-incomplete`, `store-unreadable`, `not-collected` or `harness-unsupported`.
- `known`: a boolean, true exactly when `reason` is null.
- `version`: the store format the module read against as a string, or null when it read nothing.
Core checks the answer before it writes. Anything else throws `harness <name> compactions: bad
answer: <what>` and nothing is appended. A throw from the module itself is the same case. Both reach
the launcher's existing catch (`launcher.mjs:313-316`), which logs the message and records the run's
`compactions` event as unknown with `store-unreadable`, as a scan that throws today does.
### interfaceVersion stays 1
- Every harness module lives in this tree, and the loader loads nothing else (decision 143,
`loader.mjs:1-5`). Both shipped modules gain the export in the same commit.
- A module without the export already refuses at load, as `missing-export` naming `compactions`.
That is the brief's third test. A bump would add a second refusal for the same fact.
- No existing export changes its arguments or answer. Row 125 moved limit-check to 2 because
`mayLaunch`, `mustStop` and `report` changed shape. Nothing like that happens here.
- `harness.test.mjs:36` pins `interfaceVersion` 1, and the brief keeps that file unchanged.
The tradeoff: a module someone wrote against version 1 without `compactions` reports
`missing-export`, not `interface-version`. The message names the export, which is the more useful of
the two.
## What moves where
New file `packages/plugins/harness/pi/compactions.mjs`, imported by `pi/index.mjs`. The loader
checks only `index.mjs` itself (`loader.mjs:42-54`), and claude-code's module already imports files
outside its directory (`claude-code/index.mjs:11-12`). It takes, unchanged in behaviour:
- `scanPi`, with `readRange`, `digest`, `STREAM`, `TAIL` and the chunk size it reads by;
- `PI_VERSION` ("0.85.1");
- `claudeHistory(store)`;
- the reason order `["store-incomplete", "store-unreadable", "not-collected"]` from `:301`;
- the header comment's Pi paragraphs (`compactions.mjs:12-19`, `:21-24`).
pi's `compactions`:
- `first` and `claudeHistory(store)`: answers `{ found: [], cursors: {}, known: false, reason:
"harness-unsupported", version: "0.85.1" }`. That is today's `:283-286`.
- otherwise: `scanPi(store.session, cursors, budget, streams)`, and answers its `found` and
`cursors` with the first reason in the order above, `known` when that's null, and version
"0.85.1". That is today's `:287-302` before the dedupe.
claude-code's `compactions` reads nothing and answers `{ found: [], cursors: {}, known: false,
reason: "harness-unsupported", version: null }`. That is today's `:303-304`. Vikunja 466 still has
no pinned Claude Code format.
## Core keeps the ledger
`packages/seat/src/compactions.mjs` keeps `LEDGER`, `READ_BYTES`, `STREAMS`, `readBudget`,
`readStreams`, `storeDir`, `readLedger`, `compactionCount`, the key and the single O_APPEND write.
`collectCompactions(store, harness, { now, budget, streams })` takes `harness = { name,
compactions }`, the name the route used and the loaded module's export. It:
1. reads the ledger (`prior`), as now;
2. calls `harness.compactions({ store: { session: store.session, projects: store.projects },
cursors: { ...ledger.cursors }, budget, streams, first: prior === null })` and checks the answer;
3. appends, in today's order: one `compaction` line per key the ledger doesn't hold yet, one
`cursor` line per stream whose cursor moved, then `{ v: 1, kind: "collected", at, known, reason,
harness: name, version }`. These are the same lines and field order as today's `:288-302` and
`:304`. `name` is a variable, never a literal;
4. returns `compactionCount(store.dir)`.
`readLedger`'s unsupported test becomes `r.reason === "harness-unsupported"`, a field every answer
carries. No core line names a harness. The core comments drop the quoted names too, because the
grep reads comments.
`packages/cli/src/launcher.mjs:309-318`: the `compactions` closure takes the loaded module too and
calls `collectCompactions(store, { name: model.harness, compactions: harness.compactions }, {
budget, streams })`. Both call sites, `:509` and `:650`, have `harness` in scope (it's
`startLocked`'s `let harness` from `:503`; the `exited.then` callback at `:632` closes over it).
The closure calls the export directly, not through `call()` (`launcher.mjs:196`), because `call()`
turns a throw into a run refusal. The closure gets a comment saying so (Duckworth N1).
`bus/src/runtime.mjs:282` and `broker.mjs:885-889` keep calling `compactionCount` and don't change.
`packages/plugins/README.md`, Harness section, and the comment at `kinds.mjs:35-51` each gain the
`compactions` line with the contract above.
## A ledger row 270 wrote reads the same count
Row 270's code writes a `collected` line in exactly three places:
| Line | harness | reason | version | old rule (`:232`) | new rule |
| --- | --- | --- | --- | --- | --- |
| `:286`, Claude history on the first pi collection | `"pi"` | `harness-unsupported` | "0.85.1" | unsupported | unsupported |
| `:302`, a pi scan | `"pi"` | null, `store-incomplete`, `store-unreadable` or `not-collected` | "0.85.1" | supported | supported |
| `:304`, any other harness name (`claude-code`, or `claude` in the tests) | that name | `harness-unsupported` | null | unsupported | unsupported |
The two rules agree on every line row 270 can write. The rest of `readLedger` (the `bad`, `torn`,
`incomplete` and `events` handling) and all of `compactionCount` don't change. So every ledger row
270 wrote reads the same `{ count, known, reason, at }` after the move. Nothing rewrites a ledger;
the next collection only appends.
The rules would differ only on a `collected` line naming a harness other than `"pi"` with a reason
other than `harness-unsupported`. Row 270 never writes one, and the launcher is the ledger's only
writer (`compactions.mjs:7-10`).
New collections after the move append the same bytes as before for the same store state. pi's
answer is today's scan result, core keeps the dedupe and the line format, and `harness` in the line
is still the route's name.
## Existing tests that change (to Mos through Sage, mos-1272)
Grepped for `interfaceVersion`, the harness exports, `write("harness"`, `fakeHarnesses` and
`collectCompactions(` in `packages/*/tests/*` and `scripts/`.
Four existing files change:
1. `packages/plugins/tests/kinds.test.mjs:17-21`: the pinned harness export list gains
`"compactions"` at the end.
2. `packages/seat/tests/compactions.test.mjs:11` and `:21`: import the two shipped modules. `setup`'s
`collect(harness = "pi")` passes `{ name: harness, compactions: MODULES[harness].compactions }`,
with `pi` mapped to the pi module and `claude` to claude-code's. The 27 `f.collect()` calls and
the two named ones at `:199` and `:201` stay as written.
3. `packages/seat/tests/compactions-budget.test.mjs:13` and `:24-25`: the same change in its
`collect`. Its calls at `:67-69` and `:129-134` stay as written.
4. `packages/cli/tests/compactions-launch.test.mjs:344`: the one direct
`collectCompactions(legacy, "pi")` becomes `collectCompactions(legacy, { name: "pi",
compactions: pi.compactions })`, with an import of the pi module.
Fixtures that build a harness module and need no edit, because they re-export a real module and
inherit `compactions`:
- `packages/cli/tests/helpers.mjs:133-151` `fakeHarnesses`, used by `compactions-launch`,
`idle-stop-race`, `launcher`, `lifecycle`, `session-clear`, `session-launch`, `thread-launch` and
`thread-revoke`;
- `packages/cli/tests/launch-routes.test.mjs:17-23`: `down`, `sparse`, `metered` and `throws`
re-export pi. `broken` lacks every export but `adapter` on purpose. The loader still refuses it at
`levels` first, so `:114` and `:138` (`missing-export`) hold;
- `packages/cli/tests/launcher.test.mjs:694-697`: `down` and `fixture` re-export pi.
`packages/plugins/tests/harness.test.mjs` doesn't change. `:33-37` loops over the kind's exports,
which both modules then have, and `:192` goes green.
No `scripts/test-*.sh` builds a harness module. `test-config.sh:266-280` checks only the two
config keys.
## New tests, red first (mos-1272)
1. `packages/seat/tests/compactions-ledger.test.mjs`: one fixture ledger per reason row 270 writes:
known, `store-incomplete`, `store-unreadable`, `not-collected`, `harness-unsupported` from
claude-code, `harness-unsupported` from Claude history, and a torn ledger.
- Each is literal JSONL in the test. Before the build, in the slot, a capture script runs base
1e629c892's `collectCompactions` with a fixed `now` over the same stores. The literals must
equal its output byte for byte. That proves row 270's code wrote them.
- `compactionCount` reads each one. I run this half on the base and on the candidate, and record
both outputs in BUILD.md as the before and after.
- Then one more collection through `{ name, compactions }` over an empty session gives each
fixture's expected next answer: unsupported and `store-incomplete` stay, the others go known.
This half is red on the base, where core treats the object as a harness that isn't pi.
2. `packages/plugins/tests/harness-compactions.test.mjs`:
- pi's `compactions` over fixture streams answers what base `scanPi` answers, captured by the same
script: a plain count, a budget that stops short (cursor at the last whole line,
`not-collected`), more streams than the cap (no cursor for unopened streams, `not-collected`),
a stream that shrank under its cursor (`store-incomplete`), a non-session header
(`store-unreadable`). Each answer has version "0.85.1".
- pi with `first` and a non-empty `projects` answers `harness-unsupported` without scanning.
Without `first`, the same store scans.
- claude-code answers `harness-unsupported` with version null, over directories that don't exist.
- A harness module that re-exports every other pi export by name, without `compactions`, refuses
at load: `missing-export`, "doesn't export compactions".
3. In the same seat file: core refuses each malformed answer and appends nothing. The cases are
`found` not an array, an empty `entry`, a cursor whose `bytes` is negative or `tail` isn't 64
hex, `known` true with a reason, an unknown reason, a numeric `version`, and a module that
throws. The module gets exactly `{ store: { session, projects }, cursors, budget, streams,
first }`.
## Mutants
- M1, the brief's first: core branches on a harness name again (`readLedger`'s `r.harness !== "pi"
||` restored). Killed by `harness.test.mjs:192`.
- M2, the brief's second: pi's module drops the Claude-history check. Killed by
`compactions-budget.test.mjs:86` and new test 2's `first` case.
- M3, the brief's third: `readLedger` never sets `unsupported`. Killed by new test 1's two
`harness-unsupported` fixtures and `compactions.test.mjs:197`.
- M4, mine: core skips the answer check. Killed by new test 3.
## Gate
Duckworth approves this design, then the manifest. On Sage's CLEAR:
- the capture script on base 1e629c892 first, then the new tests red on the base;
- the bus, cli, plugins (zero failures), webui and business suites, and every `scripts/test-*.sh`;
- the seat suite whole (`packages/seat`, `node --test tests/`), where two old-test edits, new
tests 1 and 3, and the M2 and M3 kills live (Duckworth C1);
- in the cli run, `compactions-launch`'s T3 tests (`:206`, and `:305` with the `:344` edit) must
run, not skip on `sandboxProblem()` (`:36`). BUILD.md names every skip (Duckworth C2);
- the mutants, each on an isolated copy with its restore checked by sha256.
Each suite runs under `timeout -k 10` at 3x or more of its longest recorded wall (mos-1275). I'll
put the numbers in BUILD.md before the first run. TMPDIR comes from
`mktemp -d /mnt/storage/scratch/tmp/gXXX`.
## Round 1
Duckworth approved round 1 on 67daf6403 (duckworth-0280). This revision takes C1 and C2 into
the gate, adds the N1 comment to the launcher plan, and corrects the N2 line refs (`:302`, `:301`).
@@ -1,79 +0,0 @@
// Row 307 (#1814): checks the new tests' literals against row 270's code at base 1e629c892.
//
// node capture.mjs <base checkout at 1e629c892> <candidate checkout>
//
// Reads the FIXTURES and CASES blocks (between `// capture:begin` and `// capture:end`) from the
// candidate's two new test files. Replays each fixture's steps with the base's collectCompactions,
// harness named by string as row 270 takes it, with the clock at 12:00:00 and one second a step,
// and compares the ledger byte for byte. Prints the base's compactionCount for each. Runs the
// base's scanPi over each case and compares the answer the base's reason order gives (:301) with
// version PI_VERSION. Exit 0 only when every one matches. Writes only under TMPDIR.
import assert from "node:assert/strict";
import { appendFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { pathToFileURL } from "node:url";
const [base, cand] = process.argv.slice(2).map((p) => p && resolve(p));
if (!base || !cand) {
console.error("usage: node capture.mjs <base checkout> <candidate checkout>");
process.exit(2);
}
function block(file) {
const text = readFileSync(join(cand, file), "utf8");
const m = /\n\/\/ capture:begin\nconst [A-Z]+ = (\{[\s\S]*?\});\n\/\/ capture:end\n/.exec(text);
if (!m) throw new Error(`${file}: no capture block`);
return JSON.parse(m[1]);
}
const FIXTURES = block("packages/seat/tests/compactions-ledger.test.mjs");
const CASES = block("packages/plugins/tests/harness-compactions.test.mjs");
const seat = await import(pathToFileURL(join(base, "packages/seat/src/compactions.mjs")).href);
const { sessionStore } = await import(pathToFileURL(join(base, "packages/seat/src/session.mjs")).href);
const root = mkdtempSync(join(tmpdir(), "g307-capture-"));
let failed = 0;
const report = (what, same, detail) => {
console.log(`${same ? "MATCH" : "DIFF "} ${what}${detail ? ` ${detail}` : ""}`);
if (!same) failed++;
};
try {
for (const [name, fx] of Object.entries(FIXTURES)) {
mkdirSync(join(root, `f-${name}`));
const store = sessionStore(join(root, `f-${name}`), "acme", "th1", "s1");
for (const [file, text] of Object.entries(fx.streams)) writeFileSync(join(store.session, file), text);
for (const [file, text] of Object.entries(fx.projects ?? {})) writeFileSync(join(store.projects, file), text);
let tick = 0;
const now = () => new Date(Date.UTC(2026, 9, 22, 12, 0, tick++)).toISOString();
for (const step of fx.steps) {
if (step.tear !== undefined) appendFileSync(join(store.dir, seat.LEDGER), step.tear);
else seat.collectCompactions(store, step.collect, { now, ...(step.budget === undefined ? {} : { budget: step.budget }) });
}
const got = readFileSync(join(store.dir, seat.LEDGER), "utf8");
const want = fx.ledger.join("\n") + "\n";
report(`ledger ${name}`, got === want, got === want ? `(${Buffer.byteLength(got)} bytes)` : `\n--- base wrote\n${got}--- test has\n${want}`);
const count = seat.compactionCount(store.dir);
report(`base count ${name}`, JSON.stringify(count) === JSON.stringify(fx.count), JSON.stringify(count));
}
for (const [name, c] of Object.entries(CASES)) {
const dir = join(root, `c-${name}`);
mkdirSync(dir);
for (const [file, text] of Object.entries(c.streams)) writeFileSync(join(dir, file), text);
const scan = seat.scanPi(dir, c.cursors, c.budget, c.cap);
const reason = ["store-incomplete", "store-unreadable", "not-collected"].find((p) => scan.problems.includes(p)) ?? null;
const answer = { found: scan.found, cursors: scan.cursors, known: reason === null, reason, version: seat.PI_VERSION };
let same = true;
try {
assert.deepStrictEqual(answer, c.answer);
} catch {
same = false;
}
report(`scan ${name}`, same, JSON.stringify(scan));
}
} finally {
rmSync(root, { recursive: true, force: true });
}
console.log(failed ? `${failed} differ` : "all match");
process.exit(failed ? 1 : 0);
-342
View File
@@ -1,342 +0,0 @@
# Row 272 / 264e (#1777): session CLI and Console chooser
Owner Huey; reviewer Scrooge per sage-2816 / mos-1310 item 2 (supersedes sage-2796). Current base 5fdfd7275, branch huey/row272-5fdfd7275 (sage-3354). Original draft base 2d0d407ba; round 1 was 850b22680 on b23783f39.
Brief: docs/plans/2026-10-21_t1-sessions.md (ff0be0c79), section 8; row 264 rulings
at 5f5b51dd6. Dependencies: 264a-d landed; 270/271 landing is 7328da8ca.
Count/clear implementation and contracts are now in the current base. No runtime, launcher, library adapter,
role, schema or queue edits belong to this slice.
## Execution and evidence
1. Read session/channel/HTTP/browser contracts and write isolation/validation tests.
2. Add session CLI through the existing verified human channel, preserving defaults.
3. Add authenticated Console chooser, per-session drafts/history/cursors, count and
clear status. Unavailable dependency verbs refuse explicitly; no simulated success.
4. On Sage's CLEAR: claim, run focused tests and required suites/mutants, repair and
record exact evidence. No Node, tests, HTTPS git, claim or push under Gander's gate.
5. After 253 and 269 land, rebase on a new branch name. Review packet to Scrooge,
Mos, Gizmoduck and Sage; push only when permitted.
2026-10-22 preparation: clean worktree switched locally to the requested base. Read
approved brief and all Q1-Q7 rulings. Della notified: no startBroker/library changes.
Gizmoduck asked to pin count/clear contracts. Tests will be written first; Sage's
explicit gate restriction defers RED/GREEN execution. No test result claimed.
Verification plan: CLI real-broker isolation and channel refusal; HTTP strict keys,
Origin/Fetch Metadata, forged selector/refusal and no retries; fixture-browser two
sessions, isolated draft/cursor/receipt, deep-link/refresh, count unknown/known,
read-only writes, clear confirmation/pending. Add selector omission and cursor/draft
sharing mutants. Broader cli/webui/plugins suites use Sage's gate only.
264c/d contracts received gizmoduck-0260: session.list gains compactions and revision/state;
session.clear and session.operation use the pinned envelopes. CLI polls at most 30 s
then reports pending; Console status checks use GET only. Counts absent on 264b show
unavailable; unknown never becomes zero. Clear absent on 264b is disabled with a reason.
USER_VERBS and tester listener write policy remain unchanged (Q7). Existing collaborators
therefore cannot enter the new session surface until the reviewed RBAC integration.
Consumer audit found the explicitly deferred B6 user-reply scope (DEFERRED.md:455-459,
queue-264/BUILD.md:317-322) bound to 272. Added a narrow broker predicate change from
thread to session and a sibling-session regression fixture, without widening user verbs.
This is the only planned broker change and does not overlap Della's runtime adapter.
2026-10-22 static review: added explicit --session to thread read/open and talk/follow;
omission remains the saved default. CLI clear first reads a recorded operation, so a
repeat after a lifecycle revision change cannot become a conflicting second write.
Console deep links name both thread and session; accepted-send receipts, drafts and
history pagination use that tuple. Clear-status GETs refresh the envelope without
reissuing clear. Read failures discard private metadata; late generations cannot paint
another selection. Scrooge is reviewer per sage-2816 / mos-1310, superseding the first
assignment. CLEAR remains after 269, 275, 203 and 207. No execution evidence yet.
## Acceptance / mutant map (prepared, unexecuted)
| Check | Evidence file / intended kill |
| --- | --- |
| T5 legacy human, forged agent, foreign session, strict HTTP identity/Origin/site | session-cli.test.mjs, chat.test.mjs; unchanged USER_VERBS matrix in user-principal.test.mjs |
| T7 saved default, explicit CLI session selector, metadata-only create | session-cli.test.mjs real broker and thread CLI compatibility tests |
| T7 Console chooser, deep link, draft/cursor/receipt isolation, unknown count, confirmation/pending | chat-browser.test.mjs; existing history/sign-out/late-read tests run whole |
| Count/clear contract absence | CLI unavailable refusal; Console disabled clear reason; exact zero vs unknown lower bound tests |
| B6 assigned follow-up | user-principal.test.mjs sibling-session citation refusal and valid same-session reply |
| M1 omit session in chat.mjs messages forwarding | chat.test.mjs explicit selector deepEqual fails |
| M2 collapse browser state key from thread/session to thread | chooser draft isolation assertion fails |
| M3 treat known:false count:0 as exact zero | CLI label assertion and browser unknown-count assertion fail |
| M4 restore B6 mt.thread/s.thread predicate | user-principal sibling refusal assertion fails |
| M5 remove session from CLI thread.send payload | explicit --session talk assertion fails |
| M6 repeat a clear write in place of session.operation poll | CLI exactly-one-clear assertion fails |
Intended focused commands, only after CLEAR, one process at a time:
- `timeout -k 10 300 node --test packages/cli/tests/session-cli.test.mjs`
- `timeout -k 10 300 node --test packages/cli/tests/thread-cli.test.mjs`
- `timeout -k 10 300 node --test packages/bus/tests/user-principal.test.mjs`
- `timeout -k 10 300 node --test packages/plugins/tests/channel.test.mjs`
- `timeout -k 10 300 node --test packages/webui/tests/chat.test.mjs`
- `timeout -k 10 600 node --test packages/webui/tests/chat-browser.test.mjs`
Whole touched suites on Sage's slot: bus (900 s), cli (1800 s, >=3x recorded 591 s),
webui (600 s), plugins (600 s), plus required integration scripts per final gate brief.
Mutants run in disposable copies of the pinned candidate, never against a live stack;
only failed assertions count as kills, never a timeout or import/setup failure.
No test process, browser, provider, credential read or live service action ran in this
preparation. `git diff --check` is the only executed draft verification so far.
Next: Sage CLEAR for claim/focused runs; repair against actual results, then rebase on
a newly named branch once 253 and 269 land. Generate final manifest only after those
changes. Review handoff is Scrooge and Mos, copying Gizmoduck and Sage; no handoff to
Duckworth under the superseded assignment. No candidate commit or green claim yet.
2026-10-22, gizmoduck-0272 / sage-2828 additive contract at 78e14352f: added
session.cancel to CLI/channel/Console with confirmed human writes and strict keys.
Cancelled envelopes retain `retired:null` (old active) or `true` (startup cancelled,
old retired); cancelled is terminal for polling. CLI reports routed message cancellation
with stored ID and exit 3, never waits for delivery or replays it. HTTP maps
session-name-too-long and session-clear-complete without reflecting transport text.
Added unexecuted before/after cancellation, identity/Origin, confirmation and message
receipt tests. Existing clear/create/read wiring is preserved. Asked Gizmoduck whether
the deterministic successor keeps 264a's UUID shape, as selectors currently require.
No Node, test run, claim, commit, push, provider call or live action. Static diff only.
Gizmoduck-0274 resolves the selector compatibility check: successors are lowercase
RFC 9562 v8 UUIDs (variant 10), while 264a sessions are v4. Existing generic UUID
validators accept both and stay unchanged. CLI explicit-selector and Console chooser
fixtures now include mixed v4/v8 IDs to prevent a later v4-only regression. Unexecuted.
## sage-3141 rebase and landed-contract check (2026-10-23)
Reapplied the uncommitted draft onto b23783f39 in the same isolated worktree, on new
branch huey/row272-b23783f39. No candidate commits existed to replay. Preserved the
original draft in the named local stash `huey row272 draft before sage-3141 rebase`.
Product files merged without conflict. Only append-only BUILD-LOG.md and SESSIONS.md
conflicted: kept every new-base byte and appended the original Huey entries unchanged.
No force push, fetch, Node, test, queue write or live change. No claim or candidate
commit yet. Static `git diff --check` clean after resolution.
Checked the actual landed broker, not just the older contract packet:
- broker.mjs:687-707 clearEnvelope supplies the same op/thread/session/successor/state/
start/refusal/at fields and cancelled-only retired:null|true. The generic UUID
selectors still accept both original v4 and successor v8 IDs.
- broker.mjs:6227-6245 session.list supplies compactions, state, revision and successor;
count reader/unknown behavior is the landed 270 contract. Real-base tests must now
exercise these available fields; stand-ins still exercise an unavailable dependency.
- broker.mjs:6270-6330 clear/cancel/operation inputs and receipts match the wired contract.
clear repeats preserve the op; cancel also refuses a failed clear as
session-clear-complete. Our existing refusal mapping already covers it.
- queue-271/BUILD.md:225-238 clarifies cancellation after retirement cancels this clear's
startup, while later deliberate human open/send can start the fresh successor. It
does not permanently disable that new session. No frontend authority change needed.
- store.mjs:17 is 3n; migration is 3m-3n.sql. This slice adds/pins no schema step,
migration blob or schema test count. No DDL copied from an older branch.
Plan after the Gander 574 run-2 hold: on a claims-only CLEAR, claim only; run no Node
or tests beyond the explicit scope of Sage's grant. On test CLEAR run new CLI tests
first, then new broker/HTTP/browser cases and whole touched files, sequentially under
the recorded timeouts. Place/report a first-run red only in a new test; do not alter
an old test, loosen an assertion or fix a second red without Mos's ruling via Sage.
Whole-suite/mutant execution remains on Sage's slot. Candidate commit and push follow
applicable green evidence and an allowed gap, then Scrooge/Mos handoff with final SHA,
manifest, copying Gizmoduck/Sage.
Existing-test edits in the inherited draft need Mos's ruling through Sage before
execution: channel.test.mjs extends its existing supported-verbs table for five
session verbs; chat-browser.test.mjs extends the existing fetch fixture with session
catalog/operation responses and changes its exact send-payload assertion to include
the selected session. Assertions are not loosened. All other added test cases are
new tests. These changes were prepared before sage-3141 and have never run. Ask Sage
to forward this precise delta rather than treating a later old-test red as permission.
sage-3145 correction: refs/stash is shared across worktrees; using it as sole draft
storage was wrong. Pinned the exact draft commit 07dc9d2f7944b4781b5e80dfa18425f4749f7a45
on local branch huey/row272-stash-keep before any stash cleanup. The entry remains
untouched; the branch retains its tracked and untracked snapshots. Future seat draft
preservation uses owned branches/local commits, not shared stash positions.
Sage explicitly directed a local draft commit before tests to preserve the rebased
work. This overrides the normal green-before-commit gate for this storage checkpoint
only. It is an untested draft, not an approved candidate, test result, push or landing.
Claims await the post-574-run-2 CLEAR; test execution awaits Mos's ruling and Sage's
separate test CLEAR. Old-test deltas were forwarded as sage-3144; no ruling assumed.
## Scrooge early static read, 850b22680 (2026-10-23)
Review key scrooge-272-early-read-huey-1. B1 confirmed: the render catch used any
403/404 to delete every sibling's draft/receipt and clear/create operation key.
Uncommitted follow-up restricts that purge to thread-not-owned, thread-not-found and
access-refused. Session-not-found still shows an unavailable read, preserving sibling
state and pending recovery coordinates. New browser test retains A's draft and a lost
clear key across a bad-session deep link, then proves Clear queries the retained op
without another write.
N1: malformed clear/cancel write receipts now add the same redacted outcome-unknown
audit line as other writes. New HTTP test checks one write log and no read log.
N2: a valid recorded clear belonging to another session now refuses with a precise
operation-key-reuse message (exit 2), rather than ambiguous outcome unknown; new CLI
test proves no clear write. Malformed envelopes retain the outcome-unknown refusal.
No approved old assertion or shared stub edited. Static diff check only; all new tests
remain unrun pending Sage's test CLEAR. Published round 1 still pins 850b22680 and its
original manifest; these follow-up edits do not replace that evidence. No new commit,
push, queue write, provider call or live change for this early-read follow-up.
Execution watch: inspect message-filter.test first if the bus suite reports a B6
fixture red (manual message_threads rows must name the run's bound session); do not
change an old fixture/assertion without Mos's ruling via Sage. thread-shares uses the
persisted session_defaults mapping per Scrooge's check. No runtime verdict claimed.
## Granted-user legacy compatibility (sage-3357; pre-candidate design)
219/295 are retained on base 5fdfd7275. USER_VERBS still excludes session verbs;
193/T5 user session grants are a separate DEFERRED item, outside 272. No owner
transport carries a user session operation. Bounded negotiation applies only to the
session.list read: only `access-refused` and an omitted-session route permit legacy
thread-default read/send/open. All other errors keep the unavailable/error state, and
explicit session links always refuse. On fallback session controls are hidden and one
status line says sessions are not available for this account. No fake session ID,
count or lifecycle status is invented; the broker continues choosing its persisted
default under current grants on every existing thread request. Owner routes keep the
normal chooser and explicit selected-session arguments.
New file chat-sessions-access.test.mjs uses the real broker with an already granted
principal over loopback and the existing repository browser fixture. It checks legacy
read/send/open with no session controls, explicit-link refusal, another-error refusal,
and unchanged owner chooser. No shared stub or existing assertion changes. The three
required mutants remove the access-refused check, remove the omitted-session check,
and display the controls during fallback; guard tests must kill each by assertion.
RED-first slot sage-3358: only this new file, before fallback implementation. Expected
run 100 s including four Chromium fixtures; bound 300 s (3x), command
`timeout -k 10 300 node --test packages/webui/tests/chat-sessions-access.test.mjs`.
TMPDIR must be assigned from mktemp -d, with no underscore. No compose service is used;
check/remove the generated directory's compose default network if any exists. Expected
legacy-positive red is placed/reported afterward under mos-1272. Any other red is
reported to Sage before a fix. No other test file/suite is authorized in this slot.
sage-3358 RED run completed before the fallback implementation. Only the new
chat-sessions-access.test.mjs ran, under the 300 s bound, TMPDIR allocated by
`mktemp -d /tmp/huey272-red-XXXXXXXX` as /tmp/huey272-red-0q66Jcf4. Exit 1;
4 tests, expected legacy-positive assertion red and 3 passes, no other reds/skips/
cancellations/timeouts, 3.504 s. Exact output: r2-red-access.tap. No matching compose
network existed. Slot returned to Sage/Mos as huey-0035; no further tests run.
mos-1442 / sage-3361 adds explicit timeout, bus-error and malformed-answer refusal
coverage. The new private fixture adds those guard cases (unrun), with a widening-key
mutant alongside the access-refused/omitted-selector/control mutants. No shared stub
or existing assertion changed. Native preview status/open both reported unavailable
in this headless environment before the authorized repository-browser regression.
Implementation now local: the catalog request catches only access-refused on omitted
session routes. Its internal null result selects the existing broker-chosen thread
default with no fabricated session ID. Read/send/open omit the session property in
that mode. One status line replaces all session controls. Explicit links and any
other failure never select that mode. USER_VERBS and all owner transport routing
remain byte-unchanged. Guard cases are preserved on the pre-fallback baseline; their
RED evidence comes from the required mutants, as Sage accepted in sage-3358.
Fallback mutants are executable via fallback-mutants-r2.py, only on Sage's slot.
It copies packages/roles into a private mktemp directory and mutates only the copied
chat.js, never candidate bytes. Each run has a 300 s bound and requires a named
assertion failure; timeout/import/setup failures do not count. F1 removes the exact
access-refused key (human-required guard); F2 removes the omitted-selector check;
F3 shows session controls; F4 widens the key to timeout/unreachable, no-bus-host and
invalid-response (timeout guard). The test file also independently checks bus-error
and malformed-answer refusal. These mutants and the post-implementation tests have
not run locally. The earlier six non-fallback mutants in this packet remain required
in the full gate; the new runner covers the four fallback mutants only.
## Round 2 rebase receipt (sage-3354)
Queue rev 3510 returned row 272 to in-progress. On new branch huey/row272-5fdfd7275,
replayed round 1 and the preserved B1/N1/N2 fixes onto 5fdfd7275 (219, after 295).
Resolved exactly the seven named conflicts. Test append conflicts retain both complete
sets of tests; existing test content equals the new base plus only the mos-1388 hunks.
No old assertion or shared stub was changed beyond those approved hunks. Static byte
comparison confirms the entire upstream test file prefixes and approved modifications.
Both append-only logs retain the complete 5fdfd7275 prefix plus Huey's entries.
219's per-instance thread picker, explicit createThread instance forwarding, choice
refresh/revocation behavior and tests remain present. 295's createChat owner-settings
read stays unchanged: only plugins uses the owner transport; user chat verbs stay on
the user transport. Removed a duplicate access-refused status entry introduced by
combining those patches. USER_VERBS is unchanged. No schema or migration changed.
This is a pre-gate candidate per Sage's explicit instruction to commit/push/request
round 2 before Sage runs the full gate. Only the expected-red new fallback test ran
under sage-3358. No green test claim, no suite/mutant result and no old-file run is
implied. Every touched test file still needs its whole-file run on Sage's slot, plus
all touched suites and mutants. Any first-run red in launcher/creative/chat-browser
returns to Mos via Sage before fixing. TMPDIR for gate runs comes only from mktemp -d,
with no underscore; remove a matching compose default network only if created.
## Round 3 preparation — gate run 1 (sage-3433)
Sage ran candidate b44332a93 over refactor 1e4c1e6e9 with the pinned esbuild
and MOSAIC_REQUIRE_EDITOR_BUILD=1. Gate RED: bus 891/0, business 231/0,
CLI 940/1, plugins 110/1, webui 372/20. No mutants ran. Sage reproduced
every failing file on b44332a93 alone, excluding overlay drift as the cause.
Evidence: /mnt/storage/scratch/sage-r272/run-*.txt and split-*.txt.
A: the new session CLI real-broker fixture omitted role authority. Verified
checkBusiness requires withinRole and crossRole arrays on every role; added
empty arrays to chief and assistant in that fixture only, as sage-3433 permits.
No production authority or existing assertion changed. No local tests ran.
B remains held for Mos under mos-1316/1317: initial bare-chat rendering compares
old?.id with undefined id, then dereferences null old at the sessions/session/key
initializers. Sage proposes old && old.id === id at all three sites. No B edit
made pending the ruling. C (plugins harness compactions) is separately owned.
Round 3 is not committed or pushed yet. The manifest path set remains the same
17 paths; regenerate hashes when the authorized fixes are complete. Future
launcher, creative and chat-browser runs use a TMPDIR allocated with
mktemp -d /mnt/storage/scratch/tmp/<alnum>XXXXXX, because bwrap hides /tmp.
Sage owns the next full gate. No tests, repo Node or queue writes here.
### Round 3 candidate — mos-1455 / sage-3435
Mos authorized B: all three initial render comparisons now use old && old.id === id,
so an initial list route cannot dereference null old. A remains fixture-only.
chat-browser.test.mjs and granted-user.test.mjs are byte-identical to b44332a93.
No pre-existing assertion, authority validator or shared stub changed.
Frozen manifest: manifest.r3.txt, 17 paths unchanged; SHA256 f98c5b7a884ed1e5951a584227ece16d403baf62199d405aaa1981d667e9e075.
Parent candidate: b44332a9360504291dda3f81131c934b286f3226; base remains 5fdfd7275.
Only session-cli.test.mjs and public/chat.js product hashes differ from round 2.
This follow-up commit/push is authorized before the round 3 gate by sage-3435.
No local tests, repo Node, mutants or queue writes ran. Gate remains RED until
Sage reruns; plugins harness compactions is a separately owned dependency, and
Mos declined an EXCEPT edit. Scrooge reviews this A/B delta; Sage posts round 3.
## Round 4 — scoped browser heading waits (mos-1460/1461)
Round 3 gate on 72690cae7: bus 891/0, CLI 941/0, business 231/0; plugins
had only the allowed exact base red, checked by Mos; webui 390/2. Both reds
were newly added chat-browser missing-session waits at lines 361 and 437.
Whole-file rerun reproduced 17/2. No round 3 green acceptance claim.
Diagnosis authorized by sage-3450/3453 and mos-1460: unchanged whole-file run
17/2, 28.223 s; scratch-only CDP probes showed the route reaching chat.js:176,
catalog rows A/B without M, and catch receiving session-not-found with status
404. DOM had first h1 "Control board" (shell), then .chat-area h1 "Thread
unavailable". Product refusal and painting worked. Evidence retained under
/mnt/storage/scratch/tmp/hueyP1enyB/ (baseline.tap, probe.tap, probe-catch.tap,
proposed.diff); scratch probe source removed, tracked tree remained clean.
mos-1461 / sage-3458 authorizes exactly two selector changes: document-wide
h1 becomes .chat-area h1 in those waits. Expected text, timeout and every
other line of chat-browser.test.mjs remain byte-identical to 72690cae7.
This scopes the same assertion to its component; it does not weaken the
composer/write/draft/recovery checks. No production code changes in round 4.
manifest.r4.txt retains the same 17 paths; SHA256 a47ed1a23fb98c1ffe6cbcc4e7130e5c515387a2c5dc41e5ae1cbf04640d8c1b.
Only chat-browser.test.mjs hash differs from r3. New local follow-up commit
is authorized before execution; push and single-file run await Sage CLEAR
while Gizmoduck owns the slot. Required pass: whole chat-browser.test.mjs,
19/19 and skipped 0, timeout -k 10 300, TMPDIR from
mktemp -d /mnt/storage/scratch/tmp/hueyXXXXXX. No round 4 run yet.
After green, claimant moves row to in-review; Sage posts request and
Scrooge reviews the exact two-line delta. Full five-suite gate remains Sage's.
-1
View File
@@ -1 +0,0 @@
5fdfd7275ce3048e488d93dcdb1f9f2aa5961a69
@@ -1,62 +0,0 @@
#!/usr/bin/env python3
"""Run only on Sage's slot. Mutate disposable sources, never the candidate tree."""
import argparse
import json
import os
from pathlib import Path
import re
import shutil
import subprocess
GUARD = "if (err.code === 'access-refused' && !match[3]) return null;"
CONTROLS = " if (current.legacyDefault) return '<p role=\"status\">Sessions are not available for this account.</p>';"
MUTANTS = {
'F1-any-code': (GUARD, "if (!match[3]) return null;", 'human-required catalog failure'),
'F2-explicit-link': (GUARD, "if (err.code === 'access-refused') return null;", 'granted explicit-session route'),
'F3-controls': (CONTROLS, ' // mutant: show session controls on a legacy fallback', 'granted legacy route'),
'F4-widened-key': (GUARD, "if (['access-refused', 'unreachable', 'no-bus-host', 'invalid-response'].includes(err.code) && !match[3]) return null;", 'timeout catalog failure'),
}
def main():
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument('--out', type=Path, required=True)
ap.add_argument('--mutant', choices=list(MUTANTS), action='append')
args = ap.parse_args()
source = Path(__file__).resolve().parents[4]
args.out.mkdir(parents=True, exist_ok=True)
for name in args.mutant or MUTANTS:
# Explicit mktemp, no underscores: same TMPDIR rule as the real gate.
scratch = Path(subprocess.check_output(['mktemp', '-d', '/tmp/huey272-fallback-mutant-XXXXXXXX'], text=True).strip())
try:
for directory in ['packages', 'roles']:
shutil.copytree(source / directory, scratch / directory)
if (source / 'node_modules').exists():
(scratch / 'node_modules').symlink_to((source / 'node_modules').resolve(), target_is_directory=True)
for filename in ['package.json', 'RELEASE']:
if (source / filename).exists():
shutil.copy2(source / filename, scratch / filename)
path = scratch / 'packages/webui/src/public/chat.js'
old, new, target = MUTANTS[name]
text = path.read_text()
if text.count(old) != 1:
raise RuntimeError(f'{name}: mutation anchor is not unique')
path.write_text(text.replace(old, new, 1))
env = dict(os.environ, TMPDIR=str(scratch))
result = subprocess.run(['timeout', '-k', '10', '300', 'node', '--test', '--test-reporter=tap',
'packages/webui/tests/chat-sessions-access.test.mjs'],
cwd=scratch, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
(args.out / f'{name}.tap').write_text(result.stdout)
killed = result.returncode == 1 and 'ERR_ASSERTION' in result.stdout and bool(
re.search(r'not ok [^\n]*' + re.escape(target), result.stdout))
print(json.dumps({'mutant': name, 'returncode': result.returncode, 'assertion_kill': killed}), flush=True)
if not killed:
raise RuntimeError(f'{name}: not an assertion kill; stop, diagnose and report before any fix')
finally:
# These tests never use compose. Remove the disposable copy after browser teardown;
# retained TAP lives only in --out. No live network/volume/service cleanup is performed.
shutil.rmtree(scratch)
if __name__ == '__main__':
main()
@@ -1,16 +0,0 @@
fb518c370aeb531220de123464f0a809156fc546b51d7195f4f9ca660409cf22 packages/bus/src/broker.mjs
35d044b0904ce913b3356b02cdc5bf22babecf738b511dca80c75f704e4ef78e packages/bus/tests/user-principal.test.mjs
e795bc4ee5aa038835edfeabe3498e53fdd700df478198cac6767498e2fac0b7 packages/cli/README.md
96c4f93628964b6ea10fb87d5cf936f9ecf2e7286aa20c0914ae8b0fb32c47e7 packages/cli/src/cli.mjs
0c31ac7260e77556f30f33a9932dc59a30f394982d8556650af7c521d2bcc947 packages/cli/src/session.mjs
58888b7731f8009d4c3f8be2caf4445f13dd8f534e1633f6e2720b259fcc3f92 packages/cli/src/thread.mjs
27fb7dd91007ec5f729fbe854219f423177cf4db2d44d1f8b04c7e8c5e6db90a packages/cli/tests/session-cli.test.mjs
5e7e1ec169392ee3065f8f47d19732ebbe8bdd90f9193581425b956e66da6b73 packages/plugins/channel/cli/index.mjs
aa086c365c4a6b0eaf84359a20ef2b30e723013ada6573fb0133163d5bf98a74 packages/plugins/channel/webui/index.mjs
143bf601badf5cc2b25cb24368ace2ec34840abec858d272af239d6a4ddcdecb packages/plugins/tests/channel.test.mjs
0720f66a57d965c9275f598b7c7ac438f238a0fac52808fc8f10312b85ba2727 packages/webui/src/chat-http.mjs
65fd3fd2337aaa88245a9fb10b55fd872f9150085ff9a53fe522e758a93c64fa packages/webui/src/chat.mjs
88dd353f5df0603ed1fd43dd543ef7b45af93fee72b6bb6a03a26c068202fbd3 packages/webui/src/public/chat.css
074d570aee4e2b6cdcbd6b8be399a2a21e863f2d620f95dad8d93ffc7d9c46da packages/webui/src/public/chat.js
2161c4830a3f73f0343e76521b948b933e401f7b9ba4ef8a5c75bf99c565d6b6 packages/webui/tests/chat-browser.test.mjs
b79a8809951580187b581450cdd4012245f2d88a371bf7d2f123580af8815449 packages/webui/tests/chat.test.mjs
@@ -1,17 +0,0 @@
c21f1bd9af6841126baf19f5c9926ca23ba8e56b9af342373d8e4fefcee63632 packages/bus/src/broker.mjs
3957243d59e50eaa2326b88b9205ed8e8b5d33bde2ce1ef62e68f20e56283568 packages/bus/tests/user-principal.test.mjs
0a920131a981c2a1c9b73428a998966f446babae4dfe7d10eebdd6455571c0c9 packages/cli/README.md
96c4f93628964b6ea10fb87d5cf936f9ecf2e7286aa20c0914ae8b0fb32c47e7 packages/cli/src/cli.mjs
1a30048032f5bb64419ae9716a1692978bc1a137220a094d1900298aca6ba1d7 packages/cli/src/session.mjs
58888b7731f8009d4c3f8be2caf4445f13dd8f534e1633f6e2720b259fcc3f92 packages/cli/src/thread.mjs
359c9fbfe30d860046ee3d29d23681900d9c73b3a4c3a91cd2f4e1d2c6be143e packages/cli/tests/session-cli.test.mjs
5e7e1ec169392ee3065f8f47d19732ebbe8bdd90f9193581425b956e66da6b73 packages/plugins/channel/cli/index.mjs
aa086c365c4a6b0eaf84359a20ef2b30e723013ada6573fb0133163d5bf98a74 packages/plugins/channel/webui/index.mjs
143bf601badf5cc2b25cb24368ace2ec34840abec858d272af239d6a4ddcdecb packages/plugins/tests/channel.test.mjs
6e743878e507be20d87ae10afdb01c105f6f4fab76d02410e065f3f20d18e597 packages/webui/src/chat-http.mjs
7a5a18a9879fe7132f20a651c6927b007475571bd8fc45314eda9d6809288cea packages/webui/src/chat.mjs
88dd353f5df0603ed1fd43dd543ef7b45af93fee72b6bb6a03a26c068202fbd3 packages/webui/src/public/chat.css
e4c25743a6d8cbe15eaac2b4d8c3bd309ffa5793f35584d862690a9d89725b72 packages/webui/src/public/chat.js
1aa313f1602cf87a0ddac145bf58bbd7f1073c02009c65797e85418fdfdbd838 packages/webui/tests/chat-browser.test.mjs
23de8678566f24a6c8bf0ca75b4550969015b06253586070e229f4eaf0bba2b4 packages/webui/tests/chat-sessions-access.test.mjs
773538c0c6a26ab525aa30e588249ba4b4ee981129533db0348f2107da5dd1df packages/webui/tests/chat.test.mjs
Loaded 100 of 465 files, more files were not shown because too many files have changed in this diff. Show more