${refusal(err) ? `refused: ${txt(err.code)}. ` : ''}${why(err)} Console shows nothing rather than a guess. Nothing was written.
${retry}
${empty('Nothing to show.', refusal(err) ? 'The view stays empty until the problem above is fixed.' : 'Read again, or come back when the bus answers.')}`;
+ const staleBanner = err => `
The last read failed. ${why(err)} This is what was read before, ${when(readAt)}. Nothing was changed.
${retry}
`;
+ // Freshness line in the command bar for bus pages.
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M01.txt b/agents/darkwing/work/queue-53-review/r1/mut/M01.txt
new file mode 100644
index 00000000..cdb05072
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M01.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (7051.173711ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (7270.330094ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8305.819932ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (465.310562ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (142.624471ms)
+✔ bus refusals map to statuses and never carry a path or a stack (60.934334ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2813.055778ms)
+✔ busReader takes --business, else the live bus host, else refuses (488.166908ms)
+✔ humanCall kills a transport that runs past its timeout (538.051321ms)
+✔ serve refuses a --business value that is not a business id (500.293546ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5952.997676ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3085.264687ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1717.994807ms)
+✔ conversation view: seats without history say so and offer no reply (1097.051106ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (6156.19174ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56811.320882ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6077.150559ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (25388.059358ms)
+✔ loopback host and board origin fail closed (10.456016ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (214.245672ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (234.702735ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1644.897153ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (3.908141ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (3.212866ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (2.272588ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7192.367132ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3294.146704ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 57463.713678
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M02.diff b/agents/darkwing/work/queue-53-review/r1/mut/M02.diff
new file mode 100644
index 00000000..f3974052
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M02.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js
+index 1bd88cf2..c941e531 100644
+--- a/packages/webui/src/public/app.js
++++ b/packages/webui/src/public/app.js
+@@ -303,7 +303,7 @@
+ // A refusal (403) fails closed: the last data is hidden, not shown as current. Any other failure keeps the last data with its scan time.
+ function error(err) {
+ failed = true; $('error').hidden = false;
+- const refused = err.status === 403;
++ const refused = false;
+ $('error').className = refused ? 'banner ref' : 'banner err';
+ $('board-refused').hidden = !refused; document.body.classList.toggle('board-refused', refused);
+ $('error').innerHTML = refused
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M02.txt b/agents/darkwing/work/queue-53-review/r1/mut/M02.txt
new file mode 100644
index 00000000..af12910c
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M02.txt
@@ -0,0 +1,59 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5906.359439ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6421.571921ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7790.380244ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (319.811693ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (141.932338ms)
+✔ bus refusals map to statuses and never carry a path or a stack (135.266704ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2526.57828ms)
+✔ busReader takes --business, else the live bus host, else refuses (389.079573ms)
+✔ humanCall kills a transport that runs past its timeout (531.702165ms)
+✔ serve refuses a --business value that is not a business id (225.100624ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5885.859729ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2943.465302ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1599.972822ms)
+✔ conversation view: seats without history say so and offer no reply (1304.01305ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5738.474826ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56134.123141ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5780.259394ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (24979.223692ms)
+✔ loopback host and board origin fail closed (11.709394ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (216.387749ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (108.234726ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1702.907874ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.588661ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (3.421399ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (2.1794ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4814.72897ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3632.166067ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 56812.431306
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4814.72897ms)
+ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ + actual - expected
+
+ + 'banner err'
+ - 'banner ref'
+ ^
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:140:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: 'banner err',
+ expected: 'banner ref',
+ operator: 'strictEqual',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M03.diff b/agents/darkwing/work/queue-53-review/r1/mut/M03.diff
new file mode 100644
index 00000000..ca6882cd
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M03.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js
+index 1bd88cf2..a5cf03b4 100644
+--- a/packages/webui/src/public/app.js
++++ b/packages/webui/src/public/app.js
+@@ -305,7 +305,7 @@
+ failed = true; $('error').hidden = false;
+ const refused = err.status === 403;
+ $('error').className = refused ? 'banner ref' : 'banner err';
+- $('board-refused').hidden = !refused; document.body.classList.toggle('board-refused', refused);
++ $('board-refused').hidden = !refused;
+ $('error').innerHTML = refused
+ ? `
The board refused the read. refused: ${esc(err.message)} Board: ${esc(board)}. Console shows nothing rather than a guess. Use Refresh to try again.
`
+ : `
${esc(err.message)} Board: ${esc(board)}. ${data ? `Showing last known data.${data.generatedAt ? ` Scanned ${esc(data.generatedAt)}.` : ''}` : 'No board data loaded.'} Use Refresh to try again.
`;
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M03.txt b/agents/darkwing/work/queue-53-review/r1/mut/M03.txt
new file mode 100644
index 00000000..211311a8
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M03.txt
@@ -0,0 +1,56 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5843.810902ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6581.265927ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8986.282108ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (1059.307807ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (207.046686ms)
+✔ bus refusals map to statuses and never carry a path or a stack (70.701032ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2229.666935ms)
+✔ busReader takes --business, else the live bus host, else refuses (349.885509ms)
+✔ humanCall kills a transport that runs past its timeout (528.250357ms)
+✔ serve refuses a --business value that is not a business id (216.252848ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (6331.227648ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3044.074164ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1387.057031ms)
+✔ conversation view: seats without history say so and offer no reply (1032.915675ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (6249.684157ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56312.695193ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5805.305368ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23253.279537ms)
+✔ loopback host and board origin fail closed (9.249748ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (148.461303ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (182.583553ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1604.6308ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.446228ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.794556ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.912476ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (6098.431393ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3104.411072ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 56801.360852
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (6098.431393ms)
+ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+
+ 'block' !== 'none'
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:142:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: 'block',
+ expected: 'none',
+ operator: 'strictEqual',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M04.diff b/agents/darkwing/work/queue-53-review/r1/mut/M04.diff
new file mode 100644
index 00000000..d02ae91e
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M04.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
+index f5389ee6..5496a305 100644
+--- a/packages/webui/src/public/bus.js
++++ b/packages/webui/src/public/bus.js
+@@ -369,7 +369,7 @@
+ const failTitle = err => err.status === 403 ? 'Bus refused the read' : ['not-configured', 'no-bus-host'].includes(err.code) ? 'No bus to read' : 'The read failed';
+ // A refusal fails closed: no kept data, the code in mono. Any other failure keeps the last read, labelled with its time.
+ const refusal = err => err.status === 403 || ['not-configured', 'no-bus-host'].includes(err.code);
+- const failedView = err => `${head(failTitle(err))}
${refusal(err) ? `refused: ${txt(err.code)}. ` : ''}${why(err)} Console shows nothing rather than a guess. Nothing was written.
${retry}
${empty('Nothing to show.', refusal(err) ? 'The view stays empty until the problem above is fixed.' : 'Read again, or come back when the bus answers.')}`;
++ const failedView = err => `${head(failTitle(err))}
${refusal(err) ? `refused: ${txt(err.code)}. ` : ''}${why(err)} Console shows nothing rather than a guess. Nothing was written.
${retry}
${empty('Nothing to show.', refusal(err) ? 'The view stays empty until the problem above is fixed.' : 'Read again, or come back when the bus answers.')}`;
+ const staleBanner = err => `
The last read failed. ${why(err)} This is what was read before, ${when(readAt)}. Nothing was changed.
${retry}
`;
+ // Freshness line in the command bar for bus pages.
+ const stamp = iso => { const t = Date.parse(iso); return Number.isFinite(t) ? `${new Date(t).toISOString().slice(11, 19)} UTC` : 'unknown'; };
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M04.txt b/agents/darkwing/work/queue-53-review/r1/mut/M04.txt
new file mode 100644
index 00000000..f7ae37e2
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M04.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5248.350804ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6871.236761ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (9267.987367ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (970.658233ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (316.969409ms)
+✔ bus refusals map to statuses and never carry a path or a stack (258.400443ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2432.255818ms)
+✔ busReader takes --business, else the live bus host, else refuses (184.834293ms)
+✔ humanCall kills a transport that runs past its timeout (528.843918ms)
+✔ serve refuses a --business value that is not a business id (199.945476ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5325.287046ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3880.82363ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1896.347832ms)
+✔ conversation view: seats without history say so and offer no reply (1341.397952ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (7915.59178ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (57016.635343ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6078.323228ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23058.579464ms)
+✔ loopback host and board origin fail closed (13.230744ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (310.414402ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (150.209364ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1760.353157ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.913986ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (3.340836ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (2.36321ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7850.747047ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2933.64496ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 57785.087003
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M05.diff b/agents/darkwing/work/queue-53-review/r1/mut/M05.diff
new file mode 100644
index 00000000..eb9173e9
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M05.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
+index f5389ee6..60995f29 100644
+--- a/packages/webui/src/public/bus.js
++++ b/packages/webui/src/public/bus.js
+@@ -375,7 +375,7 @@
+ const stamp = iso => { const t = Date.parse(iso); return Number.isFinite(t) ? `${new Date(t).toISOString().slice(11, 19)} UTC` : 'unknown'; };
+ function freshBus(state) {
+ $('fresh-bus').innerHTML = state === 'failed' ? 'Bus not read: the read failed'
+- : `Bus read ${esc(stamp(readAt))}${readAt ? ` (${esc(ago(readAt))})` : ''}${state === 'stale' ? ' · stale: the last read failed' : ''}`;
++ : `Bus read ${esc(stamp(readAt))}${readAt ? ` (${esc(ago(readAt))})` : ''}`;
+ }
+
+ // ---------------------------------------------------------------- router
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M05.txt b/agents/darkwing/work/queue-53-review/r1/mut/M05.txt
new file mode 100644
index 00000000..060325df
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M05.txt
@@ -0,0 +1,71 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5791.84315ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5931.424696ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8208.335483ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (288.745639ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (95.589345ms)
+✔ bus refusals map to statuses and never carry a path or a stack (43.548131ms)
+✔ humanCall speaks the human transport protocol without blocking the server (3157.970328ms)
+✔ busReader takes --business, else the live bus host, else refuses (182.605399ms)
+✔ humanCall kills a transport that runs past its timeout (528.453388ms)
+✔ serve refuses a --business value that is not a business id (173.453275ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5913.007381ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2826.523101ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1818.54918ms)
+✔ conversation view: seats without history say so and offer no reply (1217.464307ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5971.136144ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55587.199523ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5785.97143ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22792.773591ms)
+✔ loopback host and board origin fail closed (7.422204ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (114.173784ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (46.336575ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (921.432069ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (8.890882ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.17736ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.56056ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5850.038936ms)
+✖ five states on Board, Inbox, Tasks, Agents and Trail (2552.965234ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 25
+ℹ fail 2
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 55919.285318
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5850.038936ms)
+ AssertionError [ERR_ASSERTION]: The input did not match the regular expression /stale: the last read failed/. Input:
+
+ 'Bus read 17:41:19 UTC (0 s ago)'
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:187:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: 'Bus read 17:41:19 UTC (0 s ago)',
+ expected: /stale: the last read failed/,
+ operator: 'match',
+ diff: 'simple'
+ }
+
+test at tests/shell.test.mjs:278:1
+✖ five states on Board, Inbox, Tasks, Agents and Trail (2552.965234ms)
+ AssertionError [ERR_ASSERTION]: #/inbox
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:333:14)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: false,
+ code: 'ERR_ASSERTION',
+ actual: 'Bus read 17:41:23 UTC (0 s ago)',
+ expected: /stale: the last read failed/,
+ operator: 'match',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M06.diff b/agents/darkwing/work/queue-53-review/r1/mut/M06.diff
new file mode 100644
index 00000000..e0fb2a09
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M06.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js
+index 1bd88cf2..78a1bf8d 100644
+--- a/packages/webui/src/public/app.js
++++ b/packages/webui/src/public/app.js
+@@ -41,7 +41,7 @@
+ palette = p.id;
+ if (!['system', 'light', 'dim', 'dark'].includes(mode)) mode = 'system';
+ document.documentElement.dataset.palette = palette;
+- if (mode === 'system') delete document.documentElement.dataset.mode; else document.documentElement.dataset.mode = mode;
++ document.documentElement.dataset.mode = mode;
+ $('palette').value = palette; $('mode').value = mode;
+ try { localStorage.setItem('mosaic-console-appearance', JSON.stringify({ palette, mode })); } catch {}
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M06.txt b/agents/darkwing/work/queue-53-review/r1/mut/M06.txt
new file mode 100644
index 00000000..242386b3
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M06.txt
@@ -0,0 +1,56 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5268.206473ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5667.727448ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6423.223294ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (397.075731ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (126.647007ms)
+✔ bus refusals map to statuses and never carry a path or a stack (50.303543ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2065.282756ms)
+✔ busReader takes --business, else the live bus host, else refuses (206.772468ms)
+✔ humanCall kills a transport that runs past its timeout (536.593624ms)
+✔ serve refuses a --business value that is not a business id (216.440541ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5279.816257ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2768.013147ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1710.014915ms)
+✔ conversation view: seats without history say so and offer no reply (955.788723ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5054.287458ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54831.221513ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4747.666103ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23326.297774ms)
+✔ loopback host and board origin fail closed (9.530125ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (132.775432ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (129.121734ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (813.942492ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.744558ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.122253ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.750309ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5320.290317ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2836.644907ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 55294.850895
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5320.290317ms)
+ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+
+ true !== false
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:104:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: true,
+ expected: false,
+ operator: 'strictEqual',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M07.diff b/agents/darkwing/work/queue-53-review/r1/mut/M07.diff
new file mode 100644
index 00000000..d1e82e49
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M07.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
+index f5389ee6..e7305cbf 100644
+--- a/packages/webui/src/public/bus.js
++++ b/packages/webui/src/public/bus.js
+@@ -477,7 +477,7 @@
+ const t = $('toast'); clearTimeout(toastTimer);
+ if (text === null) { t.className = 'toast'; t.textContent = ''; return; }
+ t.className = `toast on${error ? ' err' : ''}`;
+- t.innerHTML = `${esc(text)}${error ? '' : ''}`;
++ t.innerHTML = `${text}${error ? '' : ''}`;
+ if (!error) toastTimer = setTimeout(() => toast(null), 2600);
+ }
+
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M07.txt b/agents/darkwing/work/queue-53-review/r1/mut/M07.txt
new file mode 100644
index 00000000..a53f2ec2
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M07.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3498.424498ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5073.27053ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5860.251528ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (316.037593ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (106.598219ms)
+✔ bus refusals map to statuses and never carry a path or a stack (85.782079ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2200.847869ms)
+✔ busReader takes --business, else the live bus host, else refuses (239.201748ms)
+✔ humanCall kills a transport that runs past its timeout (533.279441ms)
+✔ serve refuses a --business value that is not a business id (256.027601ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3551.87569ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2463.641056ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1169.125934ms)
+✔ conversation view: seats without history say so and offer no reply (841.998568ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3608.632384ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54356.685952ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3674.33323ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22885.872246ms)
+✔ loopback host and board origin fail closed (9.397593ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (128.255402ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (105.743453ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1209.792727ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.322274ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.723359ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.811832ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4370.26785ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2285.134171ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 54819.589769
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M08.diff b/agents/darkwing/work/queue-53-review/r1/mut/M08.diff
new file mode 100644
index 00000000..a549ca88
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M08.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
+index f5389ee6..8911ba97 100644
+--- a/packages/webui/src/public/bus.js
++++ b/packages/webui/src/public/bus.js
+@@ -496,7 +496,7 @@
+ const q = $('cmdk-input').value.trim().toLowerCase();
+ pkShown = pkAll.filter(i => !q || `${i.label} ${i.group}`.toLowerCase().includes(q)).slice(0, 50);
+ pkAt = Math.min(pkAt, Math.max(0, pkShown.length - 1));
+- $('cmdk-list').innerHTML = pkShown.length ? pkShown.map((i, n) => `
';
+ if (pkShown.length) { $('cmdk-input').setAttribute('aria-activedescendant', `cmdk-opt-${pkAt}`); $(`cmdk-opt-${pkAt}`)?.scrollIntoView({ block: 'nearest' }); }
+ else $('cmdk-input').removeAttribute('aria-activedescendant');
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M08.txt b/agents/darkwing/work/queue-53-review/r1/mut/M08.txt
new file mode 100644
index 00000000..81027c30
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M08.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5754.334404ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6557.501052ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8416.074858ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (574.930974ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (797.089799ms)
+✔ bus refusals map to statuses and never carry a path or a stack (302.286778ms)
+✔ humanCall speaks the human transport protocol without blocking the server (1995.597872ms)
+✔ busReader takes --business, else the live bus host, else refuses (228.695172ms)
+✔ humanCall kills a transport that runs past its timeout (528.891783ms)
+✔ serve refuses a --business value that is not a business id (167.030411ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5671.033678ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3129.076355ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1801.429431ms)
+✔ conversation view: seats without history say so and offer no reply (899.175464ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (6209.788072ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55273.916567ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6379.070681ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (24135.002505ms)
+✔ loopback host and board origin fail closed (9.440587ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (152.276494ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (124.824653ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1771.062865ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.492243ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.818143ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.856825ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (6039.027572ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3366.746341ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 55726.493145
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M09.diff b/agents/darkwing/work/queue-53-review/r1/mut/M09.diff
new file mode 100644
index 00000000..907d2972
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M09.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/shell.css b/packages/webui/src/public/shell.css
+index ae98ebd5..1d0049e5 100644
+--- a/packages/webui/src/public/shell.css
++++ b/packages/webui/src/public/shell.css
+@@ -18,7 +18,7 @@ body{font:400 14px/1.5 var(--font);color:var(--text);background:var(--canvas)}
+ code,kbd,pre,.mono{font-family:var(--mono);font-size:12.5px}
+ kbd{border:1px solid var(--line);border-bottom-width:2px;border-radius:4px;padding:0 .35em;background:var(--surface);color:var(--strong);white-space:nowrap;font-size:11.5px}
+ .count,td,.s1-twhen,time,.fresh,.kv dd{font-variant-numeric:tabular-nums}
+-:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
++:focus-visible{outline:2px solid var(--focus);outline-offset:0}
+ table.sessions tbody tr:focus-visible,table.s1-table tbody tr:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
+ svg.i{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
+
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M09.txt b/agents/darkwing/work/queue-53-review/r1/mut/M09.txt
new file mode 100644
index 00000000..4a3218e3
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M09.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4400.430089ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4300.640965ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5301.127984ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (276.547118ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (103.39068ms)
+✔ bus refusals map to statuses and never carry a path or a stack (65.485599ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2151.965579ms)
+✔ busReader takes --business, else the live bus host, else refuses (163.976348ms)
+✔ humanCall kills a transport that runs past its timeout (528.285651ms)
+✔ serve refuses a --business value that is not a business id (172.181607ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4371.961867ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2840.647816ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1998.086292ms)
+✔ conversation view: seats without history say so and offer no reply (1131.857592ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4574.654406ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53632.384811ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4727.108522ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22586.932856ms)
+✔ loopback host and board origin fail closed (7.712823ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (138.907671ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (128.085616ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1065.673871ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.242354ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.442883ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.419635ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4421.026726ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2740.769195ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 54058.53995
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M10.diff b/agents/darkwing/work/queue-53-review/r1/mut/M10.diff
new file mode 100644
index 00000000..30dc4826
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M10.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/shell.css b/packages/webui/src/public/shell.css
+index ae98ebd5..a410b866 100644
+--- a/packages/webui/src/public/shell.css
++++ b/packages/webui/src/public/shell.css
+@@ -18,7 +18,7 @@ body{font:400 14px/1.5 var(--font);color:var(--text);background:var(--canvas)}
+ code,kbd,pre,.mono{font-family:var(--mono);font-size:12.5px}
+ kbd{border:1px solid var(--line);border-bottom-width:2px;border-radius:4px;padding:0 .35em;background:var(--surface);color:var(--strong);white-space:nowrap;font-size:11.5px}
+ .count,td,.s1-twhen,time,.fresh,.kv dd{font-variant-numeric:tabular-nums}
+-:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
++:focus-visible{outline:1px solid var(--focus);outline-offset:2px}
+ table.sessions tbody tr:focus-visible,table.s1-table tbody tr:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
+ svg.i{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
+
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M10.txt b/agents/darkwing/work/queue-53-review/r1/mut/M10.txt
new file mode 100644
index 00000000..e251f420
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M10.txt
@@ -0,0 +1,53 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3859.095965ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4343.268551ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6605.907754ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (526.606027ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (153.465165ms)
+✔ bus refusals map to statuses and never carry a path or a stack (55.167495ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2288.47965ms)
+✔ busReader takes --business, else the live bus host, else refuses (261.219118ms)
+✔ humanCall kills a transport that runs past its timeout (531.076935ms)
+✔ serve refuses a --business value that is not a business id (384.431269ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3856.193842ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3060.373427ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1167.486824ms)
+✔ conversation view: seats without history say so and offer no reply (944.374404ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3875.563993ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56587.254808ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3876.724799ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23324.969843ms)
+✔ loopback host and board origin fail closed (8.786574ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (146.934201ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (134.739961ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1346.776736ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (0.958173ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.776603ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.395916ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (3843.314767ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2988.092ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 57019.428623
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (3843.314767ms)
+ AssertionError [ERR_ASSERTION]: #cmdk outline 1px
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:163:69)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: false,
+ code: 'ERR_ASSERTION',
+ actual: false,
+ expected: true,
+ operator: '==',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M11.diff b/agents/darkwing/work/queue-53-review/r1/mut/M11.diff
new file mode 100644
index 00000000..126ab89a
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M11.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/shell.css b/packages/webui/src/public/shell.css
+index ae98ebd5..473b94fe 100644
+--- a/packages/webui/src/public/shell.css
++++ b/packages/webui/src/public/shell.css
+@@ -165,7 +165,7 @@ body.on-bus #board-refused{display:none}
+ .cmd-right label{flex:1 1 0;min-width:0}
+ .cmd-right .btn{flex:none}
+ /* The section list wraps rather than scrolling, so a blocking count never hides a section. */
+- .s1-sections{display:flex;flex-wrap:wrap;overflow-x:visible;flex-basis:100%;gap:2px;padding-bottom:2px}
++ .s1-sections{display:flex;flex-basis:100%;gap:2px;padding-bottom:2px}
+ .s1-section{border-radius:var(--r);padding:5px 8px;white-space:nowrap;flex:none}
+ .inspector{inset:0;top:0;width:100%;z-index:40;box-shadow:none}
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M11.txt b/agents/darkwing/work/queue-53-review/r1/mut/M11.txt
new file mode 100644
index 00000000..d7beaa7e
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M11.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (7740.004399ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (15045.20497ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (15277.238224ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (1915.102997ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (37.390122ms)
+✔ bus refusals map to statuses and never carry a path or a stack (16.731727ms)
+✔ humanCall speaks the human transport protocol without blocking the server (1654.594624ms)
+✔ busReader takes --business, else the live bus host, else refuses (229.623851ms)
+✔ humanCall kills a transport that runs past its timeout (528.322018ms)
+✔ serve refuses a --business value that is not a business id (173.324632ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (11063.547959ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (4337.313117ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1973.678474ms)
+✔ conversation view: seats without history say so and offer no reply (1440.938589ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (8131.126692ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (51061.883178ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (7907.667489ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (28815.695414ms)
+✔ loopback host and board origin fail closed (8.80561ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (302.179616ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (203.376087ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (867.064023ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (0.895645ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.910895ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.387285ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8972.170949ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (6074.516516ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 51415.549688
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M12.diff b/agents/darkwing/work/queue-53-review/r1/mut/M12.diff
new file mode 100644
index 00000000..39bfcdeb
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M12.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
+index f5389ee6..7dc2fb2c 100644
+--- a/packages/webui/src/public/bus.js
++++ b/packages/webui/src/public/bus.js
+@@ -209,7 +209,7 @@
+ const items = [['/', 'Board', '', 'board'], ['/inbox', 'Inbox', inboxCount ? `${inboxCount.open}${inboxCount.blocking ? ` ${blockChip(`${inboxCount.blocking} blocking`)}` : ''}` : '', 'inbox'], ['/tasks', 'Tasks', '', 'tasks'], ['/agents', 'Agents', '', 'agents']];
+ $('sections').innerHTML = items.map(([h, l, extra, icon]) => {
+ const cur = h === '/' ? route === '/' : route.startsWith(h) || (h === '/tasks' && route.startsWith('/trail/task')) || (h === '/inbox' && route.startsWith('/trail/decision'));
+- return `
`;
+ }).join('');
+ }
+ function countInbox(rows) { inboxCount = { open: rows.length, blocking: rows.filter(d => d.blocking).length }; }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M12.txt b/agents/darkwing/work/queue-53-review/r1/mut/M12.txt
new file mode 100644
index 00000000..96b38ea3
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M12.txt
@@ -0,0 +1,56 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (9498.845618ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (14178.704126ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (14655.718816ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (1567.119707ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (44.104039ms)
+✔ bus refusals map to statuses and never carry a path or a stack (20.542495ms)
+✔ humanCall speaks the human transport protocol without blocking the server (1704.198859ms)
+✔ busReader takes --business, else the live bus host, else refuses (193.649625ms)
+✔ humanCall kills a transport that runs past its timeout (529.634379ms)
+✔ serve refuses a --business value that is not a business id (195.352905ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (13040.964383ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3460.713697ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1590.068006ms)
+✔ conversation view: seats without history say so and offer no reply (1041.528275ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (7155.666046ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (61163.295912ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (8768.9756ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (30593.233514ms)
+✔ loopback host and board origin fail closed (10.042054ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (317.593824ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (158.705182ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1128.252253ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (0.836867ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.649855ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.204314ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7835.16493ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (5311.153032ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 61560.528856
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7835.16493ms)
+ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+
+ 0 !== 4
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:174:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: 0,
+ expected: 4,
+ operator: 'strictEqual',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M13.diff b/agents/darkwing/work/queue-53-review/r1/mut/M13.diff
new file mode 100644
index 00000000..f7981375
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M13.diff
@@ -0,0 +1,12 @@
+diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js
+index 1bd88cf2..05a6089e 100644
+--- a/packages/webui/src/public/app.js
++++ b/packages/webui/src/public/app.js
+@@ -296,7 +296,6 @@
+ function accept(value) {
+ if (!value || !Array.isArray(value.sessions) || value.sessions.some(r => !r || typeof r.project !== 'string' || typeof r.agent !== 'string')) throw new Error('Invalid board session data');
+ data = value; failed = false; $('error').hidden = true; $('error').className = 'banner err';
+- $('board-refused').hidden = true; document.body.classList.remove('board-refused');
+ for (const id of awaiting.keys()) { const r = row(id); if (r && !pending(r)) awaiting.delete(id); }
+ render();
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M13.txt b/agents/darkwing/work/queue-53-review/r1/mut/M13.txt
new file mode 100644
index 00000000..e84d21dc
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M13.txt
@@ -0,0 +1,55 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (7188.855809ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (7271.704177ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8077.985604ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (532.536088ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (239.548482ms)
+✔ bus refusals map to statuses and never carry a path or a stack (25.479189ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2707.003302ms)
+✔ busReader takes --business, else the live bus host, else refuses (368.432283ms)
+✔ humanCall kills a transport that runs past its timeout (532.75841ms)
+✔ serve refuses a --business value that is not a business id (253.697624ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (7156.651219ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2332.626421ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1564.440958ms)
+✔ conversation view: seats without history say so and offer no reply (1088.29525ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (7330.458092ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (57918.906247ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (7193.459074ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (24552.102054ms)
+✔ loopback host and board origin fail closed (9.968967ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (200.59317ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (312.379414ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1496.667453ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.404264ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.784097ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.975862ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7313.200709ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2852.110982ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 58512.874055
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7313.200709ms)
+ AssertionError [ERR_ASSERTION]: Expected "actual" to be strictly unequal to:
+
+ 'none'
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:147:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: 'none',
+ expected: 'none',
+ operator: 'notStrictEqual',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M14.diff b/agents/darkwing/work/queue-53-review/r1/mut/M14.diff
new file mode 100644
index 00000000..8cfa5b9d
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M14.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
+index f5389ee6..24750eb1 100644
+--- a/packages/webui/src/public/bus.js
++++ b/packages/webui/src/public/bus.js
+@@ -525,7 +525,7 @@
+ const a = e.target.closest?.('#bus-view table.s1-table td.s1-title a');
+ if (!a || (e.key !== 'ArrowDown' && e.key !== 'ArrowUp')) return;
+ const links = [...a.closest('table').querySelectorAll('td.s1-title a')], i = links.indexOf(a);
+- e.preventDefault(); links[i + (e.key === 'ArrowDown' ? 1 : -1)]?.focus();
++ e.preventDefault(); links[i + (e.key === 'ArrowDown' ? -1 : 1)]?.focus();
+ });
+ window.addEventListener('hashchange', () => render(true));
+ $('refresh').addEventListener('click', () => render(false));
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M14.txt b/agents/darkwing/work/queue-53-review/r1/mut/M14.txt
new file mode 100644
index 00000000..4a4a5eee
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M14.txt
@@ -0,0 +1,56 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (7435.806805ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (7593.581724ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7674.576199ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (288.355604ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (177.319585ms)
+✔ bus refusals map to statuses and never carry a path or a stack (56.443497ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2392.104767ms)
+✔ busReader takes --business, else the live bus host, else refuses (283.865828ms)
+✔ humanCall kills a transport that runs past its timeout (530.708861ms)
+✔ serve refuses a --business value that is not a business id (293.569333ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (7220.28677ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2322.290614ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1306.780472ms)
+✔ conversation view: seats without history say so and offer no reply (977.03291ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (7074.876596ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56183.087593ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6068.013766ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (25233.057689ms)
+✔ loopback host and board origin fail closed (9.354686ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (147.853081ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (132.817076ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1234.273937ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.454396ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.999574ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.794182ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7048.453702ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2437.068864ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 56798.36445
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7048.453702ms)
+ AssertionError [ERR_ASSERTION]: The input did not match the regular expression /Second task/. Input:
+
+ '#7 Kept task'
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:190:38)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: '#7 Kept task',
+ expected: /Second task/,
+ operator: 'match',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M15.diff b/agents/darkwing/work/queue-53-review/r1/mut/M15.diff
new file mode 100644
index 00000000..e145410e
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M15.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/serve.mjs b/packages/webui/src/serve.mjs
+index 280a228f..93a1958f 100644
+--- a/packages/webui/src/serve.mjs
++++ b/packages/webui/src/serve.mjs
+@@ -22,7 +22,7 @@ const files = new Map([
+ ['/', ['index.html', 'text/html; charset=utf-8']],
+ ...['app.js', 'brand.js', 'bus.js'].map(f => ['/' + f, [f, 'text/javascript; charset=utf-8']]),
+ ...['shared/app.css', 'tokens.css', 'console.css', 'live.css', 'bus.css', 'shell.css'].map(f => ['/' + f, [f, 'text/css; charset=utf-8']]),
+- ['/icons.svg', ['icons.svg', 'image/svg+xml']],
++ ['/icons.svg', ['icons.svg', 'text/plain']],
+ ...[400, 500, 600, 700].map(w => [`/assets/fonts/manrope-${w}.woff2`, [`assets/fonts/manrope-${w}.woff2`, 'font/woff2']]),
+ ...[400, 500, 700].map(w => [`/assets/fonts/jetbrains-mono-${w}.woff2`, [`assets/fonts/jetbrains-mono-${w}.woff2`, 'font/woff2']]),
+ ]);
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M15.txt b/agents/darkwing/work/queue-53-review/r1/mut/M15.txt
new file mode 100644
index 00000000..ada5ca4b
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M15.txt
@@ -0,0 +1,53 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5198.663054ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5584.343092ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7086.448634ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (267.907334ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (134.094408ms)
+✔ bus refusals map to statuses and never carry a path or a stack (114.691386ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2562.538599ms)
+✔ busReader takes --business, else the live bus host, else refuses (332.854133ms)
+✔ humanCall kills a transport that runs past its timeout (537.451045ms)
+✔ serve refuses a --business value that is not a business id (322.845795ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5397.416668ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2651.201165ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1371.821427ms)
+✔ conversation view: seats without history say so and offer no reply (1038.855758ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5467.101437ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54944.465486ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5191.271543ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (24030.373521ms)
+✔ loopback host and board origin fail closed (11.434928ms)
+✖ real board fixture passes through WebUI; assets and isolated seen/reply work (119.713354ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (86.02832ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1407.454964ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.624361ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (3.168129ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.840078ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5147.231405ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2781.962804ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 55451.838299
+
+✖ failing tests:
+
+test at tests/serve.test.mjs:22:1
+✖ real board fixture passes through WebUI; assets and isolated seen/reply work (119.713354ms)
+ AssertionError [ERR_ASSERTION]: /icons.svg
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/serve.test.mjs:41:101)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: false,
+ code: 'ERR_ASSERTION',
+ actual: false,
+ expected: true,
+ operator: '==',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M16.diff b/agents/darkwing/work/queue-53-review/r1/mut/M16.diff
new file mode 100644
index 00000000..c2605092
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M16.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/shell.css b/packages/webui/src/public/shell.css
+index ae98ebd5..ef259cfa 100644
+--- a/packages/webui/src/public/shell.css
++++ b/packages/webui/src/public/shell.css
+@@ -17,7 +17,7 @@ body{font:400 14px/1.5 var(--font);color:var(--text);background:var(--canvas)}
+ .tree-title,.label{font:700 11px/1.3 var(--font);letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
+ code,kbd,pre,.mono{font-family:var(--mono);font-size:12.5px}
+ kbd{border:1px solid var(--line);border-bottom-width:2px;border-radius:4px;padding:0 .35em;background:var(--surface);color:var(--strong);white-space:nowrap;font-size:11.5px}
+-.count,td,.s1-twhen,time,.fresh,.kv dd{font-variant-numeric:tabular-nums}
++
+ :focus-visible{outline:2px solid var(--focus);outline-offset:2px}
+ table.sessions tbody tr:focus-visible,table.s1-table tbody tr:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
+ svg.i{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M16.txt b/agents/darkwing/work/queue-53-review/r1/mut/M16.txt
new file mode 100644
index 00000000..ac120b27
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M16.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5815.739101ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6306.605756ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6556.920755ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (230.898299ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (124.363066ms)
+✔ bus refusals map to statuses and never carry a path or a stack (99.788074ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2290.268607ms)
+✔ busReader takes --business, else the live bus host, else refuses (512.295669ms)
+✔ humanCall kills a transport that runs past its timeout (532.334409ms)
+✔ serve refuses a --business value that is not a business id (378.3221ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5862.379595ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2207.341974ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1319.855887ms)
+✔ conversation view: seats without history say so and offer no reply (945.392215ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5845.529279ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55253.928142ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5750.276641ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23895.725251ms)
+✔ loopback host and board origin fail closed (11.74274ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (138.324612ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (125.990286ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1148.873598ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.610914ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.83ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (2.108441ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (6080.959306ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (2551.546835ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 55753.3057
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M17.diff b/agents/darkwing/work/queue-53-review/r1/mut/M17.diff
new file mode 100644
index 00000000..6b3a32b5
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M17.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js
+index 1bd88cf2..889f9b50 100644
+--- a/packages/webui/src/public/app.js
++++ b/packages/webui/src/public/app.js
+@@ -43,7 +43,7 @@
+ document.documentElement.dataset.palette = palette;
+ if (mode === 'system') delete document.documentElement.dataset.mode; else document.documentElement.dataset.mode = mode;
+ $('palette').value = palette; $('mode').value = mode;
+- try { localStorage.setItem('mosaic-console-appearance', JSON.stringify({ palette, mode })); } catch {}
++ try { localStorage.setItem('mosaic-console-look', JSON.stringify({ palette, mode })); } catch {}
+ }
+ $('palette').innerHTML = Brand.palettes.map(p => ``).join('');
+ try { const saved = JSON.parse(localStorage.getItem('mosaic-console-appearance')); if (saved) { palette = saved.palette; mode = saved.mode; } } catch {}
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M17.txt b/agents/darkwing/work/queue-53-review/r1/mut/M17.txt
new file mode 100644
index 00000000..7950833d
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M17.txt
@@ -0,0 +1,48 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (6509.180091ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6694.384219ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8448.50645ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (283.095687ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (94.261689ms)
+✔ bus refusals map to statuses and never carry a path or a stack (171.22577ms)
+✔ humanCall speaks the human transport protocol without blocking the server (3166.486182ms)
+✔ busReader takes --business, else the live bus host, else refuses (634.294634ms)
+✔ humanCall kills a transport that runs past its timeout (546.416392ms)
+✔ serve refuses a --business value that is not a business id (277.920278ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5843.479393ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2979.713955ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1525.00909ms)
+✔ conversation view: seats without history say so and offer no reply (1119.901705ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5907.046805ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56798.491522ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5982.963587ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23060.663865ms)
+✔ loopback host and board origin fail closed (9.911459ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (151.827716ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (120.177257ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1888.294464ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.461055ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (3.105203ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.844539ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5599.305116ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3190.605625ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 57257.534522
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (5599.305116ms)
+ Error: Uncaught: TypeError: Cannot read properties of null (reading 'mode')
+ at :1:62
+ at Object.evaluate (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/browser.mjs:44:35)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:117:18)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M18.diff b/agents/darkwing/work/queue-53-review/r1/mut/M18.diff
new file mode 100644
index 00000000..c0d745a2
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M18.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/shell.css b/packages/webui/src/public/shell.css
+index ae98ebd5..618e1126 100644
+--- a/packages/webui/src/public/shell.css
++++ b/packages/webui/src/public/shell.css
+@@ -97,7 +97,7 @@ table.s1-table td code{font-size:12.5px;white-space:nowrap}
+ .skel{display:block;height:12px;border-radius:4px;background:var(--raised);animation:skel 1.4s ease-in-out infinite}
+ .skel:nth-child(odd){width:82%}
+ @keyframes skel{50%{opacity:.45}}
+-body.board-refused #board-view{display:none}
++
+ body.on-bus #board-refused{display:none}
+
+ /* Toast: one line, polite, bottom centre. */
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M18.txt b/agents/darkwing/work/queue-53-review/r1/mut/M18.txt
new file mode 100644
index 00000000..2135035f
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M18.txt
@@ -0,0 +1,56 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4795.15073ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5559.593964ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7776.997828ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (1077.378774ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (172.941475ms)
+✔ bus refusals map to statuses and never carry a path or a stack (171.347229ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2180.586418ms)
+✔ busReader takes --business, else the live bus host, else refuses (290.631709ms)
+✔ humanCall kills a transport that runs past its timeout (528.862733ms)
+✔ serve refuses a --business value that is not a business id (172.199777ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5528.326861ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3194.267668ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1843.504674ms)
+✔ conversation view: seats without history say so and offer no reply (1433.153552ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (6538.626521ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55681.83814ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6466.894866ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22981.556096ms)
+✔ loopback host and board origin fail closed (10.31224ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (151.493703ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (131.02258ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1643.650438ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.118919ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.164409ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.524389ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4961.827843ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3334.087324ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 56099.695862
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4961.827843ms)
+ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+
+ 'block' !== 'none'
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:142:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: 'block',
+ expected: 'none',
+ operator: 'strictEqual',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M19.diff b/agents/darkwing/work/queue-53-review/r1/mut/M19.diff
new file mode 100644
index 00000000..daa7e539
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M19.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
+index f5389ee6..c40651fd 100644
+--- a/packages/webui/src/public/bus.js
++++ b/packages/webui/src/public/bus.js
+@@ -430,7 +430,7 @@
+ try { html = await view(live, path, new URLSearchParams(query)); readAt = live.oldest(); }
+ catch (err) {
+ const kept = reader(false);
+- try { if (refusal(err)) throw err; html = await view(kept, path, new URLSearchParams(query)); readAt = kept.oldest(); html = staleBanner(err) + html; state = 'stale'; }
++ try { html = await view(kept, path, new URLSearchParams(query)); readAt = kept.oldest(); html = staleBanner(err) + html; state = 'stale'; }
+ catch { html = failedView(err); state = 'failed'; }
+ }
+ if (g !== gen) return;
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M19.txt b/agents/darkwing/work/queue-53-review/r1/mut/M19.txt
new file mode 100644
index 00000000..30164f8d
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M19.txt
@@ -0,0 +1,56 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5189.150978ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4797.468611ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7333.317174ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (293.313629ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (270.398019ms)
+✔ bus refusals map to statuses and never carry a path or a stack (46.997252ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2498.469401ms)
+✔ busReader takes --business, else the live bus host, else refuses (561.937736ms)
+✔ humanCall kills a transport that runs past its timeout (529.448403ms)
+✔ serve refuses a --business value that is not a business id (158.123778ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5165.831607ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2318.690956ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1214.295855ms)
+✔ conversation view: seats without history say so and offer no reply (858.950234ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5772.38394ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56013.500976ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5767.671969ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22044.47108ms)
+✔ loopback host and board origin fail closed (8.098491ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (116.266396ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (149.164044ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1526.468607ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.016667ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.453188ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.576672ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (10536.386855ms)
+✖ five states on Board, Inbox, Tasks, Agents and Trail (6210.0518ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 25
+ℹ fail 2
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 56442.086324
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (10536.386855ms)
+ Error: Uncaught (in promise) Error: Condition timed out: !!document.querySelector("#bus-view .banner.ref"): undefined
+ at Object.evaluate (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/browser.mjs:44:35)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:196:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
+
+test at tests/shell.test.mjs:278:1
+✖ five states on Board, Inbox, Tasks, Agents and Trail (6210.0518ms)
+ Error: Uncaught (in promise) Error: Condition timed out: !!document.querySelector("#bus-view .banner.ref"): undefined
+ at Object.evaluate (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/browser.mjs:44:35)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:337:7)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M20.diff b/agents/darkwing/work/queue-53-review/r1/mut/M20.diff
new file mode 100644
index 00000000..7aecec0d
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M20.diff
@@ -0,0 +1,13 @@
+diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js
+index 1bd88cf2..560b6b11 100644
+--- a/packages/webui/src/public/app.js
++++ b/packages/webui/src/public/app.js
+@@ -304,7 +304,7 @@
+ function error(err) {
+ failed = true; $('error').hidden = false;
+ const refused = err.status === 403;
+- $('error').className = refused ? 'banner ref' : 'banner err';
++ $('error').className = 'banner err';
+ $('board-refused').hidden = !refused; document.body.classList.toggle('board-refused', refused);
+ $('error').innerHTML = refused
+ ? `
The board refused the read. refused: ${esc(err.message)} Board: ${esc(board)}. Console shows nothing rather than a guess. Use Refresh to try again.
`
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/M20.txt b/agents/darkwing/work/queue-53-review/r1/mut/M20.txt
new file mode 100644
index 00000000..0948dafd
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/M20.txt
@@ -0,0 +1,59 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4106.705441ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4897.321923ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7067.560106ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (240.258586ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (133.598704ms)
+✔ bus refusals map to statuses and never carry a path or a stack (67.321441ms)
+✔ humanCall speaks the human transport protocol without blocking the server (3115.331024ms)
+✔ busReader takes --business, else the live bus host, else refuses (181.812826ms)
+✔ humanCall kills a transport that runs past its timeout (527.655765ms)
+✔ serve refuses a --business value that is not a business id (166.522998ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4231.728036ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2973.78925ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1229.737715ms)
+✔ conversation view: seats without history say so and offer no reply (730.936985ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4274.78806ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55233.84178ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4670.272359ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22574.934461ms)
+✔ loopback host and board origin fail closed (7.615952ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (131.841633ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (99.940777ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1879.694356ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.434754ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.048983ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (1.308296ms)
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4582.403832ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3147.731873ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 26
+ℹ fail 1
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 55736.314772
+
+✖ failing tests:
+
+test at tests/shell.test.mjs:84:1
+✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4582.403832ms)
+ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ + actual - expected
+
+ + 'banner err'
+ - 'banner ref'
+ ^
+
+ at TestContext. (file:///home/jwoltje/darkwing-scratch/r53a/mutwt/packages/webui/tests/shell.test.mjs:140:12)
+ at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
+ at async Test.run (node:internal/test_runner/test:1409:7)
+ at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
+ generatedMessage: true,
+ code: 'ERR_ASSERTION',
+ actual: 'banner err',
+ expected: 'banner ref',
+ operator: 'strictEqual',
+ diff: 'simple'
+ }
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/manifest-after.txt b/agents/darkwing/work/queue-53-review/r1/mut/manifest-after.txt
new file mode 100644
index 00000000..5f69a82a
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/manifest-after.txt
@@ -0,0 +1,16 @@
+packages/webui/README.md: OK
+packages/webui/src/public/app.js: OK
+packages/webui/src/public/assets/fonts/jetbrains-mono-400.woff2: OK
+packages/webui/src/public/assets/fonts/jetbrains-mono-500.woff2: OK
+packages/webui/src/public/assets/fonts/jetbrains-mono-700.woff2: OK
+packages/webui/src/public/assets/fonts/jetbrains-mono-OFL.txt: OK
+packages/webui/src/public/assets/fonts/jetbrains-mono-sources.txt: OK
+packages/webui/src/public/bus.js: OK
+packages/webui/src/public/icons.svg: OK
+packages/webui/src/public/index.html: OK
+packages/webui/src/public/shell.css: OK
+packages/webui/src/public/tokens.css: OK
+packages/webui/src/serve.mjs: OK
+packages/webui/tests/browser.mjs: OK
+packages/webui/tests/serve.test.mjs: OK
+packages/webui/tests/shell.test.mjs: OK
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/mutate.py b/agents/darkwing/work/queue-53-review/r1/mut/mutate.py
new file mode 100644
index 00000000..28c7f210
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/mutate.py
@@ -0,0 +1,31 @@
+# mutate.py : apply one named mutant to the candidate (exact text, must match once). Run from the tree root.
+import sys
+B, A, C, S, H = "packages/webui/src/public/bus.js", "packages/webui/src/public/app.js", "packages/webui/src/public/shell.css", "packages/webui/src/serve.mjs", "packages/webui/src/public/index.html"
+M = {
+ "M01": [(B, "err.status === 403 || ['not-configured', 'no-bus-host'].includes(err.code);", "err.status === 403;")],
+ "M02": [(A, "const refused = err.status === 403;", "const refused = false;")],
+ "M03": [(A, "document.body.classList.toggle('board-refused', refused);", "")],
+ "M04": [(B, "refused: ${txt(err.code)}. ", "refused: ${txt(err.code)}. ")],
+ "M05": [(B, "${state === 'stale' ? ' · stale: the last read failed' : ''}", "")],
+ "M06": [(A, "if (mode === 'system') delete document.documentElement.dataset.mode; else document.documentElement.dataset.mode = mode;", "document.documentElement.dataset.mode = mode;")],
+ "M07": [(B, "t.innerHTML = `${esc(text)}", "t.innerHTML = `${text}")],
+ "M08": [(B, "${txt(i.label)}", "${i.label}")],
+ "M09": [(C, ":focus-visible{outline:2px solid var(--focus);outline-offset:2px}", ":focus-visible{outline:2px solid var(--focus);outline-offset:0}")],
+ "M10": [(C, ":focus-visible{outline:2px solid var(--focus);outline-offset:2px}", ":focus-visible{outline:1px solid var(--focus);outline-offset:2px}")],
+ "M11": [(C, " .s1-sections{display:flex;flex-wrap:wrap;overflow-x:visible;flex-basis:100%;gap:2px;padding-bottom:2px}", " .s1-sections{display:flex;flex-basis:100%;gap:2px;padding-bottom:2px}")],
+ "M12": [(B, "", "")],
+ "M13": [(A, " $('board-refused').hidden = true; document.body.classList.remove('board-refused');\n", "")],
+ "M14": [(B, "links[i + (e.key === 'ArrowDown' ? 1 : -1)]?.focus();", "links[i + (e.key === 'ArrowDown' ? -1 : 1)]?.focus();")],
+ "M15": [(S, "['/icons.svg', ['icons.svg', 'image/svg+xml']],", "['/icons.svg', ['icons.svg', 'text/plain']],")],
+ "M16": [(C, ".count,td,.s1-twhen,time,.fresh,.kv dd{font-variant-numeric:tabular-nums}", "")],
+ "M17": [(A, "try { localStorage.setItem('mosaic-console-appearance',", "try { localStorage.setItem('mosaic-console-look',")],
+ "M18": [(C, "body.board-refused #board-view{display:none}", "")],
+ "M19": [(B, "if (refusal(err)) throw err; html = await view(kept,", "html = await view(kept,")],
+ "M20": [(A, "$('error').className = refused ? 'banner ref' : 'banner err';", "$('error').className = 'banner err';")],
+}
+for f, old, new in M[sys.argv[1]]:
+ s = open(f).read()
+ n = s.count(old)
+ if n != 1: sys.exit(f"{sys.argv[1]}: {n} matches in {f}")
+ open(f, "w").write(s.replace(old, new))
+print(sys.argv[1], "applied")
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/run.sh b/agents/darkwing/work/queue-53-review/r1/mut/run.sh
new file mode 100755
index 00000000..088fee6e
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/run.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Each mutant against the packages/webui suite in a candidate worktree, then restores from the index.
+export TMPDIR=~/darkwing-scratch/r53a/tmp
+S=~/darkwing-scratch/r53a; M=$S/mut; W=$S/mutwt
+: > $M/summary.txt
+echo "start $(date -u +%FT%TZ)" >> $M/summary.txt
+for v in $(python3 -c 'import re;print(" ".join(sorted(set(re.findall(r"\"(M\d\d)\"", open("'$M'/mutate.py").read())))))'); do
+ (cd $W && git checkout -q -- packages/webui && python3 $M/mutate.py $v > /dev/null && git diff > $M/$v.diff) || { echo "$v APPLY-FAILED" >> $M/summary.txt; continue; }
+ (cd $W/packages/webui && env -u NODE_TEST_CONTEXT node --test 'tests/*.test.mjs' > $M/$v.txt 2>&1); e=$?
+ r=killed; [ $e = 0 ] && r=SURVIVED
+ echo "$v $r exit=$e $(grep -E '^ℹ (pass|fail)' $M/$v.txt | tr '\n' ' ')" >> $M/summary.txt
+done
+(cd $W && git checkout -q -- packages/webui && sha256sum -c $S/pkt/candidate-manifest.sha256) > $M/manifest-after.txt 2>&1
+echo "end $(date -u +%FT%TZ)" >> $M/summary.txt
+echo DONE >> $M/summary.txt
diff --git a/agents/darkwing/work/queue-53-review/r1/mut/summary.txt b/agents/darkwing/work/queue-53-review/r1/mut/summary.txt
new file mode 100644
index 00000000..c3906c72
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/mut/summary.txt
@@ -0,0 +1,23 @@
+start 2026-10-10T17:37:26Z
+M01 SURVIVED exit=0 ℹ pass 27 ℹ fail 0
+M02 killed exit=1 ℹ pass 26 ℹ fail 1
+M03 killed exit=1 ℹ pass 26 ℹ fail 1
+M04 SURVIVED exit=0 ℹ pass 27 ℹ fail 0
+M05 killed exit=1 ℹ pass 25 ℹ fail 2
+M06 killed exit=1 ℹ pass 26 ℹ fail 1
+M07 SURVIVED exit=0 ℹ pass 27 ℹ fail 0
+M08 SURVIVED exit=0 ℹ pass 27 ℹ fail 0
+M09 SURVIVED exit=0 ℹ pass 27 ℹ fail 0
+M10 killed exit=1 ℹ pass 26 ℹ fail 1
+M11 SURVIVED exit=0 ℹ pass 27 ℹ fail 0
+M12 killed exit=1 ℹ pass 26 ℹ fail 1
+M13 killed exit=1 ℹ pass 26 ℹ fail 1
+M14 killed exit=1 ℹ pass 26 ℹ fail 1
+M15 killed exit=1 ℹ pass 26 ℹ fail 1
+M16 SURVIVED exit=0 ℹ pass 27 ℹ fail 0
+M17 killed exit=1 ℹ pass 26 ℹ fail 1
+M18 killed exit=1 ℹ pass 26 ℹ fail 1
+M19 killed exit=1 ℹ pass 25 ℹ fail 2
+M20 killed exit=1 ℹ pass 26 ℹ fail 1
+end 2026-10-10T17:56:15Z
+DONE
diff --git a/agents/darkwing/work/queue-53-review/r1/out/build-tokens.txt b/agents/darkwing/work/queue-53-review/r1/out/build-tokens.txt
new file mode 100644
index 00000000..20cb200f
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/build-tokens.txt
@@ -0,0 +1 @@
+tokens.css is current
diff --git a/agents/darkwing/work/queue-53-review/r1/out/node-webui.txt b/agents/darkwing/work/queue-53-review/r1/out/node-webui.txt
new file mode 100644
index 00000000..90653f84
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/node-webui.txt
@@ -0,0 +1,36 @@
+✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3254.037973ms)
+Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286}
+✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4707.01393ms)
+✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6741.095235ms)
+✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (341.416961ms)
+✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (180.268473ms)
+✔ bus refusals map to statuses and never carry a path or a stack (112.024139ms)
+✔ humanCall speaks the human transport protocol without blocking the server (2572.17701ms)
+✔ busReader takes --business, else the live bus host, else refuses (222.163707ms)
+✔ humanCall kills a transport that runs past its timeout (535.12865ms)
+✔ serve refuses a --business value that is not a business id (197.661373ms)
+✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3213.259707ms)
+✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3818.250352ms)
+✔ conversation view: a newer session with no readable history keeps the marker (1561.547729ms)
+✔ conversation view: seats without history say so and offer no reply (1241.12093ms)
+✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5596.096268ms)
+✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55064.519411ms)
+✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4872.400872ms)
+✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23577.983738ms)
+✔ loopback host and board origin fail closed (9.569663ms)
+✔ real board fixture passes through WebUI; assets and isolated seen/reply work (138.151914ms)
+✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (103.234277ms)
+✔ unreachable board reports URL; CLI rejects unsupported options (1667.864763ms)
+✔ tokens.css and icons.svg are byte copies of docs/design (1.458809ms)
+✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.787806ms)
+✔ shipped strings are unchanged, and the web keeps its write boundary (2.003515ms)
+✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4887.914731ms)
+✔ five states on Board, Inbox, Tasks, Agents and Trail (3288.045605ms)
+ℹ tests 27
+ℹ suites 0
+ℹ pass 27
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 55485.658358
diff --git a/agents/darkwing/work/queue-53-review/r1/out/summary.txt b/agents/darkwing/work/queue-53-review/r1/out/summary.txt
new file mode 100644
index 00000000..c6c364a0
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/summary.txt
@@ -0,0 +1,14 @@
+start 2026-10-10T17:31:49Z
+node-webui exit=0 ℹ pass 27 ℹ fail 0
+build-tokens --check exit=0 tokens.css is current
+test-auth exit=0 selftest: 15 passed, 0 failed
+test-conductor exit=0 selftest: 17 passed, 0 failed
+test-config exit=0 selftest: 24 passed, 0 failed
+test-discord exit=0 discord suite: 66 passed, 0 failed
+test-extension-package exit=0 extension package selftest: 18 passed, 0 failed
+test-foundation exit=0 selftest: 44 passed, 0 failed
+test-queue exit=0 queue suite: 27 passed, 0 failed
+test-release exit=0 selftest: 4 passed, 0 failed
+test-task exit=0 selftest: 26 passed, 0 failed
+end 2026-10-10T17:34:30Z
+DONE
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-auth.txt b/agents/darkwing/work/queue-53-review/r1/out/test-auth.txt
new file mode 100644
index 00000000..ac228760
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-auth.txt
@@ -0,0 +1,17 @@
+OK status with missing harness credential exits 3 and still lists accounts
+OK status reports harness credential (read-only) + mosaic accounts
+OK api key material never reaches output
+OK oauth token material never reaches output
+OK unparseable credential file exits 2
+OK symlinked credential file exits 4
+OK env-side credential names reported
+OK env var values never reach output
+OK accounts without an accounts dir reports none and creates nothing
+OK accounts lists files and marks the active one
+OK loose account perms flagged in listing
+OK agent --auth with missing account file refuses (exit 4)
+OK agent --auth with non-0600 account file refuses
+OK agent --auth with invalid account name refuses
+OK auth.sh without valid config refuses
+
+selftest: 15 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-conductor.txt b/agents/darkwing/work/queue-53-review/r1/out/test-conductor.txt
new file mode 100644
index 00000000..7844af23
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-conductor.txt
@@ -0,0 +1,55 @@
+Note: switching to '8a7871ff00f35f943054f5beb68b19f31ed1a3bd'.
+
+You are in 'detached HEAD' state. You can look around, make experimental
+changes and commit them, and you can discard any commits you make in this
+state without impacting any branches by switching back to a branch.
+
+If you want to create a new branch to retain commits you create, you may
+do so (now or later) by using -c with the switch command. Example:
+
+ git switch -c
+
+Or undo this operation with:
+
+ git switch -
+
+Turn off this advice by setting config variable advice.detachedHead to false
+
+Not currently on any branch.
+nothing to commit, working tree clean
+Note: switching to '8a7871ff00f35f943054f5beb68b19f31ed1a3bd'.
+
+You are in 'detached HEAD' state. You can look around, make experimental
+changes and commit them, and you can discard any commits you make in this
+state without impacting any branches by switching back to a branch.
+
+If you want to create a new branch to retain commits you create, you may
+do so (now or later) by using -c with the switch command. Example:
+
+ git switch -c
+
+Or undo this operation with:
+
+ git switch -
+
+Turn off this advice by setting config variable advice.detachedHead to false
+
+OK dry-run: allowed change, exit 0, nothing committed (exit 0)
+OK dry-run committed nothing
+OK apply: allowed change exits 0 (exit 0)
+OK apply: attribution in commit subject
+OK apply: target tree clean after commit
+OK disallowed path refused (exit 1)
+OK disallowed path: target untouched
+OK syntax gate refused broken .mjs (exit 1)
+OK syntax gate: target untouched
+OK suite failure refused (exit 1)
+OK suite failure: target reverted to clean
+OK disabled policy refused (exit 2)
+OK disabled policy: target untouched
+OK failed run refused (exit 1)
+OK failed run: target untouched
+OK missing run exits 4 (exit 4)
+OK invalid policy exits 2 (exit 2)
+
+selftest: 17 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-config.txt b/agents/darkwing/work/queue-53-review/r1/out/test-config.txt
new file mode 100644
index 00000000..76c05ef7
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-config.txt
@@ -0,0 +1,26 @@
+OK absent adapter defaults to pi
+OK adapter mock validates (exit 0)
+OK unsupported adapter exits 2 (exit 2)
+OK env exports adapter
+OK bootstrap creates default when absent (exit 0)
+OK bootstrap wrote config file
+OK bootstrap is idempotent on existing config (exit 0)
+OK bootstrap did not rewrite existing config
+OK validate missing config exits 3 (exit 3)
+OK malformed JSON exits 2 (exit 2)
+OK unsupported configVersion exits 2 (exit 2)
+OK unknown top-level key exits 2 (exit 2)
+OK unknown execution key exits 2 (exit 2)
+OK unsupported backend exits 2 (exit 2)
+OK unsupported environment exits 2 (exit 2)
+OK relative dataRoot exits 2 (exit 2)
+OK non-canonical dataRoot exits 2 (exit 2)
+OK filesystem root dataRoot exits 2 (exit 2)
+OK home directory dataRoot exits 2 (exit 2)
+OK dataRoot containing config dir exits 2 (exit 2)
+OK control character in provider exits 2 (exit 2)
+OK symlinked config file exits 2 (exit 2)
+OK env exports resolve correctly
+OK failed validation modified nothing
+
+selftest: 24 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-discord.txt b/agents/darkwing/work/queue-53-review/r1/out/test-discord.txt
new file mode 100644
index 00000000..b013f9ff
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-discord.txt
@@ -0,0 +1,70 @@
+toolchain: node v26.8.1
+
+OK syntax: packages/discord/src/approvals.mjs
+OK syntax: packages/discord/src/authorize.mjs
+OK syntax: packages/discord/src/binding.mjs
+OK syntax: packages/discord/src/cli.mjs
+OK syntax: packages/discord/src/connector.mjs
+OK syntax: packages/discord/src/context.mjs
+OK syntax: packages/discord/src/engine-pi.mjs
+OK syntax: packages/discord/src/errors.mjs
+OK syntax: packages/discord/src/gateway.mjs
+OK syntax: packages/discord/src/git.mjs
+OK syntax: packages/discord/src/journal.mjs
+OK syntax: packages/discord/src/notify.mjs
+OK syntax: packages/discord/src/rest.mjs
+OK syntax: packages/discord/src/setspark.mjs
+OK syntax: packages/discord/src/tools.mjs
+OK syntax: packages/discord/src/web.mjs
+OK syntax: packages/discord/bin/git-credential.mjs
+OK syntax: packages/discord/extension/tools.mjs
+OK syntax: packages/discord/tests/approvals.test.mjs
+OK syntax: packages/discord/tests/authorize.test.mjs
+OK syntax: packages/discord/tests/binding.test.mjs
+OK syntax: packages/discord/tests/connector.test.mjs
+OK syntax: packages/discord/tests/context.test.mjs
+OK syntax: packages/discord/tests/engine.test.mjs
+OK syntax: packages/discord/tests/fake-pi.mjs
+OK syntax: packages/discord/tests/gateway.test.mjs
+OK syntax: packages/discord/tests/git.test.mjs
+OK syntax: packages/discord/tests/helpers.mjs
+OK syntax: packages/discord/tests/journal.test.mjs
+OK syntax: packages/discord/tests/notify.test.mjs
+OK syntax: packages/discord/tests/recover.test.mjs
+OK syntax: packages/discord/tests/rest.test.mjs
+OK syntax: packages/discord/tests/setspark.test.mjs
+OK syntax: packages/discord/tests/tools.test.mjs
+OK syntax: packages/discord/tests/web.test.mjs
+OK syntax: packages/discord/fixtures/claim-worker.mjs
+OK syntax: packages/discord/fixtures/legacy-owner-worker.mjs
+OK syntax: scripts/discord.sh
+OK syntax: scripts/discord-service.sh
+OK packages/discord declares no dependencies
+OK no bot-token-shaped string in packages/discord
+OK fixture binding uses placeholder ids only
+OK fixture binding validates
+OK real pi with the extension exposes exactly list_dir, read_file, search and no built-in tool
+OK real pi with a writable root exposes exactly the three reads plus write_file and edit_file, and writes nothing at start
+OK real pi with a web key exposes the three reads plus web_fetch and web_search, and no write tool without a writable root
+OK real pi with a git root exposes the reads, writes and the four git verbs, commits nothing at start, and never shows the token
+OK real pi with protocol vault adds reserve_id to the git verbs
+OK real pi with a setspark key exposes the reads and the eight record verbs, no counters, and never shows the key
+OK real pi refuses a git key on a read-only root (fail closed)
+OK real pi with the pilot flags (--no-tools) exposes no tool at all
+OK real pi exits non-zero without MOSAIC_DISCORD_TOOLS: no session, no tools (fail closed)
+OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
+OK node --test packages/discord/tests/ (ℹ pass 178)
+OK scripts/discord.sh --help exits 0
+OK scripts/discord.sh check without a binding exits 4
+OK scripts/discord.sh recover without a binding exits 4
+OK scripts/discord.sh reload without a binding exits 4
+OK scripts/discord-service.sh without a command exits 4
+OK service unit renders with the repository path, a supervised run as the main process, exit 3 never retried, and reload as SIGHUP
+OK service install writes the rendered unit (0644) and leaves no temp file
+OK service install a second time reports unchanged
+OK systemd-analyze verify accepts the rendered unit
+OK service uninstall removes the unit file
+OK service install with an unknown flag exits 4
+OK service install with USER unset finishes and names the account for lingering
+
+discord suite: 66 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-extension-package.txt b/agents/darkwing/work/queue-53-review/r1/out/test-extension-package.txt
new file mode 100644
index 00000000..a194a25e
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-extension-package.txt
@@ -0,0 +1,21 @@
+OK initial ordinary-file install
+OK installed tree matches canonical source
+OK installed tree has no symlinks
+OK check detects installation drift
+OK sync refuses to overwrite installation drift
+OK check detects an extra destination file
+OK check detects an extra destination directory
+OK check rejects a destination symlink
+OK sync accepts a canonical source update
+OK updated installation matches canonical source
+scripts/test-extension-package.sh: line 14: 1734733 Killed "$@" > /dev/null 2>&1
+OK forced interruption kills the replacing process
+OK next invocation recovers old consistent installation
+OK interrupted replacement rolled back
+OK sync succeeds after interruption recovery
+OK unlocked stale lock file does not block
+OK active lock refuses a concurrent sync
+OK source symlink fails closed
+OK nested second entrypoint fails closed
+
+extension package selftest: 18 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-foundation.txt b/agents/darkwing/work/queue-53-review/r1/out/test-foundation.txt
new file mode 100644
index 00000000..6338e1e6
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-foundation.txt
@@ -0,0 +1,53 @@
+toolchain: node v26.8.1, python 3.12.8, jsonschema 4.26.0
+
+OK syntax: scripts/foundation-inspect.mjs
+OK syntax: scripts/foundation/strict-json.mjs
+OK syntax: scripts/foundation/canonical.mjs
+OK syntax: scripts/foundation/resolve.mjs
+OK syntax: scripts/foundation/validate-record.mjs
+OK syntax: scripts/foundation/fixtures/build-fixtures.mjs
+OK syntax: scripts/foundation/canonical.test.mjs
+OK syntax: scripts/foundation/cli.test.mjs
+OK syntax: scripts/foundation/fixtures.test.mjs
+OK syntax: scripts/foundation/resolve.test.mjs
+OK syntax: scripts/foundation/strict-json.test.mjs
+OK syntax: scripts/foundation/verify-schema.py (ast only; no bytecode written)
+OK fixture generator runs
+OK checked-in fixtures/bundles equal a fresh generation
+OK checked-in fixtures/raw equal a fresh generation
+OK checked-in fixtures/index.json equal a fresh generation
+OK checked-in demo bundles equal a fresh generation
+OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT
+OK node --test scripts/foundation/ (ℹ pass 80)
+OK differential schema oracle: PASS: differential schema oracle (finite corpus; compatibility evidence, not equivalence proof)
+ platform witness: strftime('%Y') for year 999 -> '999' (pinned checker refuses years 0001..0999)
+ node v26.8.1; corpus 1568 records (38 pinned fixtures, 478 unique bundle records, 1052 typeCase/mutation/lexical cases)
+ schema column: agree-valid 540, agree-invalid 991, DISAGREEMENTS 0; strict-only (parser-bound) cases: 27; unsupported-kind records not schema-assessed by the inspector: 10
+ profile column (schema-valid records only): profile-valid 510, profile-invalid 30
+ profile refusals asserted: 30 schema-agreed-valid records refused only by the strict typed-string profile (rule profile-pattern-mismatch), 12 declared by name; 73 named probes verified against declared schema/profile columns
+OK oracle: zero schema-column disagreements with the pinned checker
+OK oracle: strict-only profile refusals are counted and asserted
+OK demo: permitted read preview exits 0 (exit 0)
+OK demo: permitted file.change preview exits 0 (exit 0)
+OK demo: assignment.change proposal is unresolved (exit 3) (exit 3)
+OK demo: revoked registration is refused (exit 3) (exit 3)
+OK demo: message is not authority (exit 3) (exit 3)
+OK usage: no arguments exits 2 (exit 2)
+OK io: missing file exits 4 (exit 4)
+OK io: directory exits 4 (exit 4)
+OK io: symlink exits 4 (O_NOFOLLOW) (exit 4)
+OK bound: oversize fixture exits 2 (exit 2)
+OK profile: one final LF in a typed selection id is refused before admission (exit 2) (exit 2)
+OK profile: two final LFs fail the schema pattern itself (exit 2) (exit 2)
+OK profile: escaped newlines in free-form text stay allowed (exit 0) (exit 0)
+OK profile refusal is invalid-request/profile-pattern-mismatch with selection and operation withheld, value not echoed
+OK text output starts with the disclaimer
+OK json output is valid JSON with result allowed and exactly the charter §7 fields
+OK json golden matches byte-for-byte
+OK sandboxed bundle run (env -i, PATH=/nonexistent) produced the unresolved proposal
+OK sandbox inventory (path/type/size/mode/uid/gid/inode/mtime/sha256) unchanged by runs
+OK canary never printed (bundle run and credential-file run)
+OK a non-bundle JSON file is refused at the shape gate, not read into output
+OK no field of the non-bundle file is echoed
+
+selftest: 44 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-queue.txt b/agents/darkwing/work/queue-53-review/r1/out/test-queue.txt
new file mode 100644
index 00000000..df7f4dba
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-queue.txt
@@ -0,0 +1,35 @@
+toolchain: node v26.8.1, git version 2.55.0
+
+OK syntax: packages/queue/src/cli.mjs
+OK syntax: packages/queue/src/errors.mjs
+OK syntax: packages/queue/src/io.mjs
+OK syntax: packages/queue/src/lock.mjs
+OK syntax: packages/queue/src/queue.mjs
+OK syntax: packages/queue/src/review.mjs
+OK syntax: packages/queue/src/store.mjs
+OK syntax: packages/queue/tests/commit.test.mjs
+OK syntax: packages/queue/tests/data.test.mjs
+OK syntax: packages/queue/tests/dispatch.test.mjs
+OK syntax: packages/queue/tests/helpers.mjs
+OK syntax: packages/queue/tests/lock.test.mjs
+OK syntax: packages/queue/tests/migration.test.mjs
+OK syntax: packages/queue/tests/review.test.mjs
+OK syntax: packages/queue/tests/store.test.mjs
+OK syntax: packages/queue/tests/write.test.mjs
+OK syntax: packages/queue/tests/fixtures/fake-gitea.mjs
+OK syntax: packages/queue/tests/fixtures/kill-at.mjs
+OK syntax: packages/queue/tests/fixtures/lock-child.mjs
+OK syntax: packages/queue/tests/fixtures/mosaic-pre-a2.sh
+OK syntax: scripts/queue-commit.sh
+OK syntax: scripts/git-hooks/pre-commit
+OK syntax: scripts/mosaic
+OK queue-commit.sh, the guard and scripts/mosaic are executable
+OK packages/queue declares no dependencies
+ℹ tests 148
+ℹ pass 148
+ℹ fail 0
+OK node --test packages/queue/tests/
+OK scripts/mosaic queue help
+skip queue verify and render --check: this checkout (/home/jwoltje/darkwing-scratch/r53a/cand) is not the queue's canonical root (/mnt/storage/src/mosaic-stack)
+
+queue suite: 27 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-release-docker.txt b/agents/darkwing/work/queue-53-review/r1/out/test-release-docker.txt
new file mode 100644
index 00000000..64eb41d9
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-release-docker.txt
@@ -0,0 +1,18 @@
+start 2026-10-10T17:56:30Z
+OK valid RELEASE resolves (exit 0)
+OK invalid RELEASE exits 1 (exit 1)
+OK missing RELEASE exits 1 (exit 1)
+OK valid RELEASE leaves image tag consistent with version
+OK status safe on empty state (exit 0)
+OK status created no pointer
+OK fault-injected activation refuses (exit 1)
+OK refused activation wrote no pointer
+OK refusal logged exactly once with valid fields
+OK healthy activation succeeds (exit 0)
+OK pointer written with valid fields
+OK repeat activation succeeds (log grows) (exit 0)
+OK log is append-only across activations
+OK rollback without previous refuses (exit 1)
+
+selftest: 14 passed, 0 failed
+rc=0 end 2026-10-10T17:56:43Z
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-release.txt b/agents/darkwing/work/queue-53-review/r1/out/test-release.txt
new file mode 100644
index 00000000..1d6ed050
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-release.txt
@@ -0,0 +1,7 @@
+OK valid RELEASE resolves (exit 0)
+OK invalid RELEASE exits 1 (exit 1)
+OK missing RELEASE exits 1 (exit 1)
+OK valid RELEASE leaves image tag consistent with version
+skip state-machine cases (docker daemon unavailable)
+
+selftest: 4 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/out/test-task.txt b/agents/darkwing/work/queue-53-review/r1/out/test-task.txt
new file mode 100644
index 00000000..cd89fe9b
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/out/test-task.txt
@@ -0,0 +1,32 @@
+OK valid task validates (exit 0)
+OK unknown task key exits 2 (exit 2)
+OK unsupported taskVersion exits 2 (exit 2)
+OK invalid task id exits 2 (exit 2)
+OK empty prompt exits 2 (exit 2)
+OK NUL in expectExact exits 2 (exit 2)
+OK out-of-range timeout exits 2 (exit 2)
+OK missing mission file exits 4 (exit 4)
+OK task with valid mission validates (exit 0)
+OK invalid mission exits 2 (exit 2)
+OK validate missing task exits 4 (exit 4)
+OK validation does not modify the task file
+OK prune dry-run exits 0 (exit 0)
+OK dry-run deleted nothing
+OK prune --keep=2 --yes removes oldest (exit 0)
+OK kept exactly 2 newest runs
+OK newest run kept, oldest pruned
+OK append-only receipt written (3 entries)
+OK sessions/workspaces untouched by prune
+OK prune with invalid keep exits 4 (exit 4)
+skip adapter seam cases (docker daemon unavailable)
+skip workspace/capability cases (docker daemon unavailable)
+skip live task cases (docker unavailable)
+OK onboard without name exits 4 (non-interactive) (exit 4)
+OK onboard --name renders profile (exit 0)
+OK profile written
+OK canon structure: required filled, optional placeholdered
+OK canon sections present
+skip live recall pair: user recall run, recalled user name (docker daemon unavailable)
+OK no agent identity on headless run
+
+selftest: 26 passed, 0 failed
diff --git a/agents/darkwing/work/queue-53-review/r1/probes/probe.test.mjs b/agents/darkwing/work/queue-53-review/r1/probes/probe.test.mjs
new file mode 100644
index 00000000..5c563d13
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/probes/probe.test.mjs
@@ -0,0 +1,74 @@
+// Darkwing row 53 probes: does kept data show anywhere while the board or the bus refuses?
+// Run from a worktree's packages/webui: node --test with WT set to that worktree.
+import { test } from 'node:test';
+import assert from 'node:assert/strict';
+import { createServer } from 'node:http';
+import { pathToFileURL } from 'node:url';
+const WT = process.env.WT;
+const u = p => pathToFileURL(`${WT}/packages/webui/${p}`).href;
+const { browser } = await import(u('tests/browser.mjs'));
+const { close } = await import(u('tests/fixture.mjs'));
+const { startServer } = await import(u('src/serve.mjs'));
+const { BusReadError } = await import(u('src/bus.mjs'));
+const out = [];
+const note = (k, v) => { out.push(`${k}: ${JSON.stringify(v)}`); };
+
+test('probes', { timeout: 120000 }, async () => {
+ let reply = null;
+ const one = { agent: 'agent1', project: 'secretproj', state: 'waiting', waitingOnYou: true, task: 'Kept fixture task', lastActivity: '2026-10-10T00:00:00Z', lastAssistantText: 'Input needed: kept text', registered: null };
+ const ok = () => { reply = { status: 200, body: { sessions: [one, { ...one, agent: 'agent2', state: 'working', waitingOnYou: false }], counts: { waiting: 1, working: 1 }, generatedAt: new Date().toISOString() } }; };
+ ok();
+ const brd = createServer(async (req, res) => { for await (const c of req) void c; res.writeHead(reply.status, { 'content-type': 'application/json' }); res.end(JSON.stringify(reply.body)); });
+ await new Promise(r => brd.listen(0, '127.0.0.1', r));
+ const rows = { inbox: [{ id: 'd'.repeat(32), question: 'Kept question?', class: 'gated', action: 'git.push.protected', blocking: true, options: [{ key: 'yes', text: 'Yes' }], at: new Date().toISOString(), raised_by: 'coder' }], tasks: [{ task_ref: 'vikunja:32/7', fields: { title: 'Kept task title', bucket: 2, done: false, assignees: [] }, source: 'self' }], agents: [], trail: [] };
+ let fail = null;
+ const verb = n => async () => { if (fail) throw new BusReadError(fail, `fixture ${fail}`); return structuredClone(rows[n]); };
+ const web = await startServer({ port: 0, board: `http://127.0.0.1:${brd.address().port}`, bus: { inbox: verb('inbox'), tasks: verb('tasks'), agents: verb('agents'), trail: verb('trail') } });
+ const base = `http://127.0.0.1:${web.address().port}/`, b = await browser();
+ const wait = expr => b.evaluate(`(async()=>{for(let i=0;i<100;i++){if(${expr})return true;await new Promise(r=>setTimeout(r,50))}throw new Error('timed out: '+${JSON.stringify(expr)})})()`);
+ const vis = sel => b.evaluate(`(()=>{const e=document.querySelector(${JSON.stringify(sel)});if(!e)return null;return {shown:!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)&&!e.closest('[hidden]'),text:e.innerText.slice(0,200)}})()`);
+ const refresh = async () => { await b.evaluate('document.querySelector("#refresh").click()'); await wait('!document.querySelector("#refresh").disabled'); };
+ try {
+ await b.viewport(1440, 900);
+ await b.navigate(base); await wait('document.querySelectorAll("table.sessions tbody tr").length===2');
+ // P1/P2: open the inspector on agent1, then the board refuses.
+ await b.evaluate('document.querySelector("table.sessions [data-open]").click()');
+ await wait('document.querySelector("#inspector-title")?.textContent==="agent1"');
+ reply = { status: 403, body: { error: 'non-local Host refused' } };
+ await refresh();
+ await wait('document.querySelector("#error").className==="banner ref"');
+ note('P1 board refused: board-view display', await b.evaluate('getComputedStyle(document.querySelector("#board-view")).display'));
+ note('P1 board refused: inspector', await vis('#inspector'));
+ note('P2 board refused: projects tree', await vis('#projects'));
+ note('P2 board refused: footer', await vis('#footer'));
+ note('P2 board refused: #status', await vis('#status'));
+ // P1b: Escape from the inspector while refused.
+ ok(); await refresh(); await wait('document.querySelector("#error").hidden');
+ // P3/P4: bus pages read once, then the bus refuses.
+ await b.evaluate('location.hash="#/tasks"'); await wait('document.querySelectorAll("#bus-view td.s1-title a").length===1');
+ await b.evaluate('location.hash="#/inbox"'); await wait('!!document.querySelector("#bus-view .s1-dec-open")');
+ fail = 'human-required'; await refresh(); await wait('!!document.querySelector("#bus-view .banner.ref")');
+ note('P4 bus refused: section list', await vis('#sections'));
+ await b.evaluate('document.querySelector("#cmdk").click()'); await wait('document.querySelector("#cmdk-dialog").open');
+ await new Promise(r => setTimeout(r, 500));
+ note('P3 bus refused: palette list', await b.evaluate('[...document.querySelectorAll("#cmdk-list li")].map(l=>l.innerText.replace(/\\n/g," | "))'));
+ await b.key('Escape');
+ // P3b: from the board page while the bus refuses, the Inbox count.
+ await b.evaluate('location.hash="#/"'); await wait('document.querySelectorAll("table.sessions tbody tr").length===2');
+ await new Promise(r => setTimeout(r, 500));
+ note('P4b board page, bus refused: section list', await vis('#sections'));
+ // P6: not-configured on a page read before.
+ fail = 'not-configured'; await b.evaluate('location.hash="#/tasks"'); await wait('!!document.querySelector("#bus-view .banner")');
+ note('P6 not-configured: banner class, task links', await b.evaluate('[document.querySelector("#bus-view .banner").className, document.querySelectorAll("#bus-view td.s1-title a").length]'));
+ // P7: after a refusal, a non-refusal failure: are rows from before the refusal shown as stale?
+ fail = 'outcome-unknown'; await refresh(); await wait('!!document.querySelector("#bus-view .banner")');
+ note('P7 refusal then outcome-unknown: banner class, task links, banner text', await b.evaluate('[document.querySelector("#bus-view .banner").className, document.querySelectorAll("#bus-view td.s1-title a").length, document.querySelector("#bus-view .banner").innerText.slice(0,160)]'));
+ // P8: toast in the accessibility tree before any copy.
+ const ax = await b.call('Accessibility.getFullAXTree', {});
+ note('P8 status/live nodes before any toast', ax.nodes.filter(n => ['status'].includes(n.role?.value)).map(n => n.name?.value ?? ''));
+ note('P8 toast display', await b.evaluate('getComputedStyle(document.querySelector("#toast")).display'));
+ } finally {
+ console.log(out.join('\n'));
+ await b.close(); await close(web); await new Promise(r => brd.close(r));
+ }
+});
diff --git a/agents/darkwing/work/queue-53-review/r1/probes/probes-cand.txt b/agents/darkwing/work/queue-53-review/r1/probes/probes-cand.txt
new file mode 100644
index 00000000..a8671e34
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/r1/probes/probes-cand.txt
@@ -0,0 +1,21 @@
+P1 board refused: board-view display: "none"
+P1 board refused: inspector: {"shown":true,"text":"agent1\nClose\nState\nwaiting\nProject\nsecretproj\nTask\nKept fixture task\nTask source\nunknown\nTask set by\nnot applicable (task is not from a registration)\nActive project\nunknown\nWorkspace\nunknown\nModel\nunk"}
+P2 board refused: projects tree: {"shown":true,"text":"All projects 2\nsecretproj 2"}
+P2 board refused: footer: {"shown":true,"text":"waiting 1 · working 1"}
+P2 board refused: #status: {"shown":true,"text":"Scanned 2026-10-10T17:35:07.220Z · refresh every 10s"}
+P4 bus refused: section list: {"shown":true,"text":"Board\nInbox\n1\n1 BLOCKING\nTasks\nAgents"}
+P3 bus refused: palette list: ["Board | view","Inbox | view","Tasks | view","Agents | view","Kept question? | decision dddddddd","#7 Kept task title | task"]
+P4b board page, bus refused: section list: {"shown":true,"text":"Board\nInbox\n1\n1 BLOCKING\nTasks\nAgents"}
+P6 not-configured: banner class, task links: ["banner ref",0]
+P7 refusal then outcome-unknown: banner class, task links, banner text: ["banner err s1-stale",1,"The last read failed. The bus did not answer in time. (outcome-unknown) This is what was read before, 1 s ago. Nothing was changed.\n\nRead again"]
+P8 status/live nodes before any toast: []
+P8 toast display: "none"
+✔ probes (3409.079539ms)
+ℹ tests 1
+ℹ suites 0
+ℹ pass 1
+ℹ fail 0
+ℹ cancelled 0
+ℹ skipped 0
+ℹ todo 0
+ℹ duration_ms 3480.865928
diff --git a/agents/darkwing/work/queue-53-review/review-r1.md b/agents/darkwing/work/queue-53-review/review-r1.md
new file mode 100644
index 00000000..cb70d94d
--- /dev/null
+++ b/agents/darkwing/work/queue-53-review/review-r1.md
@@ -0,0 +1,204 @@
+# Row 53, console tokens and shell restyle, round 1 review (Darkwing)
+
+Issue #1542, request comment 27138, packet comment 27139, queue revs
+358-359. Base `8a7871ff`. Candidate manifest sha256
+`75569953c1a2cd7b7266208d6e6607290335f1bfe0cf94d96ed224e480a1dda8`, 16
+files under `packages/webui`. The packet manifest and the snapshot I took
+from the checkout both check 16 OK.
+
+Verdict: **request changes**. The restyle itself is good. Tokens and the
+sprite are byte copies, the fonts match the upstream archive, every suite
+is green, and 13 of 20 mutants die on assertions. The problem is the
+refusal state. The packet says a board 403 "fails closed (kept rows
+hidden)" and a bus refusal never shows kept rows. The main table and the
+bus view do that. Five other places still show data read before the
+refusal: the inspector, the project tree, the footer and the scan line on
+the board, and the Inbox count and the Ctrl+K palette on the bus. The
+fix is small and listed under "Required".
+
+## Method
+
+- Detached worktrees at `8a7871ff`: `base`, `cand` and `mutwt`. The last
+ two hold the 16 candidate files, staged, and check 16 OK. `mutwt` still
+ checks 16 OK after the mutant runs (`r1/mut/manifest-after.txt`).
+- `r1/gate.sh`: the `packages/webui` suite, `build-tokens.mjs --check`,
+ then every `scripts/test-*.sh` with `DOCKER_HOST=unix:///nonexistent.sock`,
+ 17:31:49Z to 17:34:30Z.
+- 20 mutants (`r1/mut/mutate.py`, `r1/mut/run.sh`), each against the full
+ webui suite, 17:37:26Z to 17:56:15Z.
+- `test-release` with Docker, finished 17:56:43Z.
+- Font provenance: I downloaded `JetBrainsMono-2.304.zip` from the URL in
+ `jetbrains-mono-sources.txt` into an empty directory and compared hashes
+ (`r1/fonts/check.txt`).
+- Probes in Chromium through the candidate's own `tests/browser.mjs`,
+ with a fake board and fake bus verbs, no tracker request
+ (`r1/probes/probe.test.mjs`, output `r1/probes/probes-cand.txt`).
+- Read through `bus.js`, `app.js`, `index.html`, `shell.css`, `serve.mjs`
+ and `shell.test.mjs` against the brief and `IMPLEMENTING.md`.
+
+Node v26.8.1, `TMPDIR=~/darkwing-scratch/r53a/tmp`.
+
+## Suites
+
+| Suite | Result |
+|---|---|
+| packages/webui (node) | 27/0 |
+| build-tokens --check | rc 0, "tokens.css is current" |
+| test-auth | 15/0 |
+| test-conductor | 17/0 |
+| test-config | 24/0 |
+| test-discord | 66/0 |
+| test-extension-package | 18/0 |
+| test-foundation | 44/0 |
+| test-queue | 27/0 |
+| test-release | 4/0 without Docker, 14/0 with it |
+| test-task, Docker unreachable | 26/0 |
+
+I didn't run test-task with real Docker, because it makes live model
+calls. The candidate changes nothing outside `packages/webui`, and
+Dewey's run gave 98/0.
+
+## Copies and fonts
+
+`tokens.css` and `icons.svg` are byte-equal to `docs/design`. The archive
+hashes to `6f6376c6…7bbf`, the value in the sources file. The Regular,
+Medium and Bold woff2 files and `OFL.txt` from the archive hash the same
+as the shipped files (`a9cb1cd8…`, `086c48df…`, `c503cc5e…`, `30f0c136…`).
+
+## Probes
+
+Fixture: one board with two sessions (project `secretproj`, task
+"Kept fixture task"), one inbox decision ("Kept question?") and one task
+("Kept task title"). Each probe reads once, then makes the read refuse.
+
+| Probe | Candidate |
+|---|---|
+| P1 board 403 with the inspector open | `#board-view` is `display:none`, but the inspector stays open with agent1's state, project `secretproj` and task "Kept fixture task" |
+| P2 board 403 | the project tree shows "All projects 2 / secretproj 2"; the footer shows "waiting 1 · working 1"; `#status` shows "Scanned