From bfbcf626dec3390d71b705cc97b2740677155dff Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 10 Oct 2026 17:10:15 -0500 Subject: [PATCH] review(row54): round 2 packet, approve (darkwing) Comment 27191 on #1543, correction 27192. Candidate afb2ae0e. Co-Authored-By: Claude Opus 5.5 --- .../r2/candidate-manifest.sha256 | 14 ++ .../darkwing/work/queue-54-review/r2/gate.sh | 20 ++ .../work/queue-54-review/r2/mut/D01.diff | 12 ++ .../work/queue-54-review/r2/mut/D01.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D02.diff | 13 ++ .../work/queue-54-review/r2/mut/D02.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D03.diff | 12 ++ .../work/queue-54-review/r2/mut/D03.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D04.diff | 13 ++ .../work/queue-54-review/r2/mut/D04.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D05.diff | 12 ++ .../work/queue-54-review/r2/mut/D05.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D06.diff | 13 ++ .../work/queue-54-review/r2/mut/D06.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D07.diff | 13 ++ .../work/queue-54-review/r2/mut/D07.txt | 130 ++++++++++++ .../work/queue-54-review/r2/mut/D08.diff | 13 ++ .../work/queue-54-review/r2/mut/D08.txt | 112 ++++++++++ .../work/queue-54-review/r2/mut/D09.diff | 13 ++ .../work/queue-54-review/r2/mut/D09.txt | 69 ++++++ .../work/queue-54-review/r2/mut/D10.diff | 13 ++ .../work/queue-54-review/r2/mut/D10.txt | 132 ++++++++++++ .../work/queue-54-review/r2/mut/D11.diff | 13 ++ .../work/queue-54-review/r2/mut/D11.txt | 90 ++++++++ .../work/queue-54-review/r2/mut/D12.diff | 13 ++ .../work/queue-54-review/r2/mut/D12.txt | 70 +++++++ .../work/queue-54-review/r2/mut/D13.diff | 13 ++ .../work/queue-54-review/r2/mut/D13.txt | 89 ++++++++ .../work/queue-54-review/r2/mut/D14.diff | 13 ++ .../work/queue-54-review/r2/mut/D14.txt | 48 +++++ .../work/queue-54-review/r2/mut/D15.diff | 13 ++ .../work/queue-54-review/r2/mut/D15.txt | 89 ++++++++ .../work/queue-54-review/r2/mut/D16.diff | 13 ++ .../work/queue-54-review/r2/mut/D16.txt | 93 +++++++++ .../work/queue-54-review/r2/mut/D17.diff | 13 ++ .../work/queue-54-review/r2/mut/D17.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D18.diff | 13 ++ .../work/queue-54-review/r2/mut/D18.txt | 72 +++++++ .../work/queue-54-review/r2/mut/D19.diff | 13 ++ .../work/queue-54-review/r2/mut/D19.txt | 99 +++++++++ .../work/queue-54-review/r2/mut/D20.diff | 13 ++ .../work/queue-54-review/r2/mut/D20.txt | 77 +++++++ .../work/queue-54-review/r2/mut/D21.diff | 13 ++ .../work/queue-54-review/r2/mut/D21.txt | 54 +++++ .../work/queue-54-review/r2/mut/D22.diff | 13 ++ .../work/queue-54-review/r2/mut/D22.txt | 48 +++++ .../work/queue-54-review/r2/mut/D23.diff | 12 ++ .../work/queue-54-review/r2/mut/D23.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D24.diff | 13 ++ .../work/queue-54-review/r2/mut/D24.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D25.diff | 12 ++ .../work/queue-54-review/r2/mut/D25.txt | 70 +++++++ .../work/queue-54-review/r2/mut/D26.diff | 13 ++ .../work/queue-54-review/r2/mut/D26.txt | 59 ++++++ .../work/queue-54-review/r2/mut/D27.diff | 13 ++ .../work/queue-54-review/r2/mut/D27.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D28.diff | 13 ++ .../work/queue-54-review/r2/mut/D28.txt | 59 ++++++ .../work/queue-54-review/r2/mut/D29.diff | 13 ++ .../work/queue-54-review/r2/mut/D29.txt | 68 ++++++ .../work/queue-54-review/r2/mut/D30.diff | 13 ++ .../work/queue-54-review/r2/mut/D30.txt | 59 ++++++ .../work/queue-54-review/r2/mut/D31.diff | 13 ++ .../work/queue-54-review/r2/mut/D31.txt | 182 ++++++++++++++++ .../work/queue-54-review/r2/mut/E01.diff | 18 ++ .../work/queue-54-review/r2/mut/E01.txt | 94 +++++++++ .../work/queue-54-review/r2/mut/E02.diff | 13 ++ .../work/queue-54-review/r2/mut/E02.txt | 73 +++++++ .../work/queue-54-review/r2/mut/E03.diff | 13 ++ .../work/queue-54-review/r2/mut/E03.txt | 112 ++++++++++ .../work/queue-54-review/r2/mut/E04.diff | 13 ++ .../work/queue-54-review/r2/mut/E04.txt | 97 +++++++++ .../work/queue-54-review/r2/mut/E05.diff | 13 ++ .../work/queue-54-review/r2/mut/E05.txt | 111 ++++++++++ .../work/queue-54-review/r2/mut/E06.diff | 13 ++ .../work/queue-54-review/r2/mut/E06.txt | 71 +++++++ .../work/queue-54-review/r2/mut/E07.diff | 13 ++ .../work/queue-54-review/r2/mut/E07.txt | 90 ++++++++ .../work/queue-54-review/r2/mut/E08.diff | 13 ++ .../work/queue-54-review/r2/mut/E08.txt | 70 +++++++ .../work/queue-54-review/r2/mut/E09.diff | 13 ++ .../work/queue-54-review/r2/mut/E09.txt | 68 ++++++ .../work/queue-54-review/r2/mut/E10.diff | 13 ++ .../work/queue-54-review/r2/mut/E10.txt | 48 +++++ .../work/queue-54-review/r2/mut/E11.diff | 12 ++ .../work/queue-54-review/r2/mut/E11.txt | 73 +++++++ .../work/queue-54-review/r2/mut/E12.diff | 13 ++ .../work/queue-54-review/r2/mut/E12.txt | 48 +++++ .../work/queue-54-review/r2/mut/E13.diff | 13 ++ .../work/queue-54-review/r2/mut/E13.txt | 48 +++++ .../work/queue-54-review/r2/mut/E14.diff | 13 ++ .../work/queue-54-review/r2/mut/E14.txt | 71 +++++++ .../queue-54-review/r2/mut/manifest-after.txt | 14 ++ .../work/queue-54-review/r2/mut/mutate.py | 70 +++++++ .../work/queue-54-review/r2/mut/run.sh | 16 ++ .../work/queue-54-review/r2/mut/sites.sh | 8 + .../work/queue-54-review/r2/mut/summary.txt | 48 +++++ .../queue-54-review/r2/out/build-tokens.txt | 1 + .../queue-54-review/r2/out/node-business.txt | 68 ++++++ .../queue-54-review/r2/out/node-queue.txt | 159 ++++++++++++++ .../queue-54-review/r2/out/node-webui.txt | 48 +++++ .../work/queue-54-review/r2/out/summary.txt | 16 ++ .../work/queue-54-review/r2/out/test-auth.txt | 17 ++ .../queue-54-review/r2/out/test-conductor.txt | 55 +++++ .../queue-54-review/r2/out/test-config.txt | 26 +++ .../queue-54-review/r2/out/test-discord.txt | 70 +++++++ .../r2/out/test-extension-package.txt | 21 ++ .../r2/out/test-foundation.txt | 53 +++++ .../queue-54-review/r2/out/test-queue.txt | 35 ++++ .../r2/out/test-release-docker.txt | 17 ++ .../queue-54-review/r2/out/test-release.txt | 7 + .../work/queue-54-review/r2/out/test-task.txt | 32 +++ .../queue-54-review/r2/probes/e12-check.sh | 10 + .../queue-54-review/r2/probes/e12-check.txt | 10 + .../r2/probes/probe-browser-r2.test.mjs | 97 +++++++++ .../r2/probes/probe-browser-r2.txt | 49 +++++ .../queue-54-review/r2/probes/probe-r2.mjs | 54 +++++ .../queue-54-review/r2/probes/probe-r2.txt | 46 ++++ .../queue-54-review/r2/probes/probe-realq.mjs | 18 ++ .../queue-54-review/r2/probes/probe-realq.txt | 2 + .../work/queue-54-review/review-r2.md | 196 ++++++++++++++++++ 121 files changed, 5404 insertions(+) create mode 100644 agents/darkwing/work/queue-54-review/r2/candidate-manifest.sha256 create mode 100755 agents/darkwing/work/queue-54-review/r2/gate.sh create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D01.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D01.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D02.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D02.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D03.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D03.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D04.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D04.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D05.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D05.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D06.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D06.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D07.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D07.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D08.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D08.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D09.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D09.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D10.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D10.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D11.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D11.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D12.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D12.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D13.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D13.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D14.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D14.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D15.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D15.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D16.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D16.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D17.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D17.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D18.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D18.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D19.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D19.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D20.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D20.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D21.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D21.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D22.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D22.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D23.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D23.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D24.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D24.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D25.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D25.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D26.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D26.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D27.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D27.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D28.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D28.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D29.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D29.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D30.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D30.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D31.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/D31.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E01.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E01.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E02.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E02.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E03.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E03.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E04.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E04.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E05.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E05.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E06.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E06.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E07.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E07.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E08.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E08.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E09.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E09.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E10.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E10.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E11.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E11.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E12.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E12.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E13.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E13.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E14.diff create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/E14.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/manifest-after.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/mutate.py create mode 100755 agents/darkwing/work/queue-54-review/r2/mut/run.sh create mode 100755 agents/darkwing/work/queue-54-review/r2/mut/sites.sh create mode 100644 agents/darkwing/work/queue-54-review/r2/mut/summary.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/build-tokens.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/node-business.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/node-queue.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/node-webui.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/summary.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-auth.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-conductor.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-config.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-discord.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-extension-package.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-foundation.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-queue.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-release-docker.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-release.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/out/test-task.txt create mode 100755 agents/darkwing/work/queue-54-review/r2/probes/e12-check.sh create mode 100644 agents/darkwing/work/queue-54-review/r2/probes/e12-check.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.test.mjs create mode 100644 agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/probes/probe-r2.mjs create mode 100644 agents/darkwing/work/queue-54-review/r2/probes/probe-r2.txt create mode 100644 agents/darkwing/work/queue-54-review/r2/probes/probe-realq.mjs create mode 100644 agents/darkwing/work/queue-54-review/r2/probes/probe-realq.txt create mode 100644 agents/darkwing/work/queue-54-review/review-r2.md diff --git a/agents/darkwing/work/queue-54-review/r2/candidate-manifest.sha256 b/agents/darkwing/work/queue-54-review/r2/candidate-manifest.sha256 new file mode 100644 index 00000000..b305aa63 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/candidate-manifest.sha256 @@ -0,0 +1,14 @@ +3db6ee2a4d4b05de6768709da0c21c6815c0d7899fb9389d659444828264275d packages/queue/README.md +352d96c5cc02d01e5d524c1a9106985c0f0a12b7312d7de157d9bf733dead4d5 packages/queue/src/store.mjs +b44f6f8b07cad4f35dfc92bee2c762845052b2b79f990f7cd5f590efd2b05544 packages/queue/tests/write.test.mjs +c6880e55f5590b9801066e56b9cf3b76be633b60df4141a83d7701dc3d45af73 packages/webui/README.md +07d2c06523dd89f82c9ea14757852b16434f7207df57d7dfcbc58425e6e75c1d packages/webui/src/cli.mjs +5a611e2339fa9e31c489d24460f82852ca2bc892f07265ffdc5eca03b579541b packages/webui/src/public/app.js +a640185c5ca1458135e2297d1fb1059c893a1269b0ff20cfb3044ce297588df2 packages/webui/src/public/bus.js +4f65ab7f6a446b0ffd3c666b1ac1a726fbd5de0814a43b19f566a844e40163b0 packages/webui/src/queue-read.mjs +95767269e5971d66acea98271a028ee6ebc1540dd17849a23bdaaa7ba29b42e8 packages/webui/src/reads.mjs +8121915343ad5000cf66d474d9e4a994ce6c44ff1977822a067ad5ffd2fbbf29 packages/webui/src/serve.mjs +9221692892ac56d7097128bd88dd34b76dc39861a3ff3996eb9eae999751775b packages/webui/tests/reads-fixture.mjs +47a9931cdabfa2e164bd62e5f5ca51fbf05273211e539ef42659926274f946d9 packages/webui/tests/reads.test.mjs +85f3bd247e6f99da717a51d71db13b65d511fffa8f0232ecbafa6c5000430c4e packages/webui/tests/shell.test.mjs +35f437bcafc5ae6bc698581a0d722f6154b092cc633973e492aede0ea29eb8f4 packages/webui/tests/views.test.mjs diff --git a/agents/darkwing/work/queue-54-review/r2/gate.sh b/agents/darkwing/work/queue-54-review/r2/gate.sh new file mode 100755 index 00000000..74778d66 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/gate.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Row 54 gate: the webui, queue and business node suites, build-tokens --check, then every scripts/test-*.sh with Docker unreachable. +export TMPDIR=~/darkwing-scratch/r54b/tmp DOCKER_HOST=unix:///nonexistent.sock +cd ~/darkwing-scratch/r54b/papply +O=~/darkwing-scratch/r54b/r2/out +: > $O/summary.txt +echo "start $(date -u +%FT%TZ)" >> $O/summary.txt +for p in webui queue business; do + (cd packages/$p && env -u NODE_TEST_CONTEXT node --test 'tests/*.test.mjs') > $O/node-$p.txt 2>&1; e=$? + echo "node-$p exit=$e $(grep -E '^ℹ (pass|fail)' $O/node-$p.txt | tr '\n' ' ')" >> $O/summary.txt +done +node docs/design/tools/build-tokens.mjs --check > $O/build-tokens.txt 2>&1; e=$? +echo "build-tokens --check exit=$e $(tail -1 $O/build-tokens.txt)" >> $O/summary.txt +for f in scripts/test-*.sh; do + s=$(basename $f .sh) + $f > $O/$s.txt 2>&1; e=$? + echo "$s exit=$e $(grep -E 'passed, [0-9]+ failed' $O/$s.txt | tail -1)" >> $O/summary.txt +done +echo "end $(date -u +%FT%TZ)" >> $O/summary.txt +echo DONE >> $O/summary.txt diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D01.diff b/agents/darkwing/work/queue-54-review/r2/mut/D01.diff new file mode 100644 index 00000000..8f54933a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D01.diff @@ -0,0 +1,12 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..68928537 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -546,7 +546,6 @@ + } + async function render(navigated) { + // A refresh due while this render reads would replace it: a navigation would lose its heading focus. +- clearTimeout(timer); + const route = routeOf(), [path, query = ''] = route.split('?'), board = path === '/' || path === ''; + const g = ++gen; + document.body.classList.toggle('on-bus', !board); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D01.txt b/agents/darkwing/work/queue-54-review/r2/mut/D01.txt new file mode 100644 index 00000000..7570db68 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D01.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4208.719941ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4999.458945ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6941.091593ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (530.574978ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (357.773039ms) +✔ bus refusals map to statuses and never carry a path or a stack (412.063113ms) +✔ humanCall speaks the human transport protocol without blocking the server (2622.679286ms) +✔ busReader takes --business, else the live bus host, else refuses (124.448417ms) +✔ humanCall kills a transport that runs past its timeout (531.690003ms) +✔ serve refuses a --business value that is not a business id (221.754044ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4181.618291ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2796.913059ms) +✔ conversation view: a newer session with no readable history keeps the marker (1406.282887ms) +✔ conversation view: seats without history say so and offer no reply (1097.638907ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4688.418436ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55535.146252ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.040646ms) +✔ credential state from the date alone, as the bus states it (0.251625ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2904.39286ms) +✔ queue: a refused read fails closed with the store's text, redacted (1237.190389ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2272.179443ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (9.808171ms) +✔ business: missing or invalid file refuses with the module's text, redacted (36.746687ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.358187ms) +✔ settings: release, board, loopback address, notifier binding name only (439.831534ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4708.546566ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23458.004134ms) +✔ loopback host and board origin fail closed (8.268762ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (173.179223ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (353.514404ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2193.975153ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.46213ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.591883ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.502935ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7612.311877ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2752.109147ms) +✖ Queue, Business and Settings in their five states, with no move button (5095.451456ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2541.799195ms) +✔ the server log names no config path when the system config refuses (264.420147ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56093.660829 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (5095.451456ms) + AssertionError [ERR_ASSERTION]: the navigation cleared the due refresh + + 1 !== 0 + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:158:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 1, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D02.diff b/agents/darkwing/work/queue-54-review/r2/mut/D02.diff new file mode 100644 index 00000000..67ec6ecb --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D02.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..dd081855 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -533,7 +533,7 @@ + function keep() { + const a = document.activeElement, view = $('bus-view'); + return { +- href: view.contains(a) ? a.getAttribute('href') : null, copy: view.contains(a) ? a.dataset?.copy : null, retry: view.contains(a) && a.hasAttribute?.('data-retry'), mirror: view.contains(a) ? a.dataset?.mirror : null, h1: view.contains(a) && a.tagName === 'H1', ++ href: view.contains(a) ? a.getAttribute('href') : null, copy: view.contains(a) ? a.dataset?.copy : null, retry: view.contains(a) && a.hasAttribute?.('data-retry'), mirror: view.contains(a) ? a.dataset?.mirror : null, + open: [...view.querySelectorAll('details[id]')].filter(d => d.open).map(d => d.id), status: $('copy-status')?.textContent || '', + }; + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D02.txt b/agents/darkwing/work/queue-54-review/r2/mut/D02.txt new file mode 100644 index 00000000..d6e24bb2 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D02.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4348.500415ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4647.902087ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6919.883108ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (233.832445ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (128.399993ms) +✔ bus refusals map to statuses and never carry a path or a stack (155.11505ms) +✔ humanCall speaks the human transport protocol without blocking the server (3385.889031ms) +✔ busReader takes --business, else the live bus host, else refuses (175.63599ms) +✔ humanCall kills a transport that runs past its timeout (528.588463ms) +✔ serve refuses a --business value that is not a business id (244.249386ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4383.028811ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2657.145759ms) +✔ conversation view: a newer session with no readable history keeps the marker (1670.285092ms) +✔ conversation view: seats without history say so and offer no reply (1325.034886ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4277.649078ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55713.008064ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (4.29812ms) +✔ credential state from the date alone, as the bus states it (0.324777ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2716.335734ms) +✔ queue: a refused read fails closed with the store's text, redacted (1245.168215ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2209.182022ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (18.425673ms) +✔ business: missing or invalid file refuses with the module's text, redacted (41.557382ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.799921ms) +✔ settings: release, board, loopback address, notifier binding name only (644.798398ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4338.61902ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22513.927723ms) +✔ loopback host and board origin fail closed (10.001194ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (151.461961ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (97.613254ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2232.211928ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.53889ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.9854ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.291677ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7618.055582ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (3340.784253ms) +✖ Queue, Business and Settings in their five states, with no move button (4146.611347ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2837.097841ms) +✔ the server log names no config path when the system config refuses (268.051823ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56241.840037 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (4146.611347ms) + AssertionError [ERR_ASSERTION]: #/queue keeps heading focus + + false !== true + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:103:14) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D03.diff b/agents/darkwing/work/queue-54-review/r2/mut/D03.diff new file mode 100644 index 00000000..4e0a3220 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D03.diff @@ -0,0 +1,12 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..b9e322c0 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -542,7 +542,6 @@ + if ($('copy-status')) $('copy-status').textContent = k.status; + const el = [...$('bus-view').querySelectorAll('a[href],[data-copy],[data-retry],[data-mirror]')].find(e => k.href ? e.getAttribute('href') === k.href : k.copy ? e.dataset.copy === k.copy : k.mirror ? e.dataset.mirror === k.mirror : k.retry && e.hasAttribute('data-retry')); + if (el && (k.href || k.copy || k.retry || k.mirror)) el.focus({ preventScroll: true }); +- else if (k.h1) $('bus-view').querySelector('h1')?.focus({ preventScroll: true }); + } + async function render(navigated) { + // A refresh due while this render reads would replace it: a navigation would lose its heading focus. diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D03.txt b/agents/darkwing/work/queue-54-review/r2/mut/D03.txt new file mode 100644 index 00000000..2f373d24 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D03.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5936.990333ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (7571.075761ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7894.353341ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (216.658477ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (77.752692ms) +✔ bus refusals map to statuses and never carry a path or a stack (144.184326ms) +✔ humanCall speaks the human transport protocol without blocking the server (2430.406698ms) +✔ busReader takes --business, else the live bus host, else refuses (307.499047ms) +✔ humanCall kills a transport that runs past its timeout (534.164096ms) +✔ serve refuses a --business value that is not a business id (198.223277ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5930.350514ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3774.213726ms) +✔ conversation view: a newer session with no readable history keeps the marker (1787.027526ms) +✔ conversation view: seats without history say so and offer no reply (1157.073495ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5617.067363ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56136.772328ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (5.300351ms) +✔ credential state from the date alone, as the bus states it (0.289634ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1377.189424ms) +✔ queue: a refused read fails closed with the store's text, redacted (853.483066ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (5371.652955ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (11.687595ms) +✔ business: missing or invalid file refuses with the module's text, redacted (16.452759ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.472022ms) +✔ settings: release, board, loopback address, notifier binding name only (1178.868105ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6805.535826ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23545.481285ms) +✔ loopback host and board origin fail closed (8.588984ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (100.116446ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (70.458252ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1279.360352ms) +✔ tokens.css and icons.svg are byte copies of docs/design (5.324979ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (4.065382ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.995247ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (9844.945802ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2983.290704ms) +✖ Queue, Business and Settings in their five states, with no move button (5952.837978ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (4044.904936ms) +✔ the server log names no config path when the system config refuses (427.940057ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56523.79534 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (5952.837978ms) + AssertionError [ERR_ASSERTION]: #/queue keeps heading focus + + false !== true + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:103:14) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D04.diff b/agents/darkwing/work/queue-54-review/r2/mut/D04.diff new file mode 100644 index 00000000..c99406e0 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D04.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js +index d321b483..c0491091 100644 +--- a/packages/webui/src/public/app.js ++++ b/packages/webui/src/public/app.js +@@ -191,7 +191,7 @@ + conv = { row: rowKey, id: null, branch: null, follow: null, messages: new Map(), markers: new Map(), sessionId: null, loading: true, polling: false, returnFocus: returnTo }; + selected = null; render(); showConversation(true); + $('conv-title').textContent = r ? `${r.agent} conversation` : 'Conversation'; +- $('conv-meta').textContent = ''; $('conv-pick').replaceChildren(); $('conv-log').replaceChildren(); drawMarkers(); convForm(); ++ $('conv-meta').textContent = ''; $('conv-log').replaceChildren(); drawMarkers(); convForm(); + if (!sameRow) $('conv-reply').value = drafts.get(rowKey) || ''; + convStatus('Loading history…'); + const slash = rowKey.lastIndexOf('/'), project = r?.project ?? rowKey.slice(0, slash), agent = r?.agent ?? rowKey.slice(slash + 1); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D04.txt b/agents/darkwing/work/queue-54-review/r2/mut/D04.txt new file mode 100644 index 00000000..431313e6 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D04.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5192.932491ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6671.626105ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7522.884088ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (473.014164ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (312.622442ms) +✔ bus refusals map to statuses and never carry a path or a stack (141.60371ms) +✔ humanCall speaks the human transport protocol without blocking the server (2784.611407ms) +✔ busReader takes --business, else the live bus host, else refuses (324.283405ms) +✔ humanCall kills a transport that runs past its timeout (529.269294ms) +✔ serve refuses a --business value that is not a business id (193.287612ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5161.956155ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3405.126943ms) +✔ conversation view: a newer session with no readable history keeps the marker (1432.807999ms) +✔ conversation view: seats without history say so and offer no reply (895.937261ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5247.077192ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55551.768246ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.447375ms) +✔ credential state from the date alone, as the bus states it (1.095046ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2659.512292ms) +✔ queue: a refused read fails closed with the store's text, redacted (1561.842751ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3535.887599ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (47.817239ms) +✔ business: missing or invalid file refuses with the module's text, redacted (9.846016ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (69.949869ms) +✔ settings: release, board, loopback address, notifier binding name only (583.942019ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5153.659867ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22651.637657ms) +✔ loopback host and board origin fail closed (10.121519ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (147.27203ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (191.427035ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1892.359564ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.291996ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.587158ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.404825ms) +✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4936.384145ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (3870.5278ms) +✔ Queue, Business and Settings in their five states, with no move button (6653.459383ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (3218.601514ms) +✔ the server log names no config path when the system config refuses (214.3862ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56221.788424 + +✖ failing tests: + +test at tests/shell.test.mjs:96:1 +✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4936.384145ms) + AssertionError [ERR_ASSERTION]: no stale session in the picker + + 1 !== 0 + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/shell.test.mjs:220: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: false, + code: 'ERR_ASSERTION', + actual: 1, + expected: 0, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D05.diff b/agents/darkwing/work/queue-54-review/r2/mut/D05.diff new file mode 100644 index 00000000..34684206 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D05.diff @@ -0,0 +1,12 @@ +diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js +index d321b483..fab77574 100644 +--- a/packages/webui/src/public/app.js ++++ b/packages/webui/src/public/app.js +@@ -325,7 +325,6 @@ + : `

${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.

`; + fresh(); + // Clearing the board or closing a conversation can remove what had focus: give it to the page. +- if (focused && document.activeElement === document.body) $('main').focus(); + } + function schedule() { clearTimeout(timer); if (!paused) timer = setTimeout(refresh, 10000); } + async function refresh() { diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D05.txt b/agents/darkwing/work/queue-54-review/r2/mut/D05.txt new file mode 100644 index 00000000..96d984f4 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D05.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4577.658283ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5143.059818ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (10302.727932ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (489.782787ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (488.78588ms) +✔ bus refusals map to statuses and never carry a path or a stack (247.157332ms) +✔ humanCall speaks the human transport protocol without blocking the server (2502.957297ms) +✔ busReader takes --business, else the live bus host, else refuses (186.141747ms) +✔ humanCall kills a transport that runs past its timeout (550.901946ms) +✔ serve refuses a --business value that is not a business id (300.318644ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4482.704509ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (6914.113485ms) +✔ conversation view: a newer session with no readable history keeps the marker (4181.995544ms) +✔ conversation view: seats without history say so and offer no reply (2066.329928ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4174.867865ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55089.109485ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.62962ms) +✔ credential state from the date alone, as the bus states it (1.836337ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2550.379886ms) +✔ queue: a refused read fails closed with the store's text, redacted (1408.237083ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (5406.357458ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (12.024609ms) +✔ business: missing or invalid file refuses with the module's text, redacted (106.505158ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.923792ms) +✔ settings: release, board, loopback address, notifier binding name only (1720.723619ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4486.443051ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22557.045626ms) +✔ loopback host and board origin fail closed (10.377262ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (193.217504ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (170.030744ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2074.814401ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.369496ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.685044ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.100934ms) +✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4060.138874ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (7463.012003ms) +✔ Queue, Business and Settings in their five states, with no move button (5265.171038ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (8341.47856ms) +✔ the server log names no config path when the system config refuses (268.736137ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55746.287428 + +✖ failing tests: + +test at tests/shell.test.mjs:96:1 +✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4060.138874ms) + AssertionError [ERR_ASSERTION]: focus after a refusal closes the conversation + + '' !== 'main' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/shell.test.mjs:231: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: false, + code: 'ERR_ASSERTION', + actual: '', + expected: 'main', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D06.diff b/agents/darkwing/work/queue-54-review/r2/mut/D06.diff new file mode 100644 index 00000000..92d13682 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D06.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/app.js b/packages/webui/src/public/app.js +index d321b483..0f4fec95 100644 +--- a/packages/webui/src/public/app.js ++++ b/packages/webui/src/public/app.js +@@ -325,7 +325,7 @@ + : `

${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.

`; + fresh(); + // Clearing the board or closing a conversation can remove what had focus: give it to the page. +- if (focused && document.activeElement === document.body) $('main').focus(); ++ if (document.activeElement === document.body) $('main').focus(); + } + function schedule() { clearTimeout(timer); if (!paused) timer = setTimeout(refresh, 10000); } + async function refresh() { diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D06.txt b/agents/darkwing/work/queue-54-review/r2/mut/D06.txt new file mode 100644 index 00000000..3db386f2 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D06.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3806.308805ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4245.8225ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6294.761998ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (406.016476ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (378.386294ms) +✔ bus refusals map to statuses and never carry a path or a stack (326.477432ms) +✔ humanCall speaks the human transport protocol without blocking the server (2846.756583ms) +✔ busReader takes --business, else the live bus host, else refuses (113.125937ms) +✔ humanCall kills a transport that runs past its timeout (530.842355ms) +✔ serve refuses a --business value that is not a business id (268.117929ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4063.036272ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3076.449968ms) +✔ conversation view: a newer session with no readable history keeps the marker (7537.679878ms) +✔ conversation view: seats without history say so and offer no reply (2425.97848ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3369.44327ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54430.081554ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.267306ms) +✔ credential state from the date alone, as the bus states it (0.295121ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2667.443452ms) +✔ queue: a refused read fails closed with the store's text, redacted (712.337574ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2795.520333ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.949888ms) +✔ business: missing or invalid file refuses with the module's text, redacted (18.704074ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (10.745951ms) +✔ settings: release, board, loopback address, notifier binding name only (394.456608ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3341.700633ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22544.014017ms) +✔ loopback host and board origin fail closed (9.611017ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (143.896575ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (382.234843ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1985.772993ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.352973ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (4.343082ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.368439ms) +✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4040.294605ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (5716.466986ms) +✔ Queue, Business and Settings in their five states, with no move button (5619.86532ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (5361.982497ms) +✔ the server log names no config path when the system config refuses (275.51659ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55091.523946 + +✖ failing tests: + +test at tests/shell.test.mjs:96:1 +✖ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (4040.294605ms) + AssertionError [ERR_ASSERTION]: a failure with nothing focused leaves focus alone + + false !== true + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/shell.test.mjs:191: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: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D07.diff b/agents/darkwing/work/queue-54-review/r2/mut/D07.diff new file mode 100644 index 00000000..402dc87a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D07.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..78c9a981 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -45,7 +45,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + return text => { + let s = unquote(String(text)); + for (const [re, label] of known) s = s.replace(re, label); +- return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); ++ return s.replace(/(?'); + }; + } + // Every string in a value, deep. Keys are left alone: they are fixed names or ids. diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D07.txt b/agents/darkwing/work/queue-54-review/r2/mut/D07.txt new file mode 100644 index 00000000..4b4d0143 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D07.txt @@ -0,0 +1,130 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3678.512067ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (3903.843967ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5493.171936ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (241.195821ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (110.851718ms) +✔ bus refusals map to statuses and never carry a path or a stack (51.255495ms) +✔ humanCall speaks the human transport protocol without blocking the server (3320.904789ms) +✔ busReader takes --business, else the live bus host, else refuses (143.122386ms) +✔ humanCall kills a transport that runs past its timeout (530.852264ms) +✔ serve refuses a --business value that is not a business id (245.171649ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3326.712595ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2333.936177ms) +✔ conversation view: a newer session with no readable history keeps the marker (2111.008937ms) +✔ conversation view: seats without history say so and offer no reply (6577.371911ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3517.562915ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53732.788971ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.582142ms) +✔ credential state from the date alone, as the bus states it (0.234375ms) +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1278.636646ms) +✔ queue: a refused read fails closed with the store's text, redacted (1638.868742ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (1936.391541ms) +✖ business: names, vars on the allowlist, authority, credential metadata only (155.531005ms) +✔ business: missing or invalid file refuses with the module's text, redacted (22.808553ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (11.21016ms) +✔ settings: release, board, loopback address, notifier binding name only (473.477386ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3637.578426ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22876.058089ms) +✔ loopback host and board origin fail closed (7.514381ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (138.769604ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (142.393668ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2232.792122ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.298949ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.411069ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.920183ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7342.033929ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (7159.014086ms) +✔ Queue, Business and Settings in their five states, with no move button (5426.433364ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1743.406062ms) +✔ the server log names no config path when the system config refuses (212.977487ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 35 +ℹ fail 4 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54177.291313 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.582142ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'file /run/x.token, see https://git.example/a' + - 'file , see https://git.example/a' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:25:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'file /run/x.token, see https://git.example/a', + expected: 'file , see https://git.example/a', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:48:1 +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1278.636646ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'token at /srv/secret/x.token for ; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:/srv/secret/r.json)' + - 'token at for ; tokens 0600 under (receipt file:)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:57:10) + 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: 'token at /srv/secret/x.token for ; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:/srv/secret/r.json)', + expected: 'token at for ; tokens 0600 under (receipt file:)', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:108:1 +✖ business: names, vars on the allowlist, authority, credential metadata only (155.531005ms) + AssertionError [ERR_ASSERTION]: response carries /srv/secret + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:113:3) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1743.406062ms) + AssertionError [ERR_ASSERTION]: response carries /srv/secret + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at seen (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:211:30) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:212:35) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D08.diff b/agents/darkwing/work/queue-54-review/r2/mut/D08.diff new file mode 100644 index 00000000..30a9e547 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D08.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..facc6483 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -45,7 +45,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + return text => { + let s = unquote(String(text)); + for (const [re, label] of known) s = s.replace(re, label); +- return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); ++ return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1'); + }; + } + // Every string in a value, deep. Keys are left alone: they are fixed names or ids. diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D08.txt b/agents/darkwing/work/queue-54-review/r2/mut/D08.txt new file mode 100644 index 00000000..55c348ac --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D08.txt @@ -0,0 +1,112 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3931.328382ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5970.043494ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6158.274561ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (225.440041ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (78.596474ms) +✔ bus refusals map to statuses and never carry a path or a stack (62.521748ms) +✔ humanCall speaks the human transport protocol without blocking the server (2203.730694ms) +✔ busReader takes --business, else the live bus host, else refuses (222.282006ms) +✔ humanCall kills a transport that runs past its timeout (529.410969ms) +✔ serve refuses a --business value that is not a business id (170.152906ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3896.868906ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2744.313649ms) +✔ conversation view: a newer session with no readable history keeps the marker (1630.323929ms) +✔ conversation view: seats without history say so and offer no reply (1257.682329ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4617.887488ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54082.520901ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (5.570202ms) +✔ credential state from the date alone, as the bus states it (0.339625ms) +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (492.575935ms) +✔ queue: a refused read fails closed with the store's text, redacted (960.020288ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3580.548201ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (12.187166ms) +✔ business: missing or invalid file refuses with the module's text, redacted (61.217106ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (25.172953ms) +✔ settings: release, board, loopback address, notifier binding name only (661.263159ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4945.489941ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23288.187522ms) +✔ loopback host and board origin fail closed (8.377735ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (96.264634ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (72.787602ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1095.327563ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.261571ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.826633ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.687011ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8019.060493ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (4455.207925ms) +✔ Queue, Business and Settings in their five states, with no move button (5590.236981ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1737.394462ms) +✔ the server log names no config path when the system config refuses (212.271942ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 36 +ℹ fail 3 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54448.14428 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (5.570202ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'user 123456789012345678 ok' + - 'user ok' + ^ + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:27:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'user 123456789012345678 ok', + expected: 'user ok', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:48:1 +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (492.575935ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'token at for 523456789012345678; tokens 0600 under (receipt file:)' + - 'token at for ; tokens 0600 under (receipt file:)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:57:10) + 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: 'token at for 523456789012345678; tokens 0600 under (receipt file:)', + expected: 'token at for ; tokens 0600 under (receipt file:)', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1737.394462ms) + AssertionError [ERR_ASSERTION]: response carries id 523456789012345678 + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:59:38) + at seen (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:211:30) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:212:35) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D09.diff b/agents/darkwing/work/queue-54-review/r2/mut/D09.diff new file mode 100644 index 00000000..fcfa0a2e --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D09.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..0ffd10af 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -43,7 +43,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + .sort((a, b) => b[0].length - a[0].length) + .map(([p, label]) => [new RegExp(`${escape(p.replace(/\/+$/, ''))}(?![\\w.-])`, 'g'), label]); + return text => { +- let s = unquote(String(text)); ++ let s = String(text); + for (const [re, label] of known) s = s.replace(re, label); + return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); + }; diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D09.txt b/agents/darkwing/work/queue-54-review/r2/mut/D09.txt new file mode 100644 index 00000000..127a69ff --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D09.txt @@ -0,0 +1,69 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4728.007494ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4606.165471ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6811.446749ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (232.152816ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (139.964411ms) +✔ bus refusals map to statuses and never carry a path or a stack (48.463107ms) +✔ humanCall speaks the human transport protocol without blocking the server (3445.232541ms) +✔ busReader takes --business, else the live bus host, else refuses (163.321375ms) +✔ humanCall kills a transport that runs past its timeout (546.022051ms) +✔ serve refuses a --business value that is not a business id (186.72156ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4763.25719ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2505.302061ms) +✔ conversation view: a newer session with no readable history keeps the marker (1597.890188ms) +✔ conversation view: seats without history say so and offer no reply (918.025465ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4273.618933ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55641.475104ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.971457ms) +✔ credential state from the date alone, as the bus states it (0.34117ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2691.151603ms) +✔ queue: a refused read fails closed with the store's text, redacted (1195.633838ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2989.654121ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.699895ms) +✔ business: missing or invalid file refuses with the module's text, redacted (5.761328ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.764472ms) +✔ settings: release, board, loopback address, notifier binding name only (200.762444ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4222.822665ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23592.882024ms) +✔ loopback host and board origin fail closed (7.353928ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (135.536145ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (155.867461ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2308.225348ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.341359ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.798919ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.558612ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7286.368903ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2919.432083ms) +✔ Queue, Business and Settings in their five states, with no move button (5390.885393ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (3279.683395ms) +✔ the server log names no config path when the system config refuses (213.512902ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56203.235049 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.971457ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + true !== false + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:35:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D10.diff b/agents/darkwing/work/queue-54-review/r2/mut/D10.diff new file mode 100644 index 00000000..c15df1ea --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D10.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..a0c03c51 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -44,7 +44,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + .map(([p, label]) => [new RegExp(`${escape(p.replace(/\/+$/, ''))}(?![\\w.-])`, 'g'), label]); + return text => { + let s = unquote(String(text)); +- for (const [re, label] of known) s = s.replace(re, label); ++ + return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); + }; + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D10.txt b/agents/darkwing/work/queue-54-review/r2/mut/D10.txt new file mode 100644 index 00000000..372167ee --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D10.txt @@ -0,0 +1,132 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4722.268365ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5400.932358ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5778.666337ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (263.664355ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (125.445744ms) +✔ bus refusals map to statuses and never carry a path or a stack (43.840408ms) +✔ humanCall speaks the human transport protocol without blocking the server (2331.699754ms) +✔ busReader takes --business, else the live bus host, else refuses (309.594864ms) +✔ humanCall kills a transport that runs past its timeout (531.213591ms) +✔ serve refuses a --business value that is not a business id (195.01894ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4727.096661ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2170.952575ms) +✔ conversation view: a newer session with no readable history keeps the marker (1853.995345ms) +✔ conversation view: seats without history say so and offer no reply (920.933734ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4725.348709ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53969.84547ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (5.237736ms) +✔ credential state from the date alone, as the bus states it (0.306016ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1517.775138ms) +✔ queue: a refused read fails closed with the store's text, redacted (993.552147ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3562.394769ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.729812ms) +✖ business: missing or invalid file refuses with the module's text, redacted (2.779218ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.561618ms) +✖ settings: release, board, loopback address, notifier binding name only (339.833526ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5289.213889ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23306.13427ms) +✔ loopback host and board origin fail closed (9.493386ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (167.027399ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (175.030721ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1121.549859ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.53641ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (6.446344ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (8.171333ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7825.244186ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2546.776066ms) +✔ Queue, Business and Settings in their five states, with no move button (5798.424176ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2211.462107ms) +✔ the server log names no config path when the system config refuses (317.455796ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 35 +ℹ fail 4 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54509.985201 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (5.237736ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'business file not found: ' + - 'business file not found: /businesses/a.json' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:23:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'business file not found: ', + expected: 'business file not found: /businesses/a.json', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:136:1 +✖ business: missing or invalid file refuses with the module's text, redacted (2.779218ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: + + actual - expected + + { + error: 'not-configured', + + message: 'business file not found: ' + - message: 'business file not found: /businesses/acme.json' + } + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:142:10) + 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: { error: 'not-configured', message: 'business file not found: ' }, + expected: { error: 'not-configured', message: 'business file not found: /businesses/acme.json' }, + operator: 'deepStrictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:171:1 +✖ settings: release, board, loopback address, notifier binding name only (339.833526ms) + AssertionError [ERR_ASSERTION]: The input did not match the regular expression /^no notifier config at \/notify\/acme\/notify\.json/. Input: + + 'no notifier config at ; write {"notifyVersion": 1, "binding": ""} there, mode 0600, or "binding": null to run without DMs' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:187:10) + 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: 'no notifier config at ; write {"notifyVersion": 1, "binding": ""} there, mode 0600, or "binding": null to run without DMs', + expected: /^no notifier config at \/notify\/acme\/notify\.json/, + operator: 'match', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2211.462107ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'business file not found: ' + - 'business file not found: /businesses/acme.json' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:239: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: 'business file not found: ', + expected: 'business file not found: /businesses/acme.json', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D11.diff b/agents/darkwing/work/queue-54-review/r2/mut/D11.diff new file mode 100644 index 00000000..61075d44 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D11.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..84240cbf 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -181,7 +181,7 @@ export function consoleReads({ root, system = null, configDir = null, rolesDir, + return { + async queue() { + const doc = await readQueue(); +- return scrub({ rows: doc.rows.map(queueSummary), notes: doc.notes, at: new Date(now()).toISOString() }, redact); ++ return { rows: doc.rows.map(queueSummary), notes: doc.notes, at: new Date(now()).toISOString() }; + }, + async row(id) { + const doc = await readQueue(); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D11.txt b/agents/darkwing/work/queue-54-review/r2/mut/D11.txt new file mode 100644 index 00000000..b4b3c2f0 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D11.txt @@ -0,0 +1,90 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5374.994585ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5154.547699ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7958.465663ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (324.05237ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (146.699204ms) +✔ bus refusals map to statuses and never carry a path or a stack (116.658124ms) +✔ humanCall speaks the human transport protocol without blocking the server (2864.586946ms) +✔ busReader takes --business, else the live bus host, else refuses (748.526501ms) +✔ humanCall kills a transport that runs past its timeout (530.070455ms) +✔ serve refuses a --business value that is not a business id (183.667224ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5124.550084ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3191.925738ms) +✔ conversation view: a newer session with no readable history keeps the marker (1767.818426ms) +✔ conversation view: seats without history say so and offer no reply (1183.383133ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5331.263643ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56394.632605ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.117182ms) +✔ credential state from the date alone, as the bus states it (0.28685ms) +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1422.931001ms) +✔ queue: a refused read fails closed with the store's text, redacted (3404.135366ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2998.642045ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (23.923501ms) +✔ business: missing or invalid file refuses with the module's text, redacted (14.964285ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (14.878068ms) +✔ settings: release, board, loopback address, notifier binding name only (385.602784ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5428.031155ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23455.509921ms) +✔ loopback host and board origin fail closed (7.720627ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (146.186748ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (148.941151ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1731.86876ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.191567ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.34193ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.864872ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7824.111254ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2729.619118ms) +✔ Queue, Business and Settings in their five states, with no move button (5629.939344ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2681.240296ms) +✔ the server log names no config path when the system config refuses (403.992828ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 37 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56903.397336 + +✖ failing tests: + +test at tests/reads.test.mjs:48:1 +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1422.931001ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'token at /srv/secret/x.token for 523456789012345678; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:/srv/secret/r.json)' + - 'token at for ; tokens 0600 under (receipt file:)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:57:10) + 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: 'token at /srv/secret/x.token for 523456789012345678; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:/srv/secret/r.json)', + expected: 'token at for ; tokens 0600 under (receipt file:)', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2681.240296ms) + AssertionError [ERR_ASSERTION]: response carries id 523456789012345678 + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:59:38) + at seen (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:211:30) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:212:35) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D12.diff b/agents/darkwing/work/queue-54-review/r2/mut/D12.diff new file mode 100644 index 00000000..154c3334 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D12.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..cb944e97 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -187,7 +187,7 @@ export function consoleReads({ root, system = null, configDir = null, rolesDir, + const doc = await readQueue(); + const row = doc.rows.find(r => r.id === id); + if (!row) throw fail('not-found', `no row ${id}`); +- return scrub({ row, notes: doc.notes, at: new Date(now()).toISOString() }, redact); ++ return { row, notes: doc.notes, at: new Date(now()).toISOString() }; + }, + async business() { + const b = loaded(); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D12.txt b/agents/darkwing/work/queue-54-review/r2/mut/D12.txt new file mode 100644 index 00000000..23234e68 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D12.txt @@ -0,0 +1,70 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4676.256766ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5652.009835ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5982.448685ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (256.274111ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (108.264037ms) +✔ bus refusals map to statuses and never carry a path or a stack (80.124769ms) +✔ humanCall speaks the human transport protocol without blocking the server (2178.092946ms) +✔ busReader takes --business, else the live bus host, else refuses (251.408163ms) +✔ humanCall kills a transport that runs past its timeout (529.002981ms) +✔ serve refuses a --business value that is not a business id (199.063046ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4714.136805ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2612.545133ms) +✔ conversation view: a newer session with no readable history keeps the marker (1303.086032ms) +✔ conversation view: seats without history say so and offer no reply (1378.328177ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5213.376009ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54056.852181ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.612748ms) +✔ credential state from the date alone, as the bus states it (0.168115ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1310.294031ms) +✔ queue: a refused read fails closed with the store's text, redacted (1063.140646ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3836.191496ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (11.044211ms) +✔ business: missing or invalid file refuses with the module's text, redacted (22.247917ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.606046ms) +✔ settings: release, board, loopback address, notifier binding name only (485.438037ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4877.471577ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (24394.322748ms) +✔ loopback host and board origin fail closed (8.420247ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (133.519218ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (105.873123ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1057.915363ms) +✔ tokens.css and icons.svg are byte copies of docs/design (0.991312ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.154849ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.422882ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8069.859073ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2618.472126ms) +✔ Queue, Business and Settings in their five states, with no move button (5865.88656ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1477.079296ms) +✔ the server log names no config path when the system config refuses (265.243078ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54456.915528 + +✖ failing tests: + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1477.079296ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'token at /srv/secret/x.token for 523456789012345678; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:/srv/secret/r.json)' + - 'token at for ; tokens 0600 under (receipt file:)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:214: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: 'token at /srv/secret/x.token for 523456789012345678; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:/srv/secret/r.json)', + expected: 'token at for ; tokens 0600 under (receipt file:)', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D13.diff b/agents/darkwing/work/queue-54-review/r2/mut/D13.diff new file mode 100644 index 00000000..cb3ed5a1 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D13.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..8c7e56b1 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -153,7 +153,7 @@ export function businessView(b, { system = null, now = Date.now() } = {}) { + for (const [service, ref] of Object.entries(b.tracker.sync.credentials)) credentials.push(credential(service, ref, b.tracker.sync.bot, 'tracker sync', now)); + return { + id: b.id, human: b.human, arbiters: b.arbiters, projects: Object.keys(b.projects), actions: [...ACTIONS], +- vars: pick(b.vars, VAR_KEYS), instances, launch: b.launch, credentials, ++ vars: b.vars, instances, launch: b.launch, credentials, + }; + } + diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D13.txt b/agents/darkwing/work/queue-54-review/r2/mut/D13.txt new file mode 100644 index 00000000..422d9e82 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D13.txt @@ -0,0 +1,89 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4602.491827ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5159.727876ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6238.889327ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (223.687836ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (736.783592ms) +✔ bus refusals map to statuses and never carry a path or a stack (201.408026ms) +✔ humanCall speaks the human transport protocol without blocking the server (2546.757467ms) +✔ busReader takes --business, else the live bus host, else refuses (177.799923ms) +✔ humanCall kills a transport that runs past its timeout (554.252001ms) +✔ serve refuses a --business value that is not a business id (179.635775ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4698.848196ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2346.391915ms) +✔ conversation view: a newer session with no readable history keeps the marker (1459.063784ms) +✔ conversation view: seats without history say so and offer no reply (866.044357ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4545.453806ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55238.209044ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.043624ms) +✔ credential state from the date alone, as the bus states it (1.427885ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2428.272353ms) +✔ queue: a refused read fails closed with the store's text, redacted (1149.222825ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2975.803027ms) +✖ business: names, vars on the allowlist, authority, credential metadata only (8.902499ms) +✔ business: missing or invalid file refuses with the module's text, redacted (104.672072ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.129818ms) +✔ settings: release, board, loopback address, notifier binding name only (227.836278ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4587.181249ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22788.635144ms) +✔ loopback host and board origin fail closed (8.672021ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (128.863615ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (81.857364ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2102.805706ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.234646ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.268908ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.85466ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7413.989444ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2836.131328ms) +✔ Queue, Business and Settings in their five states, with no move button (5454.209289ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2223.529846ms) +✔ the server log names no config path when the system config refuses (270.013578ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 37 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55720.295293 + +✖ failing tests: + +test at tests/reads.test.mjs:108:1 +✖ business: names, vars on the allowlist, authority, credential metadata only (8.902499ms) + AssertionError [ERR_ASSERTION]: response carries discordUserId + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:113:3) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2223.529846ms) + AssertionError [ERR_ASSERTION]: response carries discordUserId + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at seen (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:211:30) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:229: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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D14.diff b/agents/darkwing/work/queue-54-review/r2/mut/D14.diff new file mode 100644 index 00000000..92ea9409 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D14.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..6c873bcc 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -144,7 +144,7 @@ export function businessView(b, { system = null, now = Date.now() } = {}) { + refused = err.message; + } + } +- return { instance, definition: r.definition, holder: r.holder, vars: pick(r.vars, AGENT_KEYS), authority, refused }; ++ return { instance, definition: r.definition, holder: r.holder, vars: r.vars, authority, refused }; + }); + const credentials = []; + for (const [instance, r] of Object.entries(b.roles)) { diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D14.txt b/agents/darkwing/work/queue-54-review/r2/mut/D14.txt new file mode 100644 index 00000000..0e851ecb --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D14.txt @@ -0,0 +1,48 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4131.882197ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4167.204727ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6627.253569ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (283.309507ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (130.708288ms) +✔ bus refusals map to statuses and never carry a path or a stack (347.918781ms) +✔ humanCall speaks the human transport protocol without blocking the server (3171.960558ms) +✔ busReader takes --business, else the live bus host, else refuses (118.399742ms) +✔ humanCall kills a transport that runs past its timeout (528.763455ms) +✔ serve refuses a --business value that is not a business id (182.624836ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3919.263903ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2627.213977ms) +✔ conversation view: a newer session with no readable history keeps the marker (1501.84676ms) +✔ conversation view: seats without history say so and offer no reply (1392.664804ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3997.750009ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55321.272948ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.445275ms) +✔ credential state from the date alone, as the bus states it (0.272509ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2609.429165ms) +✔ queue: a refused read fails closed with the store's text, redacted (1424.883275ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (1760.787216ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (13.683278ms) +✔ business: missing or invalid file refuses with the module's text, redacted (9.352988ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.205694ms) +✔ settings: release, board, loopback address, notifier binding name only (351.5801ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4078.351086ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22833.484482ms) +✔ loopback host and board origin fail closed (8.808166ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (118.935744ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (91.85138ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2263.001801ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.284015ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.488139ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.30261ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7813.292614ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2622.207004ms) +✔ Queue, Business and Settings in their five states, with no move button (5342.54415ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2567.422788ms) +✔ the server log names no config path when the system config refuses (315.958541ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 39 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55749.29821 diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D15.diff b/agents/darkwing/work/queue-54-review/r2/mut/D15.diff new file mode 100644 index 00000000..c84c7274 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D15.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..105cdbc5 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -130,7 +130,7 @@ export function credentialState(service, date, now = Date.now()) { + } + const credential = (service, ref, account, role, now) => { + const dateKind = ref.expires ? 'expires' : 'rotateBy', date = ref[dateKind]; +- return { service, account, role, dateKind, date, state: credentialState(service, date, now) }; ++ return { ...ref, service, account, role, dateKind, date, state: credentialState(service, date, now) }; + }; + export function businessView(b, { system = null, now = Date.now() } = {}) { + const instances = Object.entries(b.roles).map(([instance, r]) => { diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D15.txt b/agents/darkwing/work/queue-54-review/r2/mut/D15.txt new file mode 100644 index 00000000..f643c345 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D15.txt @@ -0,0 +1,89 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3949.132243ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4898.888391ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5716.080111ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (240.269611ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (145.45023ms) +✔ bus refusals map to statuses and never carry a path or a stack (70.571976ms) +✔ humanCall speaks the human transport protocol without blocking the server (3037.741963ms) +✔ busReader takes --business, else the live bus host, else refuses (156.119455ms) +✔ humanCall kills a transport that runs past its timeout (528.209489ms) +✔ serve refuses a --business value that is not a business id (183.311854ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3621.207214ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3166.097566ms) +✔ conversation view: a newer session with no readable history keeps the marker (1254.86862ms) +✔ conversation view: seats without history say so and offer no reply (996.497539ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3865.311272ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54864.923962ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.163408ms) +✔ credential state from the date alone, as the bus states it (1.269508ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2303.380439ms) +✔ queue: a refused read fails closed with the store's text, redacted (997.87605ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2804.692817ms) +✖ business: names, vars on the allowlist, authority, credential metadata only (10.857313ms) +✔ business: missing or invalid file refuses with the module's text, redacted (8.456777ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (10.228548ms) +✔ settings: release, board, loopback address, notifier binding name only (699.092336ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3994.012616ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22487.710403ms) +✔ loopback host and board origin fail closed (8.781455ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (127.524933ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (86.144701ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2070.848546ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.258834ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.241808ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.875651ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7443.85949ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2410.449774ms) +✔ Queue, Business and Settings in their five states, with no move button (4986.666175ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2043.067467ms) +✔ the server log names no config path when the system config refuses (211.499426ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 37 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55347.999572 + +✖ failing tests: + +test at tests/reads.test.mjs:108:1 +✖ business: names, vars on the allowlist, authority, credential metadata only (10.857313ms) + AssertionError [ERR_ASSERTION]: response carries CODER_GITEA_SECRET_ENV + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:113:3) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2043.067467ms) + AssertionError [ERR_ASSERTION]: response carries CODER_GITEA_SECRET_ENV + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at seen (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:211:30) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:229: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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D16.diff b/agents/darkwing/work/queue-54-review/r2/mut/D16.diff new file mode 100644 index 00000000..8f8c5794 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D16.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..985a43dd 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -164,7 +164,7 @@ export function businessView(b, { system = null, now = Date.now() } = {}) { + export function consoleReads({ root, system = null, configDir = null, rolesDir, business = null, env = process.env, queueTimeoutMs = 30000, now = () => Date.now() }) { + const dataRoot = system?.dataRoot ?? null; + const redact = redactor({ configDir, dataRoot }); +- const fail = (code, message) => new ReadError(code, redact(message)); ++ const fail = (code, message) => new ReadError(code, message); + const queue = queueReader({ root, env, timeoutMs: queueTimeoutMs }); + const readQueue = async () => { + try { return await queue(); } catch (err) { throw err instanceof ReadError ? fail(err.code, err.message) : fail('read-failed', 'the queue read failed'); } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D16.txt b/agents/darkwing/work/queue-54-review/r2/mut/D16.txt new file mode 100644 index 00000000..961ccfc5 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D16.txt @@ -0,0 +1,93 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5867.029886ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5912.089574ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (7793.618512ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (474.232052ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (602.691653ms) +✔ bus refusals map to statuses and never carry a path or a stack (140.492635ms) +✔ humanCall speaks the human transport protocol without blocking the server (2399.529924ms) +✔ busReader takes --business, else the live bus host, else refuses (552.492231ms) +✔ humanCall kills a transport that runs past its timeout (546.777911ms) +✔ serve refuses a --business value that is not a business id (240.706993ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5771.61711ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2528.334127ms) +✔ conversation view: a newer session with no readable history keeps the marker (1875.502367ms) +✔ conversation view: seats without history say so and offer no reply (885.754778ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5981.576749ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55897.546762ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.949392ms) +✔ credential state from the date alone, as the bus states it (0.228941ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1995.013977ms) +✔ queue: a refused read fails closed with the store's text, redacted (2487.073336ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3559.528795ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.825428ms) +✖ business: missing or invalid file refuses with the module's text, redacted (3.687303ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (10.006011ms) +✔ settings: release, board, loopback address, notifier binding name only (203.093737ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (5847.99141ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23729.650368ms) +✔ loopback host and board origin fail closed (9.369667ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (132.50777ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (111.331344ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1845.380474ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.15701ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.072417ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.945738ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8095.937044ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2831.761142ms) +✔ Queue, Business and Settings in their five states, with no move button (5852.540818ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (3121.887177ms) +✔ the server log names no config path when the system config refuses (247.687992ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 37 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56355.392968 + +✖ failing tests: + +test at tests/reads.test.mjs:136:1 +✖ business: missing or invalid file refuses with the module's text, redacted (3.687303ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: + + actual - expected + + { + error: 'not-configured', + + message: 'business file not found: /home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-webui-reads-rqkZ2Q/config/businesses/acme.json' + - message: 'business file not found: /businesses/acme.json' + } + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:142:10) + 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: { error: 'not-configured', message: 'business file not found: /home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-webui-reads-rqkZ2Q/config/businesses/acme.json' }, + expected: { error: 'not-configured', message: 'business file not found: /businesses/acme.json' }, + operator: 'deepStrictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (3121.887177ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'business file not found: /home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-webui-reads-Ned8SO/config/businesses/acme.json' + - 'business file not found: /businesses/acme.json' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:239: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: 'business file not found: /home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-webui-reads-Ned8SO/config/businesses/acme.json', + expected: 'business file not found: /businesses/acme.json', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D17.diff b/agents/darkwing/work/queue-54-review/r2/mut/D17.diff new file mode 100644 index 00000000..be34ff7a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D17.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..e7564ce4 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -204,7 +204,7 @@ export function consoleReads({ root, system = null, configDir = null, rolesDir, + } catch (err) { + notifier = { refused: err instanceof ReadError ? err.code : 'not-configured', message: err.message }; + } +- return scrub({ release, business: id, notifier, at: new Date(now()).toISOString() }, redact); ++ return { release, business: id, notifier, at: new Date(now()).toISOString() }; + }, + }; + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D17.txt b/agents/darkwing/work/queue-54-review/r2/mut/D17.txt new file mode 100644 index 00000000..afda97d4 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D17.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4348.365756ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4590.193253ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6917.027162ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (352.357767ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (291.913158ms) +✔ bus refusals map to statuses and never carry a path or a stack (135.787056ms) +✔ humanCall speaks the human transport protocol without blocking the server (3014.315336ms) +✔ busReader takes --business, else the live bus host, else refuses (241.415565ms) +✔ humanCall kills a transport that runs past its timeout (538.008542ms) +✔ serve refuses a --business value that is not a business id (268.507569ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4319.007368ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2913.972453ms) +✔ conversation view: a newer session with no readable history keeps the marker (2088.469565ms) +✔ conversation view: seats without history say so and offer no reply (815.168859ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4289.462964ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55144.754029ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.353572ms) +✔ credential state from the date alone, as the bus states it (0.28609ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2666.117459ms) +✔ queue: a refused read fails closed with the store's text, redacted (1543.867749ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2738.10677ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (10.904728ms) +✔ business: missing or invalid file refuses with the module's text, redacted (7.725911ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.517597ms) +✖ settings: release, board, loopback address, notifier binding name only (211.789585ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4107.073039ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22742.977483ms) +✔ loopback host and board origin fail closed (9.050178ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (138.000942ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (242.709727ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2338.489446ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.43992ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.321153ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.718531ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7565.697193ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (3515.178213ms) +✔ Queue, Business and Settings in their five states, with no move button (5627.006557ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (3522.340426ms) +✔ the server log names no config path when the system config refuses (213.934237ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55785.179189 + +✖ failing tests: + +test at tests/reads.test.mjs:171:1 +✖ settings: release, board, loopback address, notifier binding name only (211.789585ms) + AssertionError [ERR_ASSERTION]: The input did not match the regular expression /^no notifier config at \/notify\/acme\/notify\.json/. Input: + + 'no notifier config at /home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-webui-reads-bueESS/data/notify/acme/notify.json; write {"notifyVersion": 1, "binding": ""} there, mode 0600, or "binding": null to run without DMs' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:187:10) + 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: 'no notifier config at /home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-webui-reads-bueESS/data/notify/acme/notify.json; write {"notifyVersion": 1, "binding": ""} there, mode 0600, or "binding": null to run without DMs', + expected: /^no notifier config at \/notify\/acme\/notify\.json/, + operator: 'match', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D18.diff b/agents/darkwing/work/queue-54-review/r2/mut/D18.diff new file mode 100644 index 00000000..88cf0601 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D18.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/cli.mjs b/packages/webui/src/cli.mjs +index 64b3e7b4..ccbe6780 100644 +--- a/packages/webui/src/cli.mjs ++++ b/packages/webui/src/cli.mjs +@@ -35,7 +35,7 @@ try { + const { dataRoot } = system; + bus = busReader({ dataRoot, socket: socketPath(dataRoot), business: options.business ?? null }); + busLine = `Bus: ${options.business ?? 'the running bus host\'s business'}`; +- } catch (err) { busLine = `Bus: not configured (${redactor({ configDir: configDir() })(err.message)})`; } ++ } catch (err) { busLine = `Bus: not configured (${err.message})`; } + const reads = consoleReads({ root: REPO, system, configDir: configDir(), rolesDir: rolesDir(), business: options.business ?? null }); + const server = await startServer({ board: options.board, port: options.port, bus, reads }); + console.log(`Mosaic Console: http://127.0.0.1:${server.address().port}/\nBoard: ${options.board}\n${busLine}\nCtrl-C stops this server.`); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D18.txt b/agents/darkwing/work/queue-54-review/r2/mut/D18.txt new file mode 100644 index 00000000..25026319 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D18.txt @@ -0,0 +1,72 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4223.124473ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4436.319299ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6393.227182ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (376.933607ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (335.390414ms) +✔ bus refusals map to statuses and never carry a path or a stack (96.684686ms) +✔ humanCall speaks the human transport protocol without blocking the server (2908.829243ms) +✔ busReader takes --business, else the live bus host, else refuses (182.361482ms) +✔ humanCall kills a transport that runs past its timeout (527.752745ms) +✔ serve refuses a --business value that is not a business id (232.77596ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4403.822956ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2502.117814ms) +✔ conversation view: a newer session with no readable history keeps the marker (1516.603152ms) +✔ conversation view: seats without history say so and offer no reply (877.20519ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4103.492276ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55031.195869ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.166716ms) +✔ credential state from the date alone, as the bus states it (1.112045ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2318.460758ms) +✔ queue: a refused read fails closed with the store's text, redacted (1670.23949ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2250.257953ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.363064ms) +✔ business: missing or invalid file refuses with the module's text, redacted (10.183282ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.242805ms) +✔ settings: release, board, loopback address, notifier binding name only (201.870563ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4237.656103ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22648.333507ms) +✔ loopback host and board origin fail closed (7.331302ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (118.392945ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (126.992258ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2157.409044ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.241189ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.391278ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.938146ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7096.450587ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (3160.359737ms) +✔ Queue, Business and Settings in their five states, with no move button (4979.436725ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2526.695671ms) +✖ the server log names no config path when the system config refuses (158.788827ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55511.953513 + +✖ failing tests: + +test at tests/views.test.mjs:251:1 +✖ the server log names no config path when the system config refuses (158.788827ms) + AssertionError [ERR_ASSERTION]: missing: the log names the temporary directory: Mosaic Console: http://127.0.0.1:37015/ + Board: http://127.0.0.1:7331 + Bus: not configured (system config problem (mosaic-config exit 3): mosaic-config: configuration not found: /home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-webui-log-qIlWKG/cfg/config.json (run scripts/bootstrap.sh to create it)) + Ctrl-C stops this server. + + + true !== false + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:263: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: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D19.diff b/agents/darkwing/work/queue-54-review/r2/mut/D19.diff new file mode 100644 index 00000000..b851dcd4 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D19.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..5f6f0c4e 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -83,7 +83,7 @@ export function queueReader({ root, env = process.env, timeoutMs = 30000, maxByt + // store's text. Anything else failed to run, and its stderr may be + // Node's own (a path and a stack), so it is not shown; the view keeps + // its last read. +- if (status === 2) return done(reject, new ReadError('queue-refused', said || 'the queue refused the read')); ++ if (status === 3) return done(reject, new ReadError('queue-refused', said || 'the queue refused the read')); + if (status !== 0) return done(reject, new ReadError('read-failed', `the queue read failed (exit ${status})`)); + try { + const doc = JSON.parse(Buffer.concat(out).toString('utf8')); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D19.txt b/agents/darkwing/work/queue-54-review/r2/mut/D19.txt new file mode 100644 index 00000000..cf6fd89a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D19.txt @@ -0,0 +1,99 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4429.40732ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5312.273282ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5485.762034ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (275.054415ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (77.848536ms) +✔ bus refusals map to statuses and never carry a path or a stack (55.357571ms) +✔ humanCall speaks the human transport protocol without blocking the server (2290.13066ms) +✔ busReader takes --business, else the live bus host, else refuses (443.643787ms) +✔ humanCall kills a transport that runs past its timeout (529.38196ms) +✔ serve refuses a --business value that is not a business id (203.869284ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4480.17962ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2617.543798ms) +✔ conversation view: a newer session with no readable history keeps the marker (1778.415676ms) +✔ conversation view: seats without history say so and offer no reply (1148.889093ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (5122.774685ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54151.79558ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.131276ms) +✔ credential state from the date alone, as the bus states it (0.273848ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1573.122796ms) +✖ queue: a refused read fails closed with the store's text, redacted (917.48889ms) +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3206.28123ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (10.424364ms) +✔ business: missing or invalid file refuses with the module's text, redacted (15.729521ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (40.43878ms) +✔ settings: release, board, loopback address, notifier binding name only (248.206273ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4525.101236ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23639.555408ms) +✔ loopback host and board origin fail closed (8.863177ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (136.032222ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (149.106678ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1136.35831ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.215173ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.776312ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.544684ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7924.244182ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (3020.961004ms) +✔ Queue, Business and Settings in their five states, with no move button (5692.379658ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2383.936414ms) +✔ the server log names no config path when the system config refuses (278.783402ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 37 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54586.555323 + +✖ failing tests: + +test at tests/reads.test.mjs:75:1 +✖ queue: a refused read fails closed with the store's text, redacted (917.48889ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'read-failed' + - 'queue-refused' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:81:10) + 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: 'read-failed', + expected: 'queue-refused', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:87:1 +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3206.28123ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: + + actual - expected + + Comparison { + + code: 'queue-refused', + + message: 'Error: boom\n at main (file:///srv/q/x.mjs:1:1)' + - code: 'read-failed', + - message: 'the queue read failed (exit 3)' + } + + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:103:3) + 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: Error: Error: boom + at main (file:///srv/q/x.mjs:1:1) + at ChildProcess. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/src/reads.mjs:86:45) + at ChildProcess.emit (node:events:514:20) + at maybeClose (node:internal/child_process:1125:16) + at ChildProcess._handle.onexit (node:internal/child_process:305:5), + expected: { code: 'read-failed', message: 'the queue read failed (exit 3)' }, + operator: 'rejects', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D20.diff b/agents/darkwing/work/queue-54-review/r2/mut/D20.diff new file mode 100644 index 00000000..4af1727a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D20.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..fdf4d899 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -71,7 +71,7 @@ export function queueReader({ root, env = process.env, timeoutMs = 30000, maxByt + const timer = setTimeout(() => { child.kill('SIGKILL'); done(reject, new ReadError('read-failed', 'the queue read did not finish in time')); }, timeoutMs); + child.stdout.on('data', chunk => { + size += chunk.length; +- if (size > maxBytes) { child.kill('SIGKILL'); return done(reject, new ReadError('invalid-response', 'the queue read printed too much')); } ++ if (false) { child.kill('SIGKILL'); return done(reject, new ReadError('invalid-response', 'the queue read printed too much')); } + out.push(chunk); + }); + child.stderr.on('data', chunk => { if (err.length < 64) err.push(chunk); }); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D20.txt b/agents/darkwing/work/queue-54-review/r2/mut/D20.txt new file mode 100644 index 00000000..d367d217 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D20.txt @@ -0,0 +1,77 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4841.222772ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5487.098928ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6839.589268ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (609.333716ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (523.696776ms) +✔ bus refusals map to statuses and never carry a path or a stack (184.726738ms) +✔ humanCall speaks the human transport protocol without blocking the server (2442.038169ms) +✔ busReader takes --business, else the live bus host, else refuses (163.969894ms) +✔ humanCall kills a transport that runs past its timeout (533.294862ms) +✔ serve refuses a --business value that is not a business id (210.829523ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4845.392664ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2468.326383ms) +✔ conversation view: a newer session with no readable history keeps the marker (1509.60312ms) +✔ conversation view: seats without history say so and offer no reply (885.846284ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4847.73469ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55584.2969ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.155997ms) +✔ credential state from the date alone, as the bus states it (0.260761ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2371.383524ms) +✔ queue: a refused read fails closed with the store's text, redacted (1709.606179ms) +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3026.091299ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.971531ms) +✔ business: missing or invalid file refuses with the module's text, redacted (6.755023ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.167464ms) +✔ settings: release, board, loopback address, notifier binding name only (240.2436ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4848.12045ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23908.114018ms) +✔ loopback host and board origin fail closed (7.05045ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (112.575009ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (218.818305ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2099.421251ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.331225ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.402939ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.888766ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7358.671695ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2880.854254ms) +✔ Queue, Business and Settings in their five states, with no move button (5659.295659ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2871.077194ms) +✔ the server log names no config path when the system config refuses (316.944553ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56302.126017 + +✖ failing tests: + +test at tests/reads.test.mjs:87:1 +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3026.091299ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: + + actual - expected + + Comparison { + code: 'invalid-response', + + message: 'the queue read printed something that is not its JSON' + - message: 'the queue read printed too much' + } + + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:105:3) + 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: Error: the queue read printed something that is not its JSON + at ChildProcess. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/src/reads.mjs:92:30) + at ChildProcess.emit (node:events:514:20) + at maybeClose (node:internal/child_process:1125:16) + at ChildProcess._handle.onexit (node:internal/child_process:305:5), + expected: { code: 'invalid-response', message: 'the queue read printed too much' }, + operator: 'rejects', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D21.diff b/agents/darkwing/work/queue-54-review/r2/mut/D21.diff new file mode 100644 index 00000000..2254f7f7 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D21.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..9c1a3702 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -68,7 +68,7 @@ export function queueReader({ root, env = process.env, timeoutMs = 30000, maxByt + const out = [], err = []; + let size = 0, settled = false; + const done = (fn, value) => { if (!settled) { settled = true; clearTimeout(timer); fn(value); } }; +- const timer = setTimeout(() => { child.kill('SIGKILL'); done(reject, new ReadError('read-failed', 'the queue read did not finish in time')); }, timeoutMs); ++ const timer = setTimeout(() => { child.kill('SIGKILL'); done(reject, new ReadError('read-failed', 'the queue read did not finish in time')); }, timeoutMs * 1000); + child.stdout.on('data', chunk => { + size += chunk.length; + if (size > maxBytes) { child.kill('SIGKILL'); return done(reject, new ReadError('invalid-response', 'the queue read printed too much')); } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D21.txt b/agents/darkwing/work/queue-54-review/r2/mut/D21.txt new file mode 100644 index 00000000..80892aba --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D21.txt @@ -0,0 +1,54 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4047.994713ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5493.364724ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6475.060786ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (344.669139ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (526.327841ms) +✔ bus refusals map to statuses and never carry a path or a stack (210.186982ms) +✔ humanCall speaks the human transport protocol without blocking the server (2813.384958ms) +✔ busReader takes --business, else the live bus host, else refuses (420.859817ms) +✔ humanCall kills a transport that runs past its timeout (529.301788ms) +✔ serve refuses a --business value that is not a business id (196.932872ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4508.597913ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2381.989167ms) +✔ conversation view: a newer session with no readable history keeps the marker (1654.282576ms) +✔ conversation view: seats without history say so and offer no reply (1143.875431ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3691.037414ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55027.507575ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.076111ms) +✔ credential state from the date alone, as the bus states it (0.183395ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2331.254237ms) +✔ queue: a refused read fails closed with the store's text, redacted (1310.612494ms) +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (60006.561036ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (9.189127ms) +✔ business: missing or invalid file refuses with the module's text, redacted (11.046848ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.183987ms) +✔ settings: release, board, loopback address, notifier binding name only (122.816233ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4044.671923ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23956.03821ms) +✔ loopback host and board origin fail closed (8.915996ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (137.47571ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (165.899756ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1984.05131ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.232064ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.309421ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.854287ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7668.289939ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2565.94891ms) +✔ Queue, Business and Settings in their five states, with no move button (5557.335915ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2503.584613ms) +✔ the server log names no config path when the system config refuses (210.196887ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 0 +ℹ cancelled 1 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 306671.544654 + +✖ failing tests: + +test at tests/reads.test.mjs:87:1 +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (60006.561036ms) + 'test timed out after 60000ms' diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D22.diff b/agents/darkwing/work/queue-54-review/r2/mut/D22.diff new file mode 100644 index 00000000..48b96c27 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D22.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..067fb8ab 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -114,7 +114,7 @@ export function businessId({ business = null, dataRoot = null }) { + if (!dataRoot) throw new ReadError('not-configured', 'the Console has no system config, so it knows no business'); + let state; + try { state = readHostState(dataRoot); } catch { throw new ReadError('no-bus-host', 'the bus host state file is unreadable'); } +- if (!state?.live) throw new ReadError('no-bus-host', 'no bus host is running and no --business was given'); ++ if (!state) throw new ReadError('no-bus-host', 'no bus host is running and no --business was given'); + return state.business; + } + const VAR_KEYS = ['tracker.kind', 'tracker.baseUrl', 'tracker.reconcileMinutes', 'tracker.pollSeconds', 'gitea.baseUrl', 'limits.tools', 'limits.network', 'limits.authority']; diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D22.txt b/agents/darkwing/work/queue-54-review/r2/mut/D22.txt new file mode 100644 index 00000000..0c8ada71 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D22.txt @@ -0,0 +1,48 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (6798.308522ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (8171.126344ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (10339.650081ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (620.104369ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (651.908336ms) +✔ bus refusals map to statuses and never carry a path or a stack (107.145963ms) +✔ humanCall speaks the human transport protocol without blocking the server (1856.613127ms) +✔ busReader takes --business, else the live bus host, else refuses (428.950655ms) +✔ humanCall kills a transport that runs past its timeout (531.241142ms) +✔ serve refuses a --business value that is not a business id (364.365598ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (7312.748843ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3310.811576ms) +✔ conversation view: a newer session with no readable history keeps the marker (1877.555631ms) +✔ conversation view: seats without history say so and offer no reply (961.142231ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (6694.324745ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (59345.415131ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.049565ms) +✔ credential state from the date alone, as the bus states it (0.262295ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2140.76369ms) +✔ queue: a refused read fails closed with the store's text, redacted (2728.342112ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (4001.802398ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.942483ms) +✔ business: missing or invalid file refuses with the module's text, redacted (22.480108ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.902561ms) +✔ settings: release, board, loopback address, notifier binding name only (1078.874523ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6688.571398ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (24397.913766ms) +✔ loopback host and board origin fail closed (8.856782ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (154.151941ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (166.653841ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1540.812704ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.325053ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.580587ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.172395ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (9786.737883ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (3176.507332ms) +✔ Queue, Business and Settings in their five states, with no move button (8068.083754ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (3933.18414ms) +✔ the server log names no config path when the system config refuses (212.185224ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 39 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 59922.92532 diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D23.diff b/agents/darkwing/work/queue-54-review/r2/mut/D23.diff new file mode 100644 index 00000000..76b770fd --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D23.diff @@ -0,0 +1,12 @@ +diff --git a/packages/webui/src/serve.mjs b/packages/webui/src/serve.mjs +index 8e89e3ed..96f47c8c 100644 +--- a/packages/webui/src/serve.mjs ++++ b/packages/webui/src/serve.mjs +@@ -117,7 +117,6 @@ export async function startServer({ host = '127.0.0.1', port = 7330, board = DEF + return busRead(res, bus, verb, search); + } + if (path === '/api/queue' || path.startsWith('/api/queue/') || path === '/api/business' || path === '/api/settings') { +- if (req.method !== 'GET') return json(res, 405, { error: 'method not allowed' }); + const a = server.address(), address = `http://${a.family === 'IPv6' ? `[${a.address}]` : a.address}:${a.port}/`; + if (path === '/api/settings') return consoleRead(res, async () => ({ ...(reads ? await reads.settings() : { release: null, business: null, notifier: { refused: 'not-configured', message: 'the Console has no reads configured' } }), board: upstream, address })); + if (!reads) return json(res, 503, { error: 'not-configured', message: 'the Console has no reads configured' }); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D23.txt b/agents/darkwing/work/queue-54-review/r2/mut/D23.txt new file mode 100644 index 00000000..66a2efed --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D23.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (6078.744644ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6248.49229ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8218.903911ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (424.798005ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (387.042542ms) +✔ bus refusals map to statuses and never carry a path or a stack (94.136201ms) +✔ humanCall speaks the human transport protocol without blocking the server (2106.912183ms) +✔ busReader takes --business, else the live bus host, else refuses (475.968302ms) +✔ humanCall kills a transport that runs past its timeout (530.262334ms) +✔ serve refuses a --business value that is not a business id (180.398907ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (6107.065921ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3770.987086ms) +✔ conversation view: a newer session with no readable history keeps the marker (1401.864309ms) +✔ conversation view: seats without history say so and offer no reply (976.349453ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (7366.709912ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (57136.937351ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.056273ms) +✔ credential state from the date alone, as the bus states it (0.268275ms) +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (2035.856025ms) +✔ queue: a refused read fails closed with the store's text, redacted (3220.497398ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3460.203009ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (14.434854ms) +✔ business: missing or invalid file refuses with the module's text, redacted (138.587854ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.591409ms) +✔ settings: release, board, loopback address, notifier binding name only (985.066988ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6189.061228ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22251.182976ms) +✔ loopback host and board origin fail closed (9.093808ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (140.317167ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (307.635041ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1198.2463ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.213659ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.236961ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.011914ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8015.283452ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2999.196799ms) +✔ Queue, Business and Settings in their five states, with no move button (7352.858604ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (3556.876138ms) +✔ the server log names no config path when the system config refuses (212.127697ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 57687.620628 + +✖ failing tests: + +test at tests/reads.test.mjs:48:1 +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (2035.856025ms) + AssertionError [ERR_ASSERTION]: /api/queue + + 200 !== 405 + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:70: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: false, + code: 'ERR_ASSERTION', + actual: 200, + expected: 405, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D24.diff b/agents/darkwing/work/queue-54-review/r2/mut/D24.diff new file mode 100644 index 00000000..42457486 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D24.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/serve.mjs b/packages/webui/src/serve.mjs +index 8e89e3ed..869ac527 100644 +--- a/packages/webui/src/serve.mjs ++++ b/packages/webui/src/serve.mjs +@@ -65,7 +65,7 @@ async function busRead(res, bus, verb, search) { + } + // Row 54 (#1543): GET only. `reads` is consoleReads() from reads.mjs; its + // bodies and messages arrive redacted. No route here writes or calls out. +-const QUEUE_ID = /^[1-9]\d{0,5}$/; ++const QUEUE_ID = /^\d+$/; + async function consoleRead(res, read) { + try { return json(res, 200, await read()); } catch (err) { + const code = err instanceof ReadError ? err.code : 'invalid-response'; diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D24.txt b/agents/darkwing/work/queue-54-review/r2/mut/D24.txt new file mode 100644 index 00000000..b66290bd --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D24.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (6117.413837ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (6173.63552ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8145.420068ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (354.997969ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (227.284138ms) +✔ bus refusals map to statuses and never carry a path or a stack (276.290406ms) +✔ humanCall speaks the human transport protocol without blocking the server (2222.068086ms) +✔ busReader takes --business, else the live bus host, else refuses (259.752592ms) +✔ humanCall kills a transport that runs past its timeout (528.831941ms) +✔ serve refuses a --business value that is not a business id (175.390451ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (6115.875236ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2488.727633ms) +✔ conversation view: a newer session with no readable history keeps the marker (1497.659535ms) +✔ conversation view: seats without history say so and offer no reply (1046.730484ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (6092.814435ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56600.088764ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.384863ms) +✔ credential state from the date alone, as the bus states it (0.246035ms) +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1764.679927ms) +✔ queue: a refused read fails closed with the store's text, redacted (2651.001001ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3155.803602ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (11.352967ms) +✔ business: missing or invalid file refuses with the module's text, redacted (71.412614ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.01258ms) +✔ settings: release, board, loopback address, notifier binding name only (510.647046ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6077.424149ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22608.126134ms) +✔ loopback host and board origin fail closed (8.861319ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (125.999102ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (146.116087ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1269.193812ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.222661ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.472756ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.909738ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8121.904873ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2846.789436ms) +✔ Queue, Business and Settings in their five states, with no move button (6179.127378ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2537.018211ms) +✔ the server log names no config path when the system config refuses (315.611349ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 57269.119785 + +✖ failing tests: + +test at tests/reads.test.mjs:48:1 +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1764.679927ms) + AssertionError [ERR_ASSERTION]: 0 + + 404 !== 400 + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:68:72) + 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: 404, + expected: 400, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D25.diff b/agents/darkwing/work/queue-54-review/r2/mut/D25.diff new file mode 100644 index 00000000..90f76d7b --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D25.diff @@ -0,0 +1,12 @@ +diff --git a/packages/webui/src/serve.mjs b/packages/webui/src/serve.mjs +index 8e89e3ed..abb97b7f 100644 +--- a/packages/webui/src/serve.mjs ++++ b/packages/webui/src/serve.mjs +@@ -120,7 +120,6 @@ export async function startServer({ host = '127.0.0.1', port = 7330, board = DEF + if (req.method !== 'GET') return json(res, 405, { error: 'method not allowed' }); + const a = server.address(), address = `http://${a.family === 'IPv6' ? `[${a.address}]` : a.address}:${a.port}/`; + if (path === '/api/settings') return consoleRead(res, async () => ({ ...(reads ? await reads.settings() : { release: null, business: null, notifier: { refused: 'not-configured', message: 'the Console has no reads configured' } }), board: upstream, address })); +- if (!reads) return json(res, 503, { error: 'not-configured', message: 'the Console has no reads configured' }); + if (path === '/api/business') return consoleRead(res, () => reads.business()); + if (path === '/api/queue') return consoleRead(res, () => reads.queue()); + const id = path.slice('/api/queue/'.length); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D25.txt b/agents/darkwing/work/queue-54-review/r2/mut/D25.txt new file mode 100644 index 00000000..fd58d075 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D25.txt @@ -0,0 +1,70 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3388.587899ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4596.351229ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6159.688419ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (411.84871ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (631.586809ms) +✔ bus refusals map to statuses and never carry a path or a stack (217.509069ms) +✔ humanCall speaks the human transport protocol without blocking the server (1980.222323ms) +✔ busReader takes --business, else the live bus host, else refuses (256.172401ms) +✔ humanCall kills a transport that runs past its timeout (570.571732ms) +✔ serve refuses a --business value that is not a business id (235.059389ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3284.106218ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2927.125645ms) +✔ conversation view: a newer session with no readable history keeps the marker (1736.782424ms) +✔ conversation view: seats without history say so and offer no reply (1236.84932ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3291.133393ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54489.159269ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (4.297024ms) +✔ credential state from the date alone, as the bus states it (0.288911ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1980.168077ms) +✔ queue: a refused read fails closed with the store's text, redacted (1168.980195ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2582.733813ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (15.217129ms) +✔ business: missing or invalid file refuses with the module's text, redacted (16.961039ms) +✖ business without --business: the live bus host, else no-bus-host; no system config: not-configured (11.200116ms) +✔ settings: release, board, loopback address, notifier binding name only (294.940147ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3299.534509ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22824.43039ms) +✔ loopback host and board origin fail closed (8.839579ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (147.849395ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (159.676948ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1438.296619ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.255244ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.208118ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.534007ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7319.215182ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2558.453587ms) +✔ Queue, Business and Settings in their five states, with no move button (5376.098322ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1946.307283ms) +✔ the server log names no config path when the system config refuses (315.108793ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55033.303432 + +✖ failing tests: + +test at tests/reads.test.mjs:158:1 +✖ business without --business: the live bus host, else no-bus-host; no system config: not-configured (11.200116ms) + AssertionError [ERR_ASSERTION]: /api/business + + actual - expected + + + 'invalid-response' + - 'not-configured' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:168:78) + 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: 'invalid-response', + expected: 'not-configured', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D26.diff b/agents/darkwing/work/queue-54-review/r2/mut/D26.diff new file mode 100644 index 00000000..ecac6719 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D26.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..793387eb 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -492,7 +492,7 @@ + } + const failTitle = err => err.code === 'queue-refused' ? 'Queue refused the read' : err.status === 403 ? 'Bus refused the read' : ['not-configured', 'no-bus-host'].includes(err.code) ? (err.module ? 'Nothing to read' : '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', 'queue-refused'].includes(err.code); ++ const refusal = err => err.status === 403 || ['not-configured', 'no-bus-host'].includes(err.code); + // After a refusal nothing read before is shown anywhere: not in a view, the palette or the Inbox count. + function forget() { last.clear(); inboxCount = null; } + const failedView = err => `${head(failTitle(err))}${empty('Nothing to show.', refusal(err) ? 'The view stays empty until the problem above is fixed.' : err.module ? 'Read again.' : 'Read again, or come back when the bus answers.')}`; diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D26.txt b/agents/darkwing/work/queue-54-review/r2/mut/D26.txt new file mode 100644 index 00000000..0acb00e8 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D26.txt @@ -0,0 +1,59 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4002.554062ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4162.842619ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5319.591602ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (314.624789ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (129.921819ms) +✔ bus refusals map to statuses and never carry a path or a stack (56.629235ms) +✔ humanCall speaks the human transport protocol without blocking the server (2366.201659ms) +✔ busReader takes --business, else the live bus host, else refuses (118.480372ms) +✔ humanCall kills a transport that runs past its timeout (535.018141ms) +✔ serve refuses a --business value that is not a business id (207.875102ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4066.894136ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2329.410743ms) +✔ conversation view: a newer session with no readable history keeps the marker (1219.74782ms) +✔ conversation view: seats without history say so and offer no reply (1085.648807ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4159.473242ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53594.588941ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.994069ms) +✔ credential state from the date alone, as the bus states it (0.192593ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1566.264102ms) +✔ queue: a refused read fails closed with the store's text, redacted (961.478816ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3032.175194ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.344866ms) +✔ business: missing or invalid file refuses with the module's text, redacted (5.715274ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.587348ms) +✔ settings: release, board, loopback address, notifier binding name only (131.221001ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4174.688574ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22716.36926ms) +✔ loopback host and board origin fail closed (8.815227ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (124.288801ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (98.827197ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1139.666219ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.238538ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.537926ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.941914ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7588.679417ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2707.433741ms) +✖ Queue, Business and Settings in their five states, with no move button (12794.066818ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1577.254508ms) +✔ the server log names no config path when the system config refuses (211.482879ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54020.921006 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (12794.066818ms) + Error: Uncaught (in promise) Error: Condition timed out: !!document.querySelector("#bus-view .banner.ref"): undefined + at Object.evaluate (file:///home/jwoltje/darkwing-scratch/r54b/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/r54b/mutwt/packages/webui/tests/views.test.mjs:115:9) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D27.diff b/agents/darkwing/work/queue-54-review/r2/mut/D27.diff new file mode 100644 index 00000000..b597c2bf --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D27.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..8fd65f85 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -567,7 +567,7 @@ + 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'; } +- catch { html = failedView(err) + (path === '/settings' ? appearance() : ''); state = refusal(err) ? 'refused' : 'failed'; } ++ catch { html = failedView(err); state = refusal(err) ? 'refused' : 'failed'; } + if (refusal(err)) forget(); + } + if (g !== gen) return; diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D27.txt b/agents/darkwing/work/queue-54-review/r2/mut/D27.txt new file mode 100644 index 00000000..b8676e02 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D27.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3870.955972ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4091.144587ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6026.972553ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (528.486744ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (167.317493ms) +✔ bus refusals map to statuses and never carry a path or a stack (244.333007ms) +✔ humanCall speaks the human transport protocol without blocking the server (2337.901175ms) +✔ busReader takes --business, else the live bus host, else refuses (140.658241ms) +✔ humanCall kills a transport that runs past its timeout (528.775992ms) +✔ serve refuses a --business value that is not a business id (255.955525ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3974.017912ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2147.046613ms) +✔ conversation view: a newer session with no readable history keeps the marker (1422.710797ms) +✔ conversation view: seats without history say so and offer no reply (1134.889127ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3951.649384ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54624.106048ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.814711ms) +✔ credential state from the date alone, as the bus states it (0.255761ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2055.422421ms) +✔ queue: a refused read fails closed with the store's text, redacted (1349.755914ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (1628.966478ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.511695ms) +✔ business: missing or invalid file refuses with the module's text, redacted (11.772911ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.900573ms) +✔ settings: release, board, loopback address, notifier binding name only (814.236521ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3970.092327ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22195.766568ms) +✔ loopback host and board origin fail closed (9.005773ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (250.888173ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (296.837336ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1332.35313ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.208859ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.37262ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.933785ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7148.577753ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2510.228313ms) +✖ Queue, Business and Settings in their five states, with no move button (4046.033413ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2040.787502ms) +✔ the server log names no config path when the system config refuses (264.995459ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55144.616812 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (4046.033413ms) + AssertionError [ERR_ASSERTION]: #/settings + + 0 !== 2 + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:122:16) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 0, + expected: 2, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D28.diff b/agents/darkwing/work/queue-54-review/r2/mut/D28.diff new file mode 100644 index 00000000..92783ed5 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D28.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..35214c6c 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -628,7 +628,7 @@ + const decisions = (last.get('inbox')?.rows || []).map(d => ({ href: `#/inbox/${enc(d.id)}`, label: first(d.question), group: `decision ${short(d.id)}` })); + const tasks = (last.get('tasks')?.rows || []).filter(r => TASK.test(String(r.task_ref))).map(r => { const t = task(r); return { href: `#/tasks/${enc(t.ref)}`, label: `#${t.id} ${t.title ?? '(no title in the current read)'}`, group: 'task' }; }); + const rows = (last.get('api:queue')?.rows || []).filter(r => Number.isInteger(r.id)).map(r => ({ href: `#/queue/${r.id}`, label: `${r.id} ${r.piece ?? ''}`, group: `queue row, ${r.state}` })); +- pkAll = [...VIEWS.map(([href, label]) => ({ href, label, group: 'view' })), ...decisions, ...tasks, ...rows]; ++ pkAll = [...VIEWS.map(([href, label]) => ({ href, label, group: 'view' })), ...decisions, ...tasks]; + } + function pkFill() { + const q = $('cmdk-input').value.trim().toLowerCase(); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D28.txt b/agents/darkwing/work/queue-54-review/r2/mut/D28.txt new file mode 100644 index 00000000..74296050 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D28.txt @@ -0,0 +1,59 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (7226.437783ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (7268.597536ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (9134.26969ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (435.493217ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (328.606071ms) +✔ bus refusals map to statuses and never carry a path or a stack (83.438859ms) +✔ humanCall speaks the human transport protocol without blocking the server (2154.856637ms) +✔ busReader takes --business, else the live bus host, else refuses (393.111577ms) +✔ humanCall kills a transport that runs past its timeout (536.047412ms) +✔ serve refuses a --business value that is not a business id (247.530328ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (7290.46934ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2122.951278ms) +✔ conversation view: a newer session with no readable history keeps the marker (1417.584934ms) +✔ conversation view: seats without history say so and offer no reply (1070.737679ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (7280.258171ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (57926.788173ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.176569ms) +✔ credential state from the date alone, as the bus states it (0.25049ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1616.763465ms) +✔ queue: a refused read fails closed with the store's text, redacted (3367.757488ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3521.052495ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (9.530299ms) +✔ business: missing or invalid file refuses with the module's text, redacted (6.4989ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.402443ms) +✔ settings: release, board, loopback address, notifier binding name only (144.295192ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (7354.847694ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (24082.07915ms) +✔ loopback host and board origin fail closed (9.71539ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (125.492271ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (185.824682ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1213.728439ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.199931ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.331924ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.359069ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (9313.253605ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2725.128426ms) +✖ Queue, Business and Settings in their five states, with no move button (15790.63923ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1260.474326ms) +✔ the server log names no config path when the system config refuses (212.895219ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 58326.728018 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (15790.63923ms) + Error: Uncaught (in promise) Error: Condition timed out: [...document.querySelectorAll("#cmdk-list [data-href]")].map(e=>e.dataset.href).includes("#/queue/7"): undefined + at Object.evaluate (file:///home/jwoltje/darkwing-scratch/r54b/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/r54b/mutwt/packages/webui/tests/views.test.mjs:182:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D29.diff b/agents/darkwing/work/queue-54-review/r2/mut/D29.diff new file mode 100644 index 00000000..874f17df --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D29.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..748b1c50 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -533,7 +533,7 @@ + function keep() { + const a = document.activeElement, view = $('bus-view'); + return { +- href: view.contains(a) ? a.getAttribute('href') : null, copy: view.contains(a) ? a.dataset?.copy : null, retry: view.contains(a) && a.hasAttribute?.('data-retry'), mirror: view.contains(a) ? a.dataset?.mirror : null, h1: view.contains(a) && a.tagName === 'H1', ++ href: view.contains(a) ? a.getAttribute('href') : null, copy: view.contains(a) ? a.dataset?.copy : null, retry: view.contains(a) && a.hasAttribute?.('data-retry'), h1: view.contains(a) && a.tagName === 'H1', + open: [...view.querySelectorAll('details[id]')].filter(d => d.open).map(d => d.id), status: $('copy-status')?.textContent || '', + }; + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D29.txt b/agents/darkwing/work/queue-54-review/r2/mut/D29.txt new file mode 100644 index 00000000..caf2f970 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D29.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3422.571536ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (3813.922622ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5870.051931ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (565.018459ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (602.143025ms) +✔ bus refusals map to statuses and never carry a path or a stack (178.749255ms) +✔ humanCall speaks the human transport protocol without blocking the server (2510.979832ms) +✔ busReader takes --business, else the live bus host, else refuses (129.204442ms) +✔ humanCall kills a transport that runs past its timeout (528.924954ms) +✔ serve refuses a --business value that is not a business id (178.019281ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3390.424329ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2766.594351ms) +✔ conversation view: a newer session with no readable history keeps the marker (1778.990268ms) +✔ conversation view: seats without history say so and offer no reply (1125.156563ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3151.152306ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54476.859481ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.241969ms) +✔ credential state from the date alone, as the bus states it (0.285566ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2579.696675ms) +✔ queue: a refused read fails closed with the store's text, redacted (664.638651ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2526.230072ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (15.023538ms) +✔ business: missing or invalid file refuses with the module's text, redacted (12.776304ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (9.840733ms) +✔ settings: release, board, loopback address, notifier binding name only (209.611633ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3103.769143ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22266.039413ms) +✔ loopback host and board origin fail closed (8.741578ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (140.527887ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (263.375958ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2043.669417ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.104789ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.1368ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.917159ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7110.674581ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2606.107038ms) +✖ Queue, Business and Settings in their five states, with no move button (5005.725118ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2368.416104ms) +✔ the server log names no config path when the system config refuses (212.654379ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55004.180532 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (5005.725118ms) + AssertionError [ERR_ASSERTION]: the refresh keeps focus on the mirror select + + false !== true + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:198:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D30.diff b/agents/darkwing/work/queue-54-review/r2/mut/D30.diff new file mode 100644 index 00000000..71fff5ff --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D30.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..44ee3f35 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -671,7 +671,7 @@ + // Settings' appearance selects drive the command bar's, and follow them back. + document.addEventListener('change', e => { + const m = e.target.closest?.('#bus-view select[data-mirror]'); +- if (m) { const src = $(m.dataset.mirror); src.value = m.value; src.dispatchEvent(new Event('change')); return; } ++ if (m) return; + if (e.target.id === 'palette' || e.target.id === 'mode') for (const s of document.querySelectorAll(`#bus-view select[data-mirror="${e.target.id}"]`)) s.value = e.target.value; + }); + window.addEventListener('hashchange', () => render(true)); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D30.txt b/agents/darkwing/work/queue-54-review/r2/mut/D30.txt new file mode 100644 index 00000000..15edaca0 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D30.txt @@ -0,0 +1,59 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3210.039647ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5919.48126ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6338.073562ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (919.123782ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (237.581986ms) +✔ bus refusals map to statuses and never carry a path or a stack (192.551367ms) +✔ humanCall speaks the human transport protocol without blocking the server (2136.52214ms) +✔ busReader takes --business, else the live bus host, else refuses (274.012492ms) +✔ humanCall kills a transport that runs past its timeout (545.39136ms) +✔ serve refuses a --business value that is not a business id (234.164395ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3544.243672ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3513.304201ms) +✔ conversation view: a newer session with no readable history keeps the marker (1341.946705ms) +✔ conversation view: seats without history say so and offer no reply (1374.935202ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3335.323949ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54903.686002ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.510434ms) +✔ credential state from the date alone, as the bus states it (2.314449ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2299.933676ms) +✔ queue: a refused read fails closed with the store's text, redacted (1009.130301ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3430.84929ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (9.472442ms) +✔ business: missing or invalid file refuses with the module's text, redacted (6.70986ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.945398ms) +✔ settings: release, board, loopback address, notifier binding name only (171.65694ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3239.320367ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22558.844964ms) +✔ loopback host and board origin fail closed (7.610786ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (139.7267ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (92.609124ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1666.631056ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.167202ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.255846ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.93167ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7995.760597ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2807.285881ms) +✖ Queue, Business and Settings in their five states, with no move button (15976.377927ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1308.767678ms) +✔ the server log names no config path when the system config refuses (210.960693ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55319.096061 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (15976.377927ms) + Error: Uncaught (in promise) Error: Condition timed out: document.querySelector("#mode").value==="dark": undefined + at Object.evaluate (file:///home/jwoltje/darkwing-scratch/r54b/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/r54b/mutwt/packages/webui/tests/views.test.mjs:192:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D31.diff b/agents/darkwing/work/queue-54-review/r2/mut/D31.diff new file mode 100644 index 00000000..58f5d333 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D31.diff @@ -0,0 +1,13 @@ +diff --git a/packages/queue/src/store.mjs b/packages/queue/src/store.mjs +index 237d3525..ca6c1837 100644 +--- a/packages/queue/src/store.mjs ++++ b/packages/queue/src/store.mjs +@@ -815,7 +815,7 @@ export function list(opts) { + // lead decision 83). Same unlocked read as list; writes nothing. + export function rows(opts) { + const r = readState(opts); +- return { rows: rowsArray(r.state), err: r.notes, code: 0 }; ++ return { rows: rowsArray(r.state), err: [], code: 0 }; + } + + export function show(opts, id) { diff --git a/agents/darkwing/work/queue-54-review/r2/mut/D31.txt b/agents/darkwing/work/queue-54-review/r2/mut/D31.txt new file mode 100644 index 00000000..69aa38d6 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/D31.txt @@ -0,0 +1,182 @@ +✔ F1: an ordinary commit after update-ref is refused until step 8; then it commits and the queue stays at C (1394.333101ms) +✔ F1: a plain `commit -e` whose guard ran before update-ref fails at its own HEAD update (1140.423108ms) +ℹ git commit -e: index.lock free during the editor +✔ F1: a `commit -e -- path` whose guard ran before update-ref fails at its own HEAD update (1043.222642ms) +ℹ git commit -e -- src.txt: index.lock held during the editor +✔ F1: step 8 with index.lock held exits 3, and ordinary commits stay refused until the printed command runs (1048.386411ms) +✔ F1: HEAD moving after the step-7 guard check and before update-ref: refused, nothing published (1040.712346ms) +✔ F1: H is recorded before the canary, so HEAD moving during the step-1 canary is refused at step 7 (1086.167611ms) +✔ F1: a queue commit landing after H is recorded: step 1 says HEAD moved, not the guard (1348.095069ms) +✔ F1: a queue commit landing between the HEAD check and the canary: the failed clean run is reported as HEAD moved (979.495808ms) +✔ F1: a shared-index change during the procedure is not committed (1110.412582ms) +✔ F1: a queue path staged after update-ref: step 8 stops and touches nothing (1131.105975ms) +✔ F1: a missing or a different hook refuses (766.438973ms) +✔ F1: same bytes without the exec bit, a symlinked hook, and core.hooksPath in the local or global scope each refuse before update-ref (1306.178912ms) +✔ F1: the canary refuses a hook that git would not run (778.002631ms) +✔ F1: the guard deactivated after step 1 is refused at the step-7 recheck (1134.54885ms) +✔ bootstrap: implementation-only HEAD, the guard, genesis, the --genesis commit, then an extending commit (1024.291992ms) +✔ bootstrap: --genesis with a base present, no base without --genesis, an op before the first commit, a changed map, another branch (1172.518852ms) +✔ bootstrap: the archived tests and validator run outside any repository (1010.000103ms) +✔ general: an unrelated staged file stays staged, and the committed blobs are the snapshot bytes (1041.606489ms) +✔ general: a queue write after the snapshot is not committed (1292.026899ms) +✔ general: a snapshot whose log does not extend the base refuses (1036.985538ms) +✔ general: install-hook privilege, repair of a same-bytes hook, and its refusals (155.146831ms) +✔ general: environment overrides, a linked worktree and usage (629.476877ms) +✔ general: a queue path staged before the run refuses at step 1 (699.778485ms) +✔ general: HEAD's queue tests failing in the archive refuse (893.985863ms) +✔ genesis document serializes deterministically and replays (5.690766ms) +✔ a hand edit that stays valid JSON fails replay; a formatting-only edit fails re-serialization (3.06713ms) +✔ a tampered result, receipt or viewSha fails replay (2.373692ms) +✔ op ids: 8 to 72 characters for callers, 80 in the log for .outcome entries (0.168839ms) +✔ add: defaults for an ordinary seat, privileged extras, refusals (3.866614ms) +✔ matrix: queued→briefed privileged; briefed→in-progress owner with after satisfied (5.484063ms) +✔ matrix: release, review round, changes requested and waiting-on-jason (14.747406ms) +✔ matrix J5: in-review→done by the gate owner with evidence naming the current round (8.983846ms) +✔ review issue, lead decision 23: none refuses, one is used, several need --issue, later rounds keep it (21.334866ms) +✔ the row schema refuses a round with a null issue, and the A1 review shape (P2) (2.877811ms) +✔ matrix R1: every state × target × actor class matches 8.7, gate owner jason or not, required or not (1364.684904ms) +✔ matrix: blocked keeps the claim and returns only to previousState (4.81789ms) +✔ matrix J4: parking is Jason's, refused while required; unpark returns to queued (2.761016ms) +✔ field edits: who may change what (5.564459ms) +✔ set issues keeps a logged narrowing of closes (N10) (2.874168ms) +✔ text the table shows refuses \ and <, everywhere it enters (N8) (2.281257ms) +✔ every accepted text renders to nine cells on every row (N8) (20.311867ms) +✔ genesis: the map refuses an owner among its row's reviewers; replay doesn't (2026-10-04) (0.441717ms) +✔ times and dates must be calendar values, not just the shape (2026-10-04) (1.62284ms) +✔ replay holds every op id to the caller's rule (N11) (4.080487ms) +✔ note: owner, listed reviewer or privileged; empty clears (0.964886ms) +✔ assign moves the claim with the owner; done clears it (2.13224ms) +✔ render is byte-stable and escapes pipes (0.452775ms) +✔ view classification: current, genuine stale, edited stale marker, changed current body, markers (0.538216ms) +✔ next: resume, then review, then start, then wait, then nothing; lowest id first (15.14622ms) +✔ canonical args make a retry's identity independent of list order (0.255143ms) +✔ manifests, headings and blob ids (0.357285ms) +✔ the migration map: one queue-map block, exact keys (0.479229ms) +✔ every call but `queue` reaches the seat CLI exactly as before A2 (611.676876ms) +✔ `queue` reaches the queue CLI with the rest of the arguments (191.123194ms) +✔ the pre-A2 fixture is the script A2 changed (0.333019ms) +✔ acquire publishes the record by link; release removes only its own lock (13.52631ms) +✔ a kill between the temp write and the link leaves no lock (60.068353ms) +✔ a short or failed temp write refuses and leaves no lock and no temp (12.061676ms) +✔ a link error other than EEXIST refuses (7.528959ms) +✔ an error after the link releases the lock: unreadable gate, failing temp stat (21.595397ms) +✔ a release that fails on a gate path is reported, never a stack trace (P1) (35.474346ms) +✔ a paused holder: another writer waits 10 s, then refuses naming it live (10096.129815ms) +✔ two concurrent unlockers: the second refuses on the gate (41.230435ms) +✔ a writer publishing during an unlock, lock first: unlock sees it live and refuses (15.701983ms) +✔ a writer publishing during an unlock, gate first: the writer releases and refuses (23.024055ms) +✔ a gate swapped while held is left in place and reported, on success and on refusal (N1) (28.760912ms) +✔ a reused pid within one boot is mismatch; unlock removes the lock and never signals the process (19.667117ms) +✔ the same pid and start on a different boot is mismatch (0.759783ms) +✔ a foreign host is unknown whatever the local pid says; unlock refuses (76.967929ms) +✔ unreadable /proc: classification is unknown and acquire refuses (0.651702ms) +✔ invalid records: empty, unparsable, wrong keys, bad start or boot (0.200101ms) +✔ a stale gate blocks writers; --check-gate says mismatch for a reused pid (26.005879ms) +✔ a delayed release by a dead owner, after unlock and a new owner: the inode check keeps the new lock (38.06564ms) +✔ release checks the inode too: a byte-identical lock file with a new inode is left in place (32.627128ms) +✔ unlock refuses a live, unknown or invalid lock, and does nothing without one (58.944186ms) +✔ the migration map validates and renders the golden genesis table (3.663208ms) +✔ the marked QUEUE.md holds every row and parked item between its markers (1.75139ms) +✔ map-check reports each kind of drift (4.798679ms) +✔ a request posts once as the requester; a retry sends nothing (959.691743ms) +✔ each transport answer maps to posted, failed or uncertain (8.9 step 3) (4781.600922ms) +✔ the pre-send checks: GET user must name the requester, under the deadline (1631.634711ms) +✔ the lead's request refuses a token for login sage (969.770152ms) +✔ the credential file: the seat's own, 0600, no symlink, never the shared default (994.404807ms) +✔ an unresolved request blocks a new request, a new round, waiting-on-jason and done (2477.452402ms) +✔ a same-op retry after a kill sends nothing, even with a stale view (3473.638937ms) +✔ a held lock at the outcome exits 3 and names what the transport said (778.547047ms) +✔ late outcomes: after an abandon, and after a resolve with the same or another id (2851.521584ms) +✔ resolve checks the comment: issue, markers, round, candidate and author (1706.445578ms) +✔ the lead resolves a seat's request: the comment's author is the requester, fetched with the lead's token (751.233734ms) +✔ validateRow checks a request round's shape, which every replayed entry must keep (544.743962ms) +✔ request, changes, a new candidate, approval: every round pinned; no review files (1803.039322ms) +✔ a row with no reviewers opens a round that posts nothing (1260.304455ms) +✔ verify-commit: a prospective tree must hold exactly the candidate's paths (1410.610666ms) +✔ semantics: v1 entries replay as before; review entries need v2 (510.662268ms) +✔ set reviewers refuses the row's owner (2026-09-28) (372.077566ms) +✔ the owner records no verdict, even as a listed reviewer (502.160993ms) +✔ a request comment over the length limit is not sent (590.732364ms) +✔ a late POST on a closed row leaves a conflict nothing can resolve, and resolve asks nothing (728.424304ms) +✔ a Jason-gated row reaches waiting-on-jason only on every reviewer's approval (2602.294566ms) +✔ genesis: refusals before anything is written (451.161238ms) +✔ genesis: the map must be committed, well formed, with committed briefs and seats (677.54461ms) +✔ genesis: markers, a stray witness, once only; a retry returns the receipt (608.082873ms) +✔ genesis: a file holding genesis alone with no witness is confirmed by sync or a retry (516.991848ms) +✔ canonical checks: worktree, second clone, detached HEAD, wrong branch, GIT_DIR, foreign code; a symlink works (664.566655ms) +✔ --by that differs from MOSAIC_AGENT_NAME warns on stderr and logs nothing more (N12) (814.810242ms) +✔ op ids: missing, too long, reserved; a retry answers; another payload refuses (724.5479ms) +✔ a retried add returns the id it first allocated, after reassignment and after done (926.400294ms) +✔ Rocko's S4 schedule: a lost result, another writer, then the retry opens no second round (693.102178ms) +✔ the review issue and the evidence round through the CLI (lead decision 23, 8.7) (1314.956701ms) +✔ claims and add defaults through the CLI; candidates are manifests or reachable commits (833.698274ms) +✔ add, set reviewers and assign refuse the row's owner as a reviewer (561.836478ms) +✔ the working-brief check: a changed working copy refuses the start and flags next (740.488008ms) +✔ next: resume first, then nothing for an idle seat; needs a seat (332.061522ms) +✔ view stale: new ops and verify refuse naming the unshown op; retries answer; reads warn; render fixes (723.660043ms) +✔ view unknown: a hand edit, an old marker over an edited body, missing or duplicate markers (1178.648381ms) +✔ a hand edit to queue.json refuses every verb, reads included (583.959579ms) +✔ verify and render --check leave bytes and mtimes unchanged (448.949088ms) +✔ render is byte-stable across runs and repositories (360.732181ms) +✔ snapshot and verify --snapshot (912.444616ms) +✔ usage errors exit 4 (597.283022ms) +✔ a short write, ENOSPC or a file fsync failure: nothing visible, temp removed (328.527789ms) +✔ a rename failure: nothing visible, temp removed (186.448983ms) +✔ a directory fsync failure: uncertain, exit 3, no receipt; the tail refuses new ops; a retry confirms (339.137729ms) +✔ a directory fsync failure, then sync names the op (468.11189ms) +✔ a witness write failure: uncertain, durable, exit 3; the view is untouched (264.12832ms) +✔ the .git fsync after the witness rename fails: uncertain, exit 3, the witness says so (205.910147ms) +✔ confirming a tail fsyncs queue.json and docs/plans before the witness; either failure changes nothing (288.87307ms) +✔ the docs/plans fsync after the view rename fails: the op stands, the view is written, a warning says so (284.74277ms) +✔ a lock swapped while held is left in place and reported, on a receipt and on a refusal (240.77ms) +✔ a lock that cannot be released after an op is reported, on a receipt and on a refusal (228.15754ms) +✔ unlock prints a swapped gate's warning on stderr, the result on stdout (193.658921ms) +✔ a view write that fails keeps the op and reports a stale view (223.76549ms) +✔ SIGKILL before the rename: nothing recorded; the retry removes the leftover temp (651.409888ms) +✔ SIGKILL after the rename, before the witness: the tail refuses new ops and sync names the op (696.44472ms) +✔ SIGKILL after the witness, before the view: the stale refusal names the op (647.791881ms) +✔ SIGKILL after the view, before the receipt: the retry returns the receipt (630.032102ms) +✔ git checkout between steps 1 and 7: step 7 refuses and nothing is written (253.696153ms) +✔ git stash restoring an older valid pair: history lost; accept-history needs privilege, a reason and --yes (1090.94125ms) +✔ a deleted witness: refused after the locked recheck; accept-history records it absent (328.131904ms) +✔ a header edit during a write: the op stands, the view write is skipped with a warning (190.651961ms) +✔ a reader paused between the witness and the file while a writer finishes: no lost-history report (227.906033ms) +✖ rows: every row as show prints it, in list order; writes nothing; same notes and refusals as list (289.368789ms) +✔ file-then-witness order forced by a hook: the locked recheck prevents a false report (256.465651ms) +✔ a writer paused before and after the witness rename: readers see a tail, then a match (240.28425ms) +✔ a true rollback is reported only after the locked recheck; a held lock names its holder instead (623.838286ms) +✔ an accept-history in progress: an unlocked reader waits on the lock and never reports lost history (680.193502ms) +✔ the platform check refuses other filesystems (151.391011ms) +✔ tmpfs passes only a test layer that allows it (N5) (262.172995ms) +✔ unlock keeps a multi-line lock record on stdout (P3) (230.37843ms) +ℹ tests 149 +ℹ suites 0 +ℹ pass 148 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 31778.109925 + +✖ failing tests: + +test at tests/write.test.mjs:337:1 +✖ rows: every row as show prints it, in list order; writes nothing; same notes and refusals as list (289.368789ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: + + actual - expected + + + [] + - [ + - 'rev 1 visible, not confirmed durable' + - ] + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/queue/tests/write.test.mjs:349:10) + 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: [], + expected: [ 'rev 1 visible, not confirmed durable' ], + operator: 'deepStrictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E01.diff b/agents/darkwing/work/queue-54-review/r2/mut/E01.diff new file mode 100644 index 00000000..27a5e886 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E01.diff @@ -0,0 +1,18 @@ +diff --git a/packages/webui/src/queue-read.mjs b/packages/webui/src/queue-read.mjs +index ae7e4509..b7661fbe 100644 +--- a/packages/webui/src/queue-read.mjs ++++ b/packages/webui/src/queue-read.mjs +@@ -8,10 +8,10 @@ + // (a half-written file in a shared checkout) prints "the queue read failed", + // never Node's own message, which names the file:// path and a stack. + +-let QueueError = null; ++import { rows } from '../../queue/src/store.mjs'; ++import { QueueError as QE } from '../../queue/src/errors.mjs'; ++let QueueError = QE; + try { +- ({ QueueError } = await import('../../queue/src/errors.mjs')); +- const { rows } = await import('../../queue/src/store.mjs'); + const r = rows({}); + process.stdout.write(`${JSON.stringify({ rows: r.rows, notes: r.err })}\n`); + } catch (err) { diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E01.txt b/agents/darkwing/work/queue-54-review/r2/mut/E01.txt new file mode 100644 index 00000000..b5427c34 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E01.txt @@ -0,0 +1,94 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (5929.625638ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5699.448049ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (15524.47714ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (331.03666ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (491.260057ms) +✔ bus refusals map to statuses and never carry a path or a stack (134.817023ms) +✔ humanCall speaks the human transport protocol without blocking the server (2168.983997ms) +✔ busReader takes --business, else the live bus host, else refuses (685.867467ms) +✔ humanCall kills a transport that runs past its timeout (529.134616ms) +✔ serve refuses a --business value that is not a business id (189.017088ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5683.48261ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (10673.893349ms) +✔ conversation view: a newer session with no readable history keeps the marker (3317.025941ms) +✔ conversation view: seats without history say so and offer no reply (2797.998251ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (6107.590317ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56545.702502ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.339896ms) +✔ credential state from the date alone, as the bus states it (1.093126ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1861.127948ms) +✔ queue: a refused read fails closed with the store's text, redacted (3247.528564ms) +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (1114.135501ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (25.021431ms) +✔ business: missing or invalid file refuses with the module's text, redacted (81.651426ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (70.680331ms) +✔ settings: release, board, loopback address, notifier binding name only (1708.943976ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (6047.658121ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22505.129912ms) +✔ loopback host and board origin fail closed (8.811438ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (121.234293ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (76.948391ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1433.929743ms) +✔ tokens.css and icons.svg are byte copies of docs/design (0.909606ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.781846ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.448411ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8111.181718ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (9458.274548ms) +✔ Queue, Business and Settings in their five states, with no move button (6310.538998ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (10988.847653ms) +✔ the server log names no config path when the system config refuses (276.999784ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 57033.895715 + +✖ failing tests: + +test at tests/reads.test.mjs:87:1 +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (1114.135501ms) + AssertionError [ERR_ASSERTION]: syntax error + + actual - expected + + [ + 1, + '', + + 'file:///home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-queue-test-YLeato/repo/packages/queue/src/store.mjs:1\n' + + + 'export const rows = (;\n' + + + ' ^\n' + + + '\n' + + + "SyntaxError: Unexpected token ';'\n" + + + ' at compileSourceTextModule (node:internal/modules/esm/utils:355:16)\n' + + + ' at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:93:18)\n' + + + ' at #translate (node:internal/modules/esm/loader:441:20)\n' + + + ' at afterLoad (node:internal/modules/esm/loader:509:29)\n' + + + ' at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:514:12)\n' + + + ' at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:567:36)\n' + + + ' at afterResolve (node:internal/modules/esm/loader:614:52)\n' + + + ' at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:620:12)\n' + + + ' at ModuleJob.syncLink (node:internal/modules/esm/module_job:277:33)\n' + + + ' at ModuleJob.link (node:internal/modules/esm/module_job:389:17)\n' + + + '\n' + + + 'Node.js v26.8.1\n' + - 'the queue read failed\n' + ] + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:93:12) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.processPendingSubtests (node:internal/test_runner/test:974:18) + at Test.postRun (node:internal/test_runner/test:1542:19) + at Test.run (node:internal/test_runner/test:1467:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ 1, '', "file:///home/jwoltje/darkwing-scratch/r54b/tmp/mosaic-queue-test-YLeato/repo/packages/queue/src/store.mjs:1\nexport const rows = (;\n ^\n\nSyntaxError: Unexpected token ';'\n at compileSourceTextModule (node:internal/modules/esm/utils:355:16)\n at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:93:18)\n at #translate (node:internal/modules/esm/loader:441:20)\n at afterLoad (node:internal/modules/esm/loader:509:29)\n at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:514:12)\n at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:567:36)\n at afterResolve (node:internal/modules/esm/loader:614:52)\n at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:620:12)\n at ModuleJob.syncLink (node:internal/modules/esm/module_job:277:33)\n at ModuleJob.link (node:internal/modules/esm/module_job:389:17)\n\nNode.js v26.8.1\n" ], + expected: [ 1, '', 'the queue read failed\n' ], + operator: 'deepStrictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E02.diff b/agents/darkwing/work/queue-54-review/r2/mut/E02.diff new file mode 100644 index 00000000..93a24141 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E02.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..912a6a9b 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -84,7 +84,7 @@ export function queueReader({ root, env = process.env, timeoutMs = 30000, maxByt + // Node's own (a path and a stack), so it is not shown; the view keeps + // its last read. + if (status === 2) return done(reject, new ReadError('queue-refused', said || 'the queue refused the read')); +- if (status !== 0) return done(reject, new ReadError('read-failed', `the queue read failed (exit ${status})`)); ++ if (status !== 0) return done(reject, new ReadError('read-failed', said || `the queue read failed (exit ${status})`)); + try { + const doc = JSON.parse(Buffer.concat(out).toString('utf8')); + if (!Array.isArray(doc?.rows) || !Array.isArray(doc?.notes)) throw new Error('shape'); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E02.txt b/agents/darkwing/work/queue-54-review/r2/mut/E02.txt new file mode 100644 index 00000000..f7b2aba9 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E02.txt @@ -0,0 +1,73 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3588.55315ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4046.440624ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5589.92317ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (203.464906ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (103.150144ms) +✔ bus refusals map to statuses and never carry a path or a stack (43.636079ms) +✔ humanCall speaks the human transport protocol without blocking the server (2202.707583ms) +✔ busReader takes --business, else the live bus host, else refuses (207.303537ms) +✔ humanCall kills a transport that runs past its timeout (530.807348ms) +✔ serve refuses a --business value that is not a business id (194.562603ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3652.739114ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3249.466791ms) +✔ conversation view: a newer session with no readable history keeps the marker (4787.170709ms) +✔ conversation view: seats without history say so and offer no reply (5267.272894ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3720.365569ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53785.995754ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.725273ms) +✔ credential state from the date alone, as the bus states it (0.16658ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1381.574793ms) +✔ queue: a refused read fails closed with the store's text, redacted (1004.294774ms) +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (767.512652ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.792885ms) +✔ business: missing or invalid file refuses with the module's text, redacted (21.412841ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (11.313465ms) +✔ settings: release, board, loopback address, notifier binding name only (546.80936ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3753.713619ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22913.507935ms) +✔ loopback host and board origin fail closed (7.869447ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (116.124657ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (80.637672ms) +✔ unreachable board reports URL; CLI rejects unsupported options (943.877109ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.2269ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.300365ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.94455ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7645.884306ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (9076.352919ms) +✔ Queue, Business and Settings in their five states, with no move button (5492.400613ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1698.839121ms) +✔ the server log names no config path when the system config refuses (316.894407ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54173.091855 + +✖ failing tests: + +test at tests/reads.test.mjs:87:1 +✖ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (767.512652ms) + AssertionError [ERR_ASSERTION]: syntax error + + actual - expected + + { + error: 'read-failed', + + message: 'the queue read failed' + - message: 'the queue read failed (exit 1)' + } + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:97: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: false, + code: 'ERR_ASSERTION', + actual: { error: 'read-failed', message: 'the queue read failed' }, + expected: { error: 'read-failed', message: 'the queue read failed (exit 1)' }, + operator: 'deepStrictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E03.diff b/agents/darkwing/work/queue-54-review/r2/mut/E03.diff new file mode 100644 index 00000000..67f7c327 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E03.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..29bc5404 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -45,7 +45,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + return text => { + let s = unquote(String(text)); + for (const [re, label] of known) s = s.replace(re, label); +- return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); ++ return s.replace(/(^|[\s('"`=,[{<])~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); + }; + } + // Every string in a value, deep. Keys are left alone: they are fixed names or ids. diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E03.txt b/agents/darkwing/work/queue-54-review/r2/mut/E03.txt new file mode 100644 index 00000000..5f18029f --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E03.txt @@ -0,0 +1,112 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4019.360031ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4839.546754ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6424.819438ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (283.874313ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (122.450665ms) +✔ bus refusals map to statuses and never carry a path or a stack (62.114728ms) +✔ humanCall speaks the human transport protocol without blocking the server (2433.983865ms) +✔ busReader takes --business, else the live bus host, else refuses (274.03938ms) +✔ humanCall kills a transport that runs past its timeout (533.32155ms) +✔ serve refuses a --business value that is not a business id (358.202399ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3941.875952ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2994.887726ms) +✔ conversation view: a newer session with no readable history keeps the marker (1480.471374ms) +✔ conversation view: seats without history say so and offer no reply (1353.158154ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3605.861871ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54345.882078ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.016447ms) +✔ credential state from the date alone, as the bus states it (0.358031ms) +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (983.996112ms) +✔ queue: a refused read fails closed with the store's text, redacted (1050.192797ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3182.961094ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (26.579923ms) +✔ business: missing or invalid file refuses with the module's text, redacted (42.520817ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (10.858586ms) +✔ settings: release, board, loopback address, notifier binding name only (774.588593ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3835.422134ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23602.453142ms) +✔ loopback host and board origin fail closed (9.875578ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (125.950636ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (109.263948ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1247.602364ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.22212ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.924466ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.180531ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8333.895629ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (3340.899891ms) +✔ Queue, Business and Settings in their five states, with no move button (6078.586818ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1409.85663ms) +✔ the server log names no config path when the system config refuses (430.661909ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 36 +ℹ fail 3 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54789.900189 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.016447ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'file:/x, file:///srv/y and <>' + - 'file:, file: and <>' + ^ + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:31:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'file:/x, file:///srv/y and <>', + expected: 'file:, file: and <>', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:48:1 +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (983.996112ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'token at for ; tokens 0600 under (receipt file:/srv/secret/r.json)' + - 'token at for ; tokens 0600 under (receipt file:)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:57:10) + 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: 'token at for ; tokens 0600 under (receipt file:/srv/secret/r.json)', + expected: 'token at for ; tokens 0600 under (receipt file:)', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1409.85663ms) + AssertionError [ERR_ASSERTION]: response carries /srv/secret + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at seen (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:211:30) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:212:35) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E04.diff b/agents/darkwing/work/queue-54-review/r2/mut/E04.diff new file mode 100644 index 00000000..0827b5ee --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E04.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..0edd6a42 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -45,7 +45,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + return text => { + let s = unquote(String(text)); + for (const [re, label] of known) s = s.replace(re, label); +- return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); ++ return s.replace(/(^|[\s('"`=,[{<]|:)~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); + }; + } + // Every string in a value, deep. Keys are left alone: they are fixed names or ids. diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E04.txt b/agents/darkwing/work/queue-54-review/r2/mut/E04.txt new file mode 100644 index 00000000..e22be12f --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E04.txt @@ -0,0 +1,97 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3553.582881ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (3977.564709ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5601.882229ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (297.864833ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (85.70265ms) +✔ bus refusals map to statuses and never carry a path or a stack (53.800654ms) +✔ humanCall speaks the human transport protocol without blocking the server (2249.424172ms) +✔ busReader takes --business, else the live bus host, else refuses (179.568059ms) +✔ humanCall kills a transport that runs past its timeout (531.205351ms) +✔ serve refuses a --business value that is not a business id (274.029861ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3538.23539ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3435.646129ms) +✔ conversation view: a newer session with no readable history keeps the marker (1363.308021ms) +✔ conversation view: seats without history say so and offer no reply (1116.5204ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3664.879557ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53959.306817ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.946346ms) +✔ credential state from the date alone, as the bus states it (1.254389ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1342.577207ms) +✔ queue: a refused read fails closed with the store's text, redacted (896.503012ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3423.963019ms) +✖ business: names, vars on the allowlist, authority, credential metadata only (8.516208ms) +✔ business: missing or invalid file refuses with the module's text, redacted (11.547891ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (6.732898ms) +✔ settings: release, board, loopback address, notifier binding name only (186.709019ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3764.815771ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23029.518463ms) +✔ loopback host and board origin fail closed (9.657342ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (134.051809ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (148.699494ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1162.078506ms) +✔ tokens.css and icons.svg are byte copies of docs/design (0.966918ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.156346ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.800961ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7818.927116ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2495.433571ms) +✔ Queue, Business and Settings in their five states, with no move button (5417.895834ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1997.202561ms) +✔ the server log names no config path when the system config refuses (212.977773ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 37 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54401.902793 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.946346ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'file , see https:' + - 'file , see https://git.example/a' + ^ + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:25:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'file , see https:', + expected: 'file , see https://git.example/a', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:108:1 +✖ business: names, vars on the allowlist, authority, credential metadata only (8.516208ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: + + actual - expected + + { + + 'gitea.baseUrl': 'https:', + + 'tracker.baseUrl': 'http:', + - 'gitea.baseUrl': 'https://git.example', + - 'tracker.baseUrl': 'http://127.0.0.1:3456', + 'tracker.pollSeconds': 60 + } + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:116:10) + 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: { 'tracker.baseUrl': 'http:', 'tracker.pollSeconds': 60, 'gitea.baseUrl': 'https:' }, + expected: { 'tracker.baseUrl': 'http://127.0.0.1:3456', 'gitea.baseUrl': 'https://git.example', 'tracker.pollSeconds': 60 }, + operator: 'deepStrictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E05.diff b/agents/darkwing/work/queue-54-review/r2/mut/E05.diff new file mode 100644 index 00000000..9fdbd976 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E05.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..eed11cad 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -45,7 +45,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + return text => { + let s = unquote(String(text)); + for (const [re, label] of known) s = s.replace(re, label); +- return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); ++ return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); + }; + } + // Every string in a value, deep. Keys are left alone: they are fixed names or ids. diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E05.txt b/agents/darkwing/work/queue-54-review/r2/mut/E05.txt new file mode 100644 index 00000000..846f6b62 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E05.txt @@ -0,0 +1,111 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4808.795806ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5313.73431ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6311.106107ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (265.916343ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (193.901167ms) +✔ bus refusals map to statuses and never carry a path or a stack (446.225526ms) +✔ humanCall speaks the human transport protocol without blocking the server (2870.908832ms) +✔ busReader takes --business, else the live bus host, else refuses (176.150517ms) +✔ humanCall kills a transport that runs past its timeout (528.689869ms) +✔ serve refuses a --business value that is not a business id (168.137447ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (5038.645695ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2228.362159ms) +✔ conversation view: a newer session with no readable history keeps the marker (1553.540451ms) +✔ conversation view: seats without history say so and offer no reply (907.529289ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4802.901871ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55413.167363ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.523859ms) +✔ credential state from the date alone, as the bus states it (1.210027ms) +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1815.719137ms) +✔ queue: a refused read fails closed with the store's text, redacted (1904.673406ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2634.985616ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.709211ms) +✔ business: missing or invalid file refuses with the module's text, redacted (12.363352ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.891149ms) +✔ settings: release, board, loopback address, notifier binding name only (297.175236ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4799.252088ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22599.949339ms) +✔ loopback host and board origin fail closed (9.033996ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (125.072773ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (80.60962ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2052.047232ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.223225ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.456863ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.781237ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7257.572317ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2532.034045ms) +✔ Queue, Business and Settings in their five states, with no move button (5350.251251ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1783.156571ms) +✔ the server log names no config path when the system config refuses (213.663192ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 36 +ℹ fail 3 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55898.68915 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.523859ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (lead decision 74)' + - 'tokens 0600 under (lead decision 74)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:29:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (lead decision 74)', + expected: 'tokens 0600 under (lead decision 74)', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/reads.test.mjs:48:1 +✖ queue: rows, one row, ids and methods, notes; no path or id from a row (1815.719137ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'token at for ; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:)' + - 'token at for ; tokens 0600 under (receipt file:)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:57:10) + 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: 'token at for ; tokens 0600 under ~/.config/mosaic-dev/secrets/mosaic-stack (receipt file:)', + expected: 'token at for ; tokens 0600 under (receipt file:)', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1783.156571ms) + AssertionError [ERR_ASSERTION]: response carries ~/ + + true !== false + + at clean (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads-fixture.mjs:60:215) + at seen (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:211:30) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:212:35) + 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: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E06.diff b/agents/darkwing/work/queue-54-review/r2/mut/E06.diff new file mode 100644 index 00000000..64ad23ee --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E06.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..28298e29 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -45,7 +45,7 @@ export function redactor({ configDir = null, dataRoot = null } = {}) { + return text => { + let s = unquote(String(text)); + for (const [re, label] of known) s = s.replace(re, label); +- return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); ++ return s.replace(/(^|[\s('"`=,[{]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(/(?'); + }; + } + // Every string in a value, deep. Keys are left alone: they are fixed names or ids. diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E06.txt b/agents/darkwing/work/queue-54-review/r2/mut/E06.txt new file mode 100644 index 00000000..2bcf2f9a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E06.txt @@ -0,0 +1,71 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4638.324888ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5386.953954ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6636.592976ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (443.957455ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (275.542727ms) +✔ bus refusals map to statuses and never carry a path or a stack (143.228196ms) +✔ humanCall speaks the human transport protocol without blocking the server (2685.462607ms) +✔ busReader takes --business, else the live bus host, else refuses (172.264458ms) +✔ humanCall kills a transport that runs past its timeout (550.322903ms) +✔ serve refuses a --business value that is not a business id (224.809501ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4443.281837ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2331.427568ms) +✔ conversation view: a newer session with no readable history keeps the marker (1352.496507ms) +✔ conversation view: seats without history say so and offer no reply (1192.056894ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4576.31433ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (55584.427114ms) +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.318217ms) +✔ credential state from the date alone, as the bus states it (0.405671ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2452.060634ms) +✔ queue: a refused read fails closed with the store's text, redacted (1515.486336ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2466.521887ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (9.286482ms) +✔ business: missing or invalid file refuses with the module's text, redacted (35.701797ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.085783ms) +✔ settings: release, board, loopback address, notifier binding name only (187.229233ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4390.176562ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23404.059717ms) +✔ loopback host and board origin fail closed (10.052908ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (214.622458ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (346.137565ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1704.285338ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.30912ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.495504ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.121012ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7180.331898ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2865.146967ms) +✔ Queue, Business and Settings in their five states, with no move button (5207.697275ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2730.201284ms) +✔ the server log names no config path when the system config refuses (211.697645ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 56086.911896 + +✖ failing tests: + +test at tests/reads.test.mjs:21:1 +✖ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.318217ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'file:, file: and ' + - 'file:, file: and <>' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:31:10) + at Test.runInAsyncScope (node:async_hooks:226:14) + at Test.run (node:internal/test_runner/test:1402:25) + at Test.start (node:internal/test_runner/test:1262:17) + at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'file:, file: and ', + expected: 'file:, file: and <>', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E07.diff b/agents/darkwing/work/queue-54-review/r2/mut/E07.diff new file mode 100644 index 00000000..1a7d2108 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E07.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..888cb7c9 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -405,7 +405,7 @@ + const refused = instances.filter(i => i.refused).map(i => `
  • ${txt(i.instance)}: ${txt(i.refused)}
  • `).join(''); + const credRows = creds.map(c => `${txt(c.service)}${txt(c.account) || 'not named in the business file'}${txt(c.role)}${txt(c.dateKind === 'expires' ? 'expires' : 'rotate by')} ${badge(c.state, CRED[c.state] || 'muted')}`).join(''); + return `${head(`Business ${txt(b.id)}`, `${readLine()} The business file is edited where it lives; Console only reads it.`)} +-

    Business

    Human
    ${txt(b.human) || none}
    Arbiters
    ${arbiterRefs(b.arbiters)}
    Projects
    ${names(b.projects)}
    Launcher
    ${txt(launch.by) || none}
    May launch
    ${names(launch.instances)}
    At most
    ${Object.entries(launch.max || {}).map(([f, c]) => `${txt(c)} ${txt(f)}`).join(', ') || none}
    ++

    Business

    Human
    ${txt(b.human) || none}
    Arbiters
    ${names(b.arbiters)}
    Projects
    ${names(b.projects)}
    Launcher
    ${txt(launch.by) || none}
    May launch
    ${names(launch.instances)}
    At most
    ${Object.entries(launch.max || {}).map(([f, c]) => `${txt(c)} ${txt(f)}`).join(', ') || none}
    +

    Vars

    ${kvRows(b.vars, 'No vars Console shows are set.')}
    +

    Role instances ${instances.length}

    ${instances.length ? `
    ${['Instance', 'Definition', 'Holder', 'Harness'].map(h => ``).join('')}${roleRows}
    ${h}
    ` : empty('This business has no role instances.', 'An instance shows here when the business file names one under roles.')}
    + ${instances.length ? `

    Authority

    Within the role, cross-role (needs the other role), or gated (needs the human), as the business package classifies each action.

    ${matrix}${refused ? `
      ${refused}
    ` : ''}
    ` : ''} diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E07.txt b/agents/darkwing/work/queue-54-review/r2/mut/E07.txt new file mode 100644 index 00000000..63554ec4 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E07.txt @@ -0,0 +1,90 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4077.410808ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4171.605361ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6360.165363ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (234.632892ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (324.526034ms) +✔ bus refusals map to statuses and never carry a path or a stack (97.147284ms) +✔ humanCall speaks the human transport protocol without blocking the server (3296.610593ms) +✔ busReader takes --business, else the live bus host, else refuses (200.071063ms) +✔ humanCall kills a transport that runs past its timeout (531.239533ms) +✔ serve refuses a --business value that is not a business id (248.942733ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3687.313618ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2833.201272ms) +✔ conversation view: a newer session with no readable history keeps the marker (1362.955296ms) +✔ conversation view: seats without history say so and offer no reply (1312.956871ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3962.94978ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54936.686459ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.076275ms) +✔ credential state from the date alone, as the bus states it (0.246157ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2372.18889ms) +✔ queue: a refused read fails closed with the store's text, redacted (1236.786021ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (1913.957919ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (10.401295ms) +✔ business: missing or invalid file refuses with the module's text, redacted (20.742938ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (11.287289ms) +✔ settings: release, board, loopback address, notifier binding name only (660.976777ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3912.86125ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23172.185603ms) +✔ loopback host and board origin fail closed (9.030326ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (127.524467ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (85.092345ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2133.302061ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.187824ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.309728ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.878168ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7525.436297ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2554.399927ms) +✖ Queue, Business and Settings in their five states, with no move button (4568.702371ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2279.896343ms) +✔ the server log names no config path when the system config refuses (211.912045ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 37 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55335.294053 + +✖ failing tests: + +test at tests/views.test.mjs:63:1 +✖ Queue, Business and Settings in their five states, with no move button (4568.702371ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'none' + - 'pm (delivery)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:169:12) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async Test.run (node:internal/test_runner/test:1409:7) + at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: 'none', + expected: 'pm (delivery)', + operator: 'strictEqual', + diff: 'simple' + } + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2279.896343ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + 'none' + - 'pm (delivery), cto (technical)' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:228: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: 'pm (delivery), cto (technical)', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E08.diff b/agents/darkwing/work/queue-54-review/r2/mut/E08.diff new file mode 100644 index 00000000..c7cbefc2 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E08.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..30b7b327 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -381,7 +381,7 @@ + const cmd = `scripts/mosaic queue move ${id} --op --by `; + return `${head(`Row ${esc(id)}: ${txt(r.piece)}`, `${qState(r.state)}${r.previousState ? ` was ${txt(r.previousState)}` : ''} ${readLine()}`)} + ${storeNotes(doc.notes)} +-

    Row

    Owner
    ${txt(r.owner) || none}
    Reviewers
    ${names(r.reviewers)}
    Gate
    ${txt(r.gateOwner) || none}
    Issues
    ${issueRefs(r.issues)}
    Closes
    ${issueRefs(r.closes)}
    Brief
    ${briefRef(r.brief)}${r.brief?.blob ? ` blob ${txt(String(r.brief.blob).slice(0, 12))}` : ''}
    After
    ${Array.isArray(r.after) && r.after.length ? r.after.map(afterRef).join(', ') : none}
    Claim
    ${r.claim ? `${txt(r.claim.seat)} ${txt(r.claim.op)}` : none}
    ${r.required ? `
    Required
    yes${Number.isFinite(Date.parse(r.requiredSince)) ? ` since ${when(r.requiredSince)}` : ''}
    ` : ''}${r.blockedReason ? `
    Blocked
    ${txt(r.blockedReason)}
    ` : ''}${r.note ? `
    Note
    ${txt(r.note)}
    ` : ''}
    Created
    ${when(r.createdAt)}
    Updated
    ${when(r.updatedAt)}${r.updatedBy ? ` by ${txt(r.updatedBy)}` : ''}
    ++

    Row

    Owner
    ${txt(r.owner) || none}
    Reviewers
    ${names(r.reviewers)}
    Gate
    ${txt(r.gateOwner) || none}
    Issues
    ${issueRefs(r.issues)}
    Closes
    ${issueRefs(r.closes)}
    Brief
    ${briefRef(r.brief)}${r.brief?.blob ? ` blob ${txt(String(r.brief.blob).slice(0, 12))}` : ''}
    After
    ${Array.isArray(r.after) && r.after.length ? r.after.map(qLink).join(', ') : none}
    Claim
    ${r.claim ? `${txt(r.claim.seat)} ${txt(r.claim.op)}` : none}
    ${r.required ? `
    Required
    yes${Number.isFinite(Date.parse(r.requiredSince)) ? ` since ${when(r.requiredSince)}` : ''}
    ` : ''}${r.blockedReason ? `
    Blocked
    ${txt(r.blockedReason)}
    ` : ''}${r.note ? `
    Note
    ${txt(r.note)}
    ` : ''}
    Created
    ${when(r.createdAt)}
    Updated
    ${when(r.updatedAt)}${r.updatedBy ? ` by ${txt(r.updatedBy)}` : ''}
    +

    Review ${rounds.length}

    ${rounds.length ? `
      ${rounds.map(round).join('')}
    ` : '

    No review round yet.

    '}
    +

    Moving this row

    ${moveHelp} Copy only puts the command on your clipboard; fill in the state, op and seat before you run it.

    +
    ${txt(cmd)}

    diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E08.txt b/agents/darkwing/work/queue-54-review/r2/mut/E08.txt new file mode 100644 index 00000000..4635ae44 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E08.txt @@ -0,0 +1,70 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3856.905512ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (5475.36895ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6216.718835ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (241.895166ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (106.747958ms) +✔ bus refusals map to statuses and never carry a path or a stack (85.962143ms) +✔ humanCall speaks the human transport protocol without blocking the server (3107.790588ms) +✔ busReader takes --business, else the live bus host, else refuses (159.018046ms) +✔ humanCall kills a transport that runs past its timeout (529.234183ms) +✔ serve refuses a --business value that is not a business id (171.222193ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4726.634398ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2268.5771ms) +✔ conversation view: a newer session with no readable history keeps the marker (1393.091356ms) +✔ conversation view: seats without history say so and offer no reply (797.282953ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3939.317078ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54882.062425ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.218807ms) +✔ credential state from the date alone, as the bus states it (0.306361ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2201.684503ms) +✔ queue: a refused read fails closed with the store's text, redacted (1295.583176ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3057.835948ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (9.49504ms) +✔ business: missing or invalid file refuses with the module's text, redacted (7.216359ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.005679ms) +✔ settings: release, board, loopback address, notifier binding name only (302.327221ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3821.604474ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23144.699461ms) +✔ loopback host and board origin fail closed (7.914685ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (90.078298ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (73.46242ms) +✔ unreachable board reports URL; CLI rejects unsupported options (2125.549948ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.061105ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.238646ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.570488ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7221.583217ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2976.639377ms) +✔ Queue, Business and Settings in their five states, with no move button (5499.676861ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1490.270162ms) +✔ the server log names no config path when the system config refuses (316.204069ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55315.952746 + +✖ failing tests: + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1490.270162ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + '[object Object]' + - '6 settled' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:219: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: '[object Object]', + expected: '6 settled', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E09.diff b/agents/darkwing/work/queue-54-review/r2/mut/E09.diff new file mode 100644 index 00000000..caef35d7 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E09.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..069e36d1 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -381,7 +381,7 @@ + const cmd = `scripts/mosaic queue move ${id} --op --by `; + return `${head(`Row ${esc(id)}: ${txt(r.piece)}`, `${qState(r.state)}${r.previousState ? ` was ${txt(r.previousState)}` : ''} ${readLine()}`)} + ${storeNotes(doc.notes)} +-

    Row

    Owner
    ${txt(r.owner) || none}
    Reviewers
    ${names(r.reviewers)}
    Gate
    ${txt(r.gateOwner) || none}
    Issues
    ${issueRefs(r.issues)}
    Closes
    ${issueRefs(r.closes)}
    Brief
    ${briefRef(r.brief)}${r.brief?.blob ? ` blob ${txt(String(r.brief.blob).slice(0, 12))}` : ''}
    After
    ${Array.isArray(r.after) && r.after.length ? r.after.map(afterRef).join(', ') : none}
    Claim
    ${r.claim ? `${txt(r.claim.seat)} ${txt(r.claim.op)}` : none}
    ${r.required ? `
    Required
    yes${Number.isFinite(Date.parse(r.requiredSince)) ? ` since ${when(r.requiredSince)}` : ''}
    ` : ''}${r.blockedReason ? `
    Blocked
    ${txt(r.blockedReason)}
    ` : ''}${r.note ? `
    Note
    ${txt(r.note)}
    ` : ''}
    Created
    ${when(r.createdAt)}
    Updated
    ${when(r.updatedAt)}${r.updatedBy ? ` by ${txt(r.updatedBy)}` : ''}
    ++

    Row

    Owner
    ${txt(r.owner) || none}
    Reviewers
    ${names(r.reviewers)}
    Gate
    ${txt(r.gateOwner) || none}
    Issues
    ${issueRefs(r.issues)}
    Closes
    ${issueRefs(r.closes)}
    Brief
    ${briefRef(r.brief)}${r.brief?.blob ? ` blob ${txt(String(r.brief.blob).slice(0, 12))}` : ''}
    After
    ${Array.isArray(r.after) && r.after.length ? r.after.map(afterRef).join(', ') : none}
    Claim
    ${r.claim ? `${txt(r.claim.seat)} ${txt(r.claim.op)}` : none}
    ${r.required ? `
    Required
    ${txt(r.required)}${Number.isFinite(Date.parse(r.requiredSince)) ? ` since ${when(r.requiredSince)}` : ''}
    ` : ''}${r.blockedReason ? `
    Blocked
    ${txt(r.blockedReason)}
    ` : ''}${r.note ? `
    Note
    ${txt(r.note)}
    ` : ''}
    Created
    ${when(r.createdAt)}
    Updated
    ${when(r.updatedAt)}${r.updatedBy ? ` by ${txt(r.updatedBy)}` : ''}
    +

    Review ${rounds.length}

    ${rounds.length ? `
      ${rounds.map(round).join('')}
    ` : '

    No review round yet.

    '}
    +

    Moving this row

    ${moveHelp} Copy only puts the command on your clipboard; fill in the state, op and seat before you run it.

    +
    ${txt(cmd)}

    diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E09.txt b/agents/darkwing/work/queue-54-review/r2/mut/E09.txt new file mode 100644 index 00000000..80e5888a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E09.txt @@ -0,0 +1,68 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (2906.740481ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4973.666396ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5473.105297ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (334.048897ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (327.079288ms) +✔ bus refusals map to statuses and never carry a path or a stack (234.902697ms) +✔ humanCall speaks the human transport protocol without blocking the server (2692.782254ms) +✔ busReader takes --business, else the live bus host, else refuses (189.349222ms) +✔ humanCall kills a transport that runs past its timeout (528.782334ms) +✔ serve refuses a --business value that is not a business id (200.451627ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3004.05947ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2660.211565ms) +✔ conversation view: a newer session with no readable history keeps the marker (1503.749625ms) +✔ conversation view: seats without history say so and offer no reply (1233.425272ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (2916.774968ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54091.536195ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.033947ms) +✔ credential state from the date alone, as the bus states it (0.28147ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2484.989631ms) +✔ queue: a refused read fails closed with the store's text, redacted (561.286331ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2528.710274ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (16.345176ms) +✔ business: missing or invalid file refuses with the module's text, redacted (15.327688ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (11.881195ms) +✔ settings: release, board, loopback address, notifier binding name only (489.625053ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (2960.184824ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22990.114665ms) +✔ loopback host and board origin fail closed (8.787566ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (129.900878ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (151.946301ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1974.607268ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.198224ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.409671ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.934324ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7112.046424ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2802.647181ms) +✔ Queue, Business and Settings in their five states, with no move button (4934.634698ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1622.333656ms) +✔ the server log names no config path when the system config refuses (213.419832ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54795.319769 + +✖ failing tests: + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1622.333656ms) + AssertionError [ERR_ASSERTION]: The input did not match the regular expression /^yes( since |$)/. Input: + + 'true' + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:220: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: /^yes( since |$)/, + operator: 'match', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E10.diff b/agents/darkwing/work/queue-54-review/r2/mut/E10.diff new file mode 100644 index 00000000..d4d15da3 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E10.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..50ed0bdf 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -381,7 +381,7 @@ + const cmd = `scripts/mosaic queue move ${id} --op --by `; + return `${head(`Row ${esc(id)}: ${txt(r.piece)}`, `${qState(r.state)}${r.previousState ? ` was ${txt(r.previousState)}` : ''} ${readLine()}`)} + ${storeNotes(doc.notes)} +-

    Row

    Owner
    ${txt(r.owner) || none}
    Reviewers
    ${names(r.reviewers)}
    Gate
    ${txt(r.gateOwner) || none}
    Issues
    ${issueRefs(r.issues)}
    Closes
    ${issueRefs(r.closes)}
    Brief
    ${briefRef(r.brief)}${r.brief?.blob ? ` blob ${txt(String(r.brief.blob).slice(0, 12))}` : ''}
    After
    ${Array.isArray(r.after) && r.after.length ? r.after.map(afterRef).join(', ') : none}
    Claim
    ${r.claim ? `${txt(r.claim.seat)} ${txt(r.claim.op)}` : none}
    ${r.required ? `
    Required
    yes${Number.isFinite(Date.parse(r.requiredSince)) ? ` since ${when(r.requiredSince)}` : ''}
    ` : ''}${r.blockedReason ? `
    Blocked
    ${txt(r.blockedReason)}
    ` : ''}${r.note ? `
    Note
    ${txt(r.note)}
    ` : ''}
    Created
    ${when(r.createdAt)}
    Updated
    ${when(r.updatedAt)}${r.updatedBy ? ` by ${txt(r.updatedBy)}` : ''}
    ++

    Row

    Owner
    ${txt(r.owner) || none}
    Reviewers
    ${names(r.reviewers)}
    Gate
    ${txt(r.gateOwner) || none}
    Issues
    ${issueRefs(r.issues)}
    Closes
    ${issueRefs(r.closes)}
    Brief
    ${briefRef(r.brief)}${r.brief?.blob ? ` blob ${txt(String(r.brief.blob).slice(0, 12))}` : ''}
    After
    ${Array.isArray(r.after) && r.after.length ? r.after.map(afterRef).join(', ') : none}
    Claim
    ${r.claim ? `${txt(r.claim.seat)} ${txt(r.claim.op)}` : none}
    ${r.required ? `
    Required
    yes${r.requiredSince ? ` since ${when(r.requiredSince)}` : ''}
    ` : ''}${r.blockedReason ? `
    Blocked
    ${txt(r.blockedReason)}
    ` : ''}${r.note ? `
    Note
    ${txt(r.note)}
    ` : ''}
    Created
    ${when(r.createdAt)}
    Updated
    ${when(r.updatedAt)}${r.updatedBy ? ` by ${txt(r.updatedBy)}` : ''}
    +

    Review ${rounds.length}

    ${rounds.length ? `
      ${rounds.map(round).join('')}
    ` : '

    No review round yet.

    '}
    +

    Moving this row

    ${moveHelp} Copy only puts the command on your clipboard; fill in the state, op and seat before you run it.

    +
    ${txt(cmd)}

    diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E10.txt b/agents/darkwing/work/queue-54-review/r2/mut/E10.txt new file mode 100644 index 00000000..e4de1668 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E10.txt @@ -0,0 +1,48 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3616.980106ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (3660.989138ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5949.529873ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (781.695493ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (336.486963ms) +✔ bus refusals map to statuses and never carry a path or a stack (167.515827ms) +✔ humanCall speaks the human transport protocol without blocking the server (2477.139016ms) +✔ busReader takes --business, else the live bus host, else refuses (218.463943ms) +✔ humanCall kills a transport that runs past its timeout (558.942622ms) +✔ serve refuses a --business value that is not a business id (194.435163ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3685.671044ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2898.806207ms) +✔ conversation view: a newer session with no readable history keeps the marker (1408.156807ms) +✔ conversation view: seats without history say so and offer no reply (1278.383289ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3465.827892ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54715.651325ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (1.906711ms) +✔ credential state from the date alone, as the bus states it (2.48486ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2492.569641ms) +✔ queue: a refused read fails closed with the store's text, redacted (1078.093433ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2515.949704ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.841988ms) +✔ business: missing or invalid file refuses with the module's text, redacted (143.951841ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.545556ms) +✔ settings: release, board, loopback address, notifier binding name only (178.175074ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3562.830873ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22389.648835ms) +✔ loopback host and board origin fail closed (9.000085ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (151.76069ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (413.917858ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1882.086271ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.293433ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.230358ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.561316ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7591.926402ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2569.169226ms) +✔ Queue, Business and Settings in their five states, with no move button (5271.25471ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2374.300294ms) +✔ the server log names no config path when the system config refuses (264.645827ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 39 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 55236.597902 diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E11.diff b/agents/darkwing/work/queue-54-review/r2/mut/E11.diff new file mode 100644 index 00000000..588730a2 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E11.diff @@ -0,0 +1,12 @@ +diff --git a/packages/webui/src/reads.mjs b/packages/webui/src/reads.mjs +index 01224d15..0060886d 100644 +--- a/packages/webui/src/reads.mjs ++++ b/packages/webui/src/reads.mjs +@@ -199,7 +199,6 @@ export function consoleReads({ root, system = null, configDir = null, rolesDir, + let id = null, notifier; + try { + id = businessId({ business, dataRoot }); +- if (!dataRoot) throw new ReadError('not-configured', 'the Console has no system config, so it knows no notifier config'); + notifier = { binding: readNotifyConfig(dataRoot, id) }; + } catch (err) { + notifier = { refused: err instanceof ReadError ? err.code : 'not-configured', message: err.message }; diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E11.txt b/agents/darkwing/work/queue-54-review/r2/mut/E11.txt new file mode 100644 index 00000000..4fff4286 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E11.txt @@ -0,0 +1,73 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4822.930259ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4906.180041ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5297.173253ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (223.878341ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (107.391341ms) +✔ bus refusals map to statuses and never carry a path or a stack (75.159927ms) +✔ humanCall speaks the human transport protocol without blocking the server (2358.682472ms) +✔ busReader takes --business, else the live bus host, else refuses (255.202773ms) +✔ humanCall kills a transport that runs past its timeout (544.742006ms) +✔ serve refuses a --business value that is not a business id (173.39112ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4876.075008ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (1803.654173ms) +✔ conversation view: a newer session with no readable history keeps the marker (1821.439895ms) +✔ conversation view: seats without history say so and offer no reply (1149.941427ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4803.794434ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53903.309626ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (6.491398ms) +✔ credential state from the date alone, as the bus states it (0.265801ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1355.269881ms) +✔ queue: a refused read fails closed with the store's text, redacted (777.26881ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3261.915148ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (12.524282ms) +✔ business: missing or invalid file refuses with the module's text, redacted (7.871492ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.637237ms) +✖ settings: release, board, loopback address, notifier binding name only (340.547186ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4934.323484ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23090.237373ms) +✔ loopback host and board origin fail closed (9.603177ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (123.455381ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (158.397118ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1037.385946ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.43279ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.596386ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.831365ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8012.78546ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2567.614231ms) +✔ Queue, Business and Settings in their five states, with no move button (5785.255819ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1932.619269ms) +✔ the server log names no config path when the system config refuses (211.972681ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54368.703794 + +✖ failing tests: + +test at tests/reads.test.mjs:171:1 +✖ settings: release, board, loopback address, notifier binding name only (340.547186ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: + + actual - expected + + { + + message: 'The "path" argument must be of type string. Received null', + - message: 'the Console has no system config, so it knows no notifier config', + refused: 'not-configured' + } + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/reads.test.mjs:197:10) + 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: { refused: 'not-configured', message: 'The "path" argument must be of type string. Received null' }, + expected: { refused: 'not-configured', message: 'the Console has no system config, so it knows no notifier config' }, + operator: 'deepStrictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E12.diff b/agents/darkwing/work/queue-54-review/r2/mut/E12.diff new file mode 100644 index 00000000..d8a5984b --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E12.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/queue-read.mjs b/packages/webui/src/queue-read.mjs +index ae7e4509..33872c00 100644 +--- a/packages/webui/src/queue-read.mjs ++++ b/packages/webui/src/queue-read.mjs +@@ -15,7 +15,7 @@ try { + const r = rows({}); + process.stdout.write(`${JSON.stringify({ rows: r.rows, notes: r.err })}\n`); + } catch (err) { +- const refused = QueueError !== null && err instanceof QueueError; ++ const refused = err instanceof QueueError; + process.stderr.write(`${refused ? err.message : 'the queue read failed'}\n`); + process.exitCode = refused && Number.isInteger(err.code) && err.code > 0 ? err.code : 1; + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E12.txt b/agents/darkwing/work/queue-54-review/r2/mut/E12.txt new file mode 100644 index 00000000..5b9d421a --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E12.txt @@ -0,0 +1,48 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (3888.787759ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (3951.652781ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5720.761076ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (291.120519ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (95.355614ms) +✔ bus refusals map to statuses and never carry a path or a stack (58.784858ms) +✔ humanCall speaks the human transport protocol without blocking the server (2113.471315ms) +✔ busReader takes --business, else the live bus host, else refuses (204.506365ms) +✔ humanCall kills a transport that runs past its timeout (529.882927ms) +✔ serve refuses a --business value that is not a business id (194.190736ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (3869.638938ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3065.320252ms) +✔ conversation view: a newer session with no readable history keeps the marker (1639.493943ms) +✔ conversation view: seats without history say so and offer no reply (1074.445443ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (3722.111983ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54023.590411ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.775438ms) +✔ credential state from the date alone, as the bus states it (0.274238ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1277.909783ms) +✔ queue: a refused read fails closed with the store's text, redacted (1059.090152ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2350.726333ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.882718ms) +✔ business: missing or invalid file refuses with the module's text, redacted (57.294982ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.802986ms) +✔ settings: release, board, loopback address, notifier binding name only (880.371502ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (3653.180772ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22968.27856ms) +✔ loopback host and board origin fail closed (8.921972ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (129.379872ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (120.66428ms) +✔ unreachable board reports URL; CLI rejects unsupported options (990.201382ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.094147ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.145454ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.782519ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8085.779717ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2519.880683ms) +✔ Queue, Business and Settings in their five states, with no move button (5631.08048ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2442.264334ms) +✔ the server log names no config path when the system config refuses (268.674699ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 39 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54428.872021 diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E13.diff b/agents/darkwing/work/queue-54-review/r2/mut/E13.diff new file mode 100644 index 00000000..c14910ca --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E13.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..5be64e1b 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -349,7 +349,7 @@ + const afterRef = a => a && typeof a === 'object' ? `${qLink(a.id)}${a.when ? ` ${txt(a.when)}` : ''}` : qLink(a); + const names = list => Array.isArray(list) && list.length ? list.map(txt).join(', ') : none; + // The business file's arbiters are {delivery, technical}, each a role instance: "pm (delivery)". +- const arbiterRefs = a => a && typeof a === 'object' && !Array.isArray(a) ? Object.entries(a).map(([kind, who]) => `${txt(who)} (${txt(kind)})`).join(', ') || none : names(a); ++ const arbiterRefs = a => a && typeof a === 'object' && !Array.isArray(a) ? Object.entries(a).map(([kind, who]) => `${txt(who)} (${txt(kind)})`).join(', ') : names(a); + const issueRefs = list => Array.isArray(list) && list.length ? list.map(n => `#${txt(n)}`).join(', ') : none; + // Console serves no repository files, so the brief is its path and anchor, as the row names it. + const briefRef = b => b?.path ? `${txt(b.path)}${b.anchor ? `#${txt(b.anchor)}` : ''}` : none; diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E13.txt b/agents/darkwing/work/queue-54-review/r2/mut/E13.txt new file mode 100644 index 00000000..a2c09f48 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E13.txt @@ -0,0 +1,48 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4322.024674ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4666.375347ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (6140.987084ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (386.903021ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (492.311386ms) +✔ bus refusals map to statuses and never carry a path or a stack (196.246538ms) +✔ humanCall speaks the human transport protocol without blocking the server (2460.30512ms) +✔ busReader takes --business, else the live bus host, else refuses (271.777808ms) +✔ humanCall kills a transport that runs past its timeout (528.687229ms) +✔ serve refuses a --business value that is not a business id (219.591729ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4230.473238ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2158.338311ms) +✔ conversation view: a newer session with no readable history keeps the marker (1498.488241ms) +✔ conversation view: seats without history say so and offer no reply (1012.482769ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4913.673987ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (54314.8181ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.230514ms) +✔ credential state from the date alone, as the bus states it (0.284803ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2348.605136ms) +✔ queue: a refused read fails closed with the store's text, redacted (1248.777503ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (2560.261871ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (8.787973ms) +✔ business: missing or invalid file refuses with the module's text, redacted (12.51772ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (10.980412ms) +✔ settings: release, board, loopback address, notifier binding name only (229.462411ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4934.616438ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22092.124864ms) +✔ loopback host and board origin fail closed (8.699044ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (122.191795ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (93.141873ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1884.047098ms) +✔ tokens.css and icons.svg are byte copies of docs/design (0.949058ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (1.951111ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.630552ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (7340.548052ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2563.706796ms) +✔ Queue, Business and Settings in their five states, with no move button (5795.365193ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (2010.024848ms) +✔ the server log names no config path when the system config refuses (213.678201ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 39 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54746.741731 diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E14.diff b/agents/darkwing/work/queue-54-review/r2/mut/E14.diff new file mode 100644 index 00000000..4e4cdcae --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E14.diff @@ -0,0 +1,13 @@ +diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js +index affb9b7b..b3ffca18 100644 +--- a/packages/webui/src/public/bus.js ++++ b/packages/webui/src/public/bus.js +@@ -346,7 +346,7 @@ + const qState = s => badge(s, QSTATE[s] || 'muted'); + const qLink = id => Number.isInteger(id) ? `${esc(id)}` : txt(id); + // An after entry is {id, when}, as QUEUE.md writes it: "53 done". +- const afterRef = a => a && typeof a === 'object' ? `${qLink(a.id)}${a.when ? ` ${txt(a.when)}` : ''}` : qLink(a); ++ const afterRef = a => a && typeof a === 'object' ? `${qLink(a.id)}` : qLink(a); + const names = list => Array.isArray(list) && list.length ? list.map(txt).join(', ') : none; + // The business file's arbiters are {delivery, technical}, each a role instance: "pm (delivery)". + const arbiterRefs = a => a && typeof a === 'object' && !Array.isArray(a) ? Object.entries(a).map(([kind, who]) => `${txt(who)} (${txt(kind)})`).join(', ') || none : names(a); diff --git a/agents/darkwing/work/queue-54-review/r2/mut/E14.txt b/agents/darkwing/work/queue-54-review/r2/mut/E14.txt new file mode 100644 index 00000000..ec03531e --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/E14.txt @@ -0,0 +1,71 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (4523.703633ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (4893.533021ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (5350.033243ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (211.332362ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (109.693508ms) +✔ bus refusals map to statuses and never carry a path or a stack (58.412189ms) +✔ humanCall speaks the human transport protocol without blocking the server (2355.503452ms) +✔ busReader takes --business, else the live bus host, else refuses (337.597753ms) +✔ humanCall kills a transport that runs past its timeout (528.025656ms) +✔ serve refuses a --business value that is not a business id (240.95955ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (4515.146794ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (2182.194444ms) +✔ conversation view: a newer session with no readable history keeps the marker (1533.719937ms) +✔ conversation view: seats without history say so and offer no reply (1266.534823ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (4503.163848ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (53927.193787ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (2.126954ms) +✔ credential state from the date alone, as the bus states it (1.182791ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (1376.292615ms) +✔ queue: a refused read fails closed with the store's text, redacted (1008.274679ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (3284.956445ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (9.314001ms) +✔ business: missing or invalid file refuses with the module's text, redacted (6.446331ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (7.121053ms) +✔ settings: release, board, loopback address, notifier binding name only (365.664886ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (4499.700499ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (22665.27668ms) +✔ loopback host and board origin fail closed (8.266721ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (113.658913ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (99.996806ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1337.376123ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.262345ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.414247ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (1.899269ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8002.040069ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (2577.38598ms) +✔ Queue, Business and Settings in their five states, with no move button (5376.477477ms) +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1313.394907ms) +✔ the server log names no config path when the system config refuses (264.116342ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 38 +ℹ fail 1 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 54351.573732 + +✖ failing tests: + +test at tests/views.test.mjs:205:1 +✖ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (1313.394907ms) + AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + + actual - expected + + + '6' + - '6 settled' + ^ + + at TestContext. (file:///home/jwoltje/darkwing-scratch/r54b/mutwt/packages/webui/tests/views.test.mjs:219: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: '6', + expected: '6 settled', + operator: 'strictEqual', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-54-review/r2/mut/manifest-after.txt b/agents/darkwing/work/queue-54-review/r2/mut/manifest-after.txt new file mode 100644 index 00000000..832e0ccd --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/manifest-after.txt @@ -0,0 +1,14 @@ +packages/queue/README.md: OK +packages/queue/src/store.mjs: OK +packages/queue/tests/write.test.mjs: OK +packages/webui/README.md: OK +packages/webui/src/cli.mjs: OK +packages/webui/src/public/app.js: OK +packages/webui/src/public/bus.js: OK +packages/webui/src/queue-read.mjs: OK +packages/webui/src/reads.mjs: OK +packages/webui/src/serve.mjs: OK +packages/webui/tests/reads-fixture.mjs: OK +packages/webui/tests/reads.test.mjs: OK +packages/webui/tests/shell.test.mjs: OK +packages/webui/tests/views.test.mjs: OK diff --git a/agents/darkwing/work/queue-54-review/r2/mut/mutate.py b/agents/darkwing/work/queue-54-review/r2/mut/mutate.py new file mode 100644 index 00000000..c8fbb371 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/mutate.py @@ -0,0 +1,70 @@ +# Row 54 round 2 mutants: D01 to D31 from round 1 (D07 on the new redactor), E01 on for round 2's changes: exact text, must match once. Run from the worktree root. +import sys +A = "packages/webui/src/public/app.js" +B = "packages/webui/src/public/bus.js" +R = "packages/webui/src/reads.mjs" +V = "packages/webui/src/serve.mjs" +C = "packages/webui/src/cli.mjs" +Q = "packages/queue/src/store.mjs" +QR = "packages/webui/src/queue-read.mjs" +M = { + # my four items + "D01": [(B, " clearTimeout(timer);\n const route = routeOf()", " const route = routeOf()")], + "D02": [(B, ", h1: view.contains(a) && a.tagName === 'H1'", "")], + "D03": [(B, " else if (k.h1) $('bus-view').querySelector('h1')?.focus({ preventScroll: true });\n", "")], + "D04": [(A, " $('conv-pick').replaceChildren();", "")], + "D05": [(A, " if (focused && document.activeElement === document.body) $('main').focus();\n", "")], + "D06": [(A, "if (focused && document.activeElement === document.body)", "if (document.activeElement === document.body)")], + # redaction and projection + "D07": [(R, r"""return s.replace(/(^|[\s('"`=,[{<]|:(?!\/\/[^/]))~?\/[^\s'"`),;\]}>]+/g, '$1').replace(""", "return s.replace(")], + "D08": [(R, r""".replace(/(?')""", "")], + "D09": [(R, "let s = unquote(String(text));", "let s = String(text);")], + "D10": [(R, "for (const [re, label] of known) s = s.replace(re, label);", "")], + "D11": [(R, "return scrub({ rows: doc.rows.map(queueSummary), notes: doc.notes, at: new Date(now()).toISOString() }, redact);", "return { rows: doc.rows.map(queueSummary), notes: doc.notes, at: new Date(now()).toISOString() };")], + "D12": [(R, "return scrub({ row, notes: doc.notes, at: new Date(now()).toISOString() }, redact);", "return { row, notes: doc.notes, at: new Date(now()).toISOString() };")], + "D13": [(R, "vars: pick(b.vars, VAR_KEYS)", "vars: b.vars")], + "D14": [(R, "vars: pick(r.vars, AGENT_KEYS)", "vars: r.vars")], + "D15": [(R, "return { service, account, role, dateKind, date, state: credentialState(service, date, now) };", "return { ...ref, service, account, role, dateKind, date, state: credentialState(service, date, now) };")], + "D16": [(R, "const fail = (code, message) => new ReadError(code, redact(message));", "const fail = (code, message) => new ReadError(code, message);")], + "D17": [(R, "return scrub({ release, business: id, notifier, at: new Date(now()).toISOString() }, redact);", "return { release, business: id, notifier, at: new Date(now()).toISOString() };")], + "D18": [(C, "(${redactor({ configDir: configDir() })(err.message)})", "(${err.message})")], + # queue child + "D19": [(R, "if (status === 2) return", "if (status === 3) return")], + "D20": [(R, "if (size > maxBytes) {", "if (false) {")], + "D21": [(R, "}, timeoutMs);", "}, timeoutMs * 1000);")], + "D22": [(R, "if (!state?.live) throw", "if (!state) throw")], + # routes + "D23": [(V, " if (req.method !== 'GET') return json(res, 405, { error: 'method not allowed' });\n const a = server.address()", " const a = server.address()")], + "D24": [(V, r"const QUEUE_ID = /^[1-9]\d{0,5}$/;", r"const QUEUE_ID = /^\d+$/;")], + "D25": [(V, " if (!reads) return json(res, 503, { error: 'not-configured', message: 'the Console has no reads configured' });\n", "")], + # views + "D26": [(B, "['not-configured', 'no-bus-host', 'queue-refused'].includes(err.code)", "['not-configured', 'no-bus-host'].includes(err.code)")], + "D27": [(B, "html = failedView(err) + (path === '/settings' ? appearance() : '');", "html = failedView(err);")], + "D28": [(B, "...decisions, ...tasks, ...rows];", "...decisions, ...tasks];")], + "D29": [(B, ", mirror: view.contains(a) ? a.dataset?.mirror : null", "")], + "D30": [(B, "if (m) { const src = $(m.dataset.mirror); src.value = m.value; src.dispatchEvent(new Event('change')); return; }", "if (m) return;")], + # store + "D31": [(Q, "return { rows: rowsArray(r.state), err: r.notes, code: 0 };", "return { rows: rowsArray(r.state), err: [], code: 0 };")], + # round 2 changes + "E01": [(QR, "let QueueError = null;\n", "import { rows } from '../../queue/src/store.mjs';\nimport { QueueError as QE } from '../../queue/src/errors.mjs';\nlet QueueError = QE;\n"), + (QR, " ({ QueueError } = await import('../../queue/src/errors.mjs'));\n const { rows } = await import('../../queue/src/store.mjs');\n", "")], + "E02": [(R, "new ReadError('read-failed', `the queue read failed (exit ${status})`)", "new ReadError('read-failed', said || `the queue read failed (exit ${status})`)")], + "E03": [(R, r"""|:(?!\/\/[^/]))~?\/""", r""")~?\/""")], + "E04": [(R, r""":(?!\/\/[^/])""", ":")], + "E05": [(R, r"""~?\/[^\s'""", r"""\/[^\s'""")], + "E06": [(R, r"""[\s('"`=,[{<]|""", r"""[\s('"`=,[{]|""")], + "E07": [(B, "
    ${arbiterRefs(b.arbiters)}
    ", "
    ${names(b.arbiters)}
    ")], + "E08": [(B, "r.after.map(afterRef)", "r.after.map(qLink)")], + "E09": [(B, "
    yes${Number.isFinite", "
    ${txt(r.required)}${Number.isFinite")], + "E10": [(B, "Number.isFinite(Date.parse(r.requiredSince))", "r.requiredSince")], + "E11": [(R, " if (!dataRoot) throw new ReadError('not-configured', 'the Console has no system config, so it knows no notifier config');\n", "")], + "E12": [(QR, "const refused = QueueError !== null && err instanceof QueueError;", "const refused = err instanceof QueueError;")], + "E13": [(B, ".join(', ') || none : names(a);", ".join(', ') : names(a);")], + "E14": [(B, "${a.when ? ` ${txt(a.when)}` : ''}", "")], +} +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-54-review/r2/mut/run.sh b/agents/darkwing/work/queue-54-review/r2/mut/run.sh new file mode 100755 index 00000000..141566da --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/run.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Each mutant against its package suite in a candidate worktree, then restores from the index. +export TMPDIR=~/darkwing-scratch/r54b/tmp +S=~/darkwing-scratch/r54b; M=$S/r2/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"\"([DE]\d\d)\"", open("'$M'/mutate.py").read())))))'); do + (cd $W && git checkout -q -- packages/webui packages/queue && python3 $M/mutate.py $v > /dev/null && git diff > $M/$v.diff) || { echo "$v APPLY-FAILED" >> $M/summary.txt; continue; } + pkg=webui; [ $v = D31 ] && pkg=queue + (cd $W/packages/$pkg && 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 packages/queue && 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-54-review/r2/mut/sites.sh b/agents/darkwing/work/queue-54-review/r2/mut/sites.sh new file mode 100755 index 00000000..f31233cf --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/sites.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Prints each mutant's result and the test lines its failures point at. +M=~/darkwing-scratch/r54b/r2/mut +grep -E '^[DE][0-9][0-9] ' $M/summary.txt | while read -r id res rest; do + sites=$(sed -n '/failing tests:/,$p' $M/$id.txt | grep -oE 'tests/[a-z0-9-]+\.test\.mjs:[0-9]+' | grep -v ':1$' | sort -u | tr '\n' ' ') + names=$(sed -n '/failing tests:/,$p' $M/$id.txt | grep -E '^✖ ' | grep -v 'failing tests' | sed -E 's/^✖ //; s/ \([0-9.]+ms\)$//' | sort -u | tr '\n' '|') + echo "$id $res | $sites| $names" +done diff --git a/agents/darkwing/work/queue-54-review/r2/mut/summary.txt b/agents/darkwing/work/queue-54-review/r2/mut/summary.txt new file mode 100644 index 00000000..b2619bd6 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/mut/summary.txt @@ -0,0 +1,48 @@ +start 2026-10-10T21:22:02Z +D01 killed exit=1 ℹ pass 38 ℹ fail 1 +D02 killed exit=1 ℹ pass 38 ℹ fail 1 +D03 killed exit=1 ℹ pass 38 ℹ fail 1 +D04 killed exit=1 ℹ pass 38 ℹ fail 1 +D05 killed exit=1 ℹ pass 38 ℹ fail 1 +D06 killed exit=1 ℹ pass 38 ℹ fail 1 +D07 killed exit=1 ℹ pass 35 ℹ fail 4 +D08 killed exit=1 ℹ pass 36 ℹ fail 3 +D09 killed exit=1 ℹ pass 38 ℹ fail 1 +D10 killed exit=1 ℹ pass 35 ℹ fail 4 +D11 killed exit=1 ℹ pass 37 ℹ fail 2 +D12 killed exit=1 ℹ pass 38 ℹ fail 1 +D13 killed exit=1 ℹ pass 37 ℹ fail 2 +D14 SURVIVED exit=0 ℹ pass 39 ℹ fail 0 +D15 killed exit=1 ℹ pass 37 ℹ fail 2 +D16 killed exit=1 ℹ pass 37 ℹ fail 2 +D17 killed exit=1 ℹ pass 38 ℹ fail 1 +D18 killed exit=1 ℹ pass 38 ℹ fail 1 +D19 killed exit=1 ℹ pass 37 ℹ fail 2 +D20 killed exit=1 ℹ pass 38 ℹ fail 1 +D21 killed exit=1 ℹ pass 38 ℹ fail 0 +D22 SURVIVED exit=0 ℹ pass 39 ℹ fail 0 +D23 killed exit=1 ℹ pass 38 ℹ fail 1 +D24 killed exit=1 ℹ pass 38 ℹ fail 1 +D25 killed exit=1 ℹ pass 38 ℹ fail 1 +D26 killed exit=1 ℹ pass 38 ℹ fail 1 +D27 killed exit=1 ℹ pass 38 ℹ fail 1 +D28 killed exit=1 ℹ pass 38 ℹ fail 1 +D29 killed exit=1 ℹ pass 38 ℹ fail 1 +D30 killed exit=1 ℹ pass 38 ℹ fail 1 +D31 killed exit=1 ℹ pass 148 ℹ fail 1 +E01 killed exit=1 ℹ pass 38 ℹ fail 1 +E02 killed exit=1 ℹ pass 38 ℹ fail 1 +E03 killed exit=1 ℹ pass 36 ℹ fail 3 +E04 killed exit=1 ℹ pass 37 ℹ fail 2 +E05 killed exit=1 ℹ pass 36 ℹ fail 3 +E06 killed exit=1 ℹ pass 38 ℹ fail 1 +E07 killed exit=1 ℹ pass 37 ℹ fail 2 +E08 killed exit=1 ℹ pass 38 ℹ fail 1 +E09 killed exit=1 ℹ pass 38 ℹ fail 1 +E10 SURVIVED exit=0 ℹ pass 39 ℹ fail 0 +E11 killed exit=1 ℹ pass 38 ℹ fail 1 +E12 SURVIVED exit=0 ℹ pass 39 ℹ fail 0 +E13 SURVIVED exit=0 ℹ pass 39 ℹ fail 0 +E14 killed exit=1 ℹ pass 38 ℹ fail 1 +end 2026-10-10T22:07:37Z +DONE diff --git a/agents/darkwing/work/queue-54-review/r2/out/build-tokens.txt b/agents/darkwing/work/queue-54-review/r2/out/build-tokens.txt new file mode 100644 index 00000000..20cb200f --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/out/build-tokens.txt @@ -0,0 +1 @@ +tokens.css is current diff --git a/agents/darkwing/work/queue-54-review/r2/out/node-business.txt b/agents/darkwing/work/queue-54-review/r2/out/node-business.txt new file mode 100644 index 00000000..be433cd2 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/out/node-business.txt @@ -0,0 +1,68 @@ +✔ config directory and file path follow MOSAIC_CONFIG (1.358293ms) +✔ the fixture business validates and comes back frozen (4.319109ms) +✔ two instances may share a definition (1.396227ms) +✔ top-level refusals (4.055262ms) +✔ arbiters and projects (7.498012ms) +✔ role instances (3.986412ms) +✔ Vikunja bots (8.432332ms) +✔ a role without Vikunja takes no tracker block (3.583648ms) +✔ credential references match the definition's services (3.569963ms) +✔ launch (9.358031ms) +✔ loadBusiness: file checks (1.91489ms) +✔ loadBusiness: not a regular file (41.934608ms) +✔ loading writes nothing (1.116741ms) +✔ names that are Object.prototype properties don't count as declared (2.823344ms) +✔ the shipped example refuses as written and validates once filled in (0.554849ms) +✔ usage errors exit 4 (280.926956ms) +✔ validate: a good business exits 0 and prints instance digests (60.874599ms) +✔ validate: project files (309.472006ms) +✔ validate: missing files and a broken system config (240.996764ms) +✔ validate: credential reference problems exit 2 and name each one (63.782088ms) +✔ validate: a token file inside the repository is refused (64.100441ms) +✔ validate: role definitions come from MOSAIC_ROLES_DIR (199.841638ms) +✔ resolve: prints one instance's record (195.243118ms) +✔ resolve: refusals (391.947059ms) +✔ parse: exactly one of file or env, plus the service's date (2.48624ms) +✔ check: a good file has no problems (0.818496ms) +✔ check never opens the file: a write-only token passes (0.334117ms) +✔ check: file problems (0.873893ms) +✔ check: token files can't live in the repository or dataRoot, even through a linked directory (0.812928ms) +✔ check: dates and environment references (0.525454ms) +✔ path and load (2.561329ms) +✔ refusals (1.291396ms) +✔ systemVars flattens the validated config (1.952187ms) +✔ precedence: system, business, project, project role, agent (6.651473ms) +✔ limits narrow the definition and never widen it (2.836445ms) +✔ role.launch stays within-role only for the instance the launch block names (5.06657ms) +✔ limits.authority without role.launch leaves the launcher with no launch block (2.441279ms) +✔ limits.authority narrows cross-role actions too (1.426583ms) +✔ classify (1.598098ms) +✔ the record carries what the broker and launcher need (1.419734ms) +✔ digest: key order doesn't matter, any value change does (18.247732ms) +✔ refusals (2.333964ms) +✔ the four shipped version 2 roles load (3.985346ms) +✔ shipped role scopes match addendum B section 2 and the SR runbook (1.378316ms) +✔ shipped authority follows the note's table (0.770182ms) +✔ version 1 files keep loading with no authority (1.288688ms) +✔ the conductor policy isn't a role (0.298652ms) +✔ a missing role file is exit 4, a symbolic link too (0.519974ms) +✔ version 2 refusals (2.025378ms) +✔ authority: closed vocabulary, no gated-only action, no overlap (2.901348ms) +✔ credentials: Gitea scopes (1.426595ms) +✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (1.586912ms) +✔ credentials: services (0.786069ms) +✔ contract: a non-empty regular Markdown file beside the role file (0.765377ms) +✔ every key names known layers and a merge rule (1.091141ms) +✔ unknown keys and wrong layers refuse (0.703586ms) +✔ types (1.723076ms) +✔ merge: defaults, then the most specific layer wins (0.270166ms) +✔ merge: limits only narrow, and provenance lists each source (0.323513ms) +✔ merge doesn't change its inputs (0.12932ms) +ℹ tests 60 +ℹ suites 0 +ℹ pass 60 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 1880.166622 diff --git a/agents/darkwing/work/queue-54-review/r2/out/node-queue.txt b/agents/darkwing/work/queue-54-review/r2/out/node-queue.txt new file mode 100644 index 00000000..55f18405 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/out/node-queue.txt @@ -0,0 +1,159 @@ +✔ F1: an ordinary commit after update-ref is refused until step 8; then it commits and the queue stays at C (1706.172781ms) +✔ F1: a plain `commit -e` whose guard ran before update-ref fails at its own HEAD update (1286.359657ms) +ℹ git commit -e: index.lock free during the editor +✔ F1: a `commit -e -- path` whose guard ran before update-ref fails at its own HEAD update (1241.840481ms) +ℹ git commit -e -- src.txt: index.lock held during the editor +✔ F1: step 8 with index.lock held exits 3, and ordinary commits stay refused until the printed command runs (1297.494888ms) +✔ F1: HEAD moving after the step-7 guard check and before update-ref: refused, nothing published (1245.085287ms) +✔ F1: H is recorded before the canary, so HEAD moving during the step-1 canary is refused at step 7 (1247.854944ms) +✔ F1: a queue commit landing after H is recorded: step 1 says HEAD moved, not the guard (1695.611309ms) +✔ F1: a queue commit landing between the HEAD check and the canary: the failed clean run is reported as HEAD moved (1292.930871ms) +✔ F1: a shared-index change during the procedure is not committed (1256.919569ms) +✔ F1: a queue path staged after update-ref: step 8 stops and touches nothing (1255.561012ms) +✔ F1: a missing or a different hook refuses (906.609279ms) +✔ F1: same bytes without the exec bit, a symlinked hook, and core.hooksPath in the local or global scope each refuse before update-ref (4859.566789ms) +✔ F1: the canary refuses a hook that git would not run (1511.922455ms) +✔ F1: the guard deactivated after step 1 is refused at the step-7 recheck (1565.127039ms) +✔ bootstrap: implementation-only HEAD, the guard, genesis, the --genesis commit, then an extending commit (1373.944257ms) +✔ bootstrap: --genesis with a base present, no base without --genesis, an op before the first commit, a changed map, another branch (1303.326184ms) +✔ bootstrap: the archived tests and validator run outside any repository (1095.80342ms) +✔ general: an unrelated staged file stays staged, and the committed blobs are the snapshot bytes (986.911079ms) +✔ general: a queue write after the snapshot is not committed (1456.064641ms) +✔ general: a snapshot whose log does not extend the base refuses (1018.585156ms) +✔ general: install-hook privilege, repair of a same-bytes hook, and its refusals (157.799269ms) +✔ general: environment overrides, a linked worktree and usage (681.538055ms) +✔ general: a queue path staged before the run refuses at step 1 (700.427566ms) +✔ general: HEAD's queue tests failing in the archive refuse (1091.531507ms) +✔ genesis document serializes deterministically and replays (4.714347ms) +✔ a hand edit that stays valid JSON fails replay; a formatting-only edit fails re-serialization (3.134875ms) +✔ a tampered result, receipt or viewSha fails replay (3.554262ms) +✔ op ids: 8 to 72 characters for callers, 80 in the log for .outcome entries (0.21945ms) +✔ add: defaults for an ordinary seat, privileged extras, refusals (5.927961ms) +✔ matrix: queued→briefed privileged; briefed→in-progress owner with after satisfied (8.269384ms) +✔ matrix: release, review round, changes requested and waiting-on-jason (16.848162ms) +✔ matrix J5: in-review→done by the gate owner with evidence naming the current round (12.104397ms) +✔ review issue, lead decision 23: none refuses, one is used, several need --issue, later rounds keep it (31.412102ms) +✔ the row schema refuses a round with a null issue, and the A1 review shape (P2) (3.765794ms) +✔ matrix R1: every state × target × actor class matches 8.7, gate owner jason or not, required or not (1951.538792ms) +✔ matrix: blocked keeps the claim and returns only to previousState (4.328121ms) +✔ matrix J4: parking is Jason's, refused while required; unpark returns to queued (2.794808ms) +✔ field edits: who may change what (5.753757ms) +✔ set issues keeps a logged narrowing of closes (N10) (3.220109ms) +✔ text the table shows refuses \ and <, everywhere it enters (N8) (2.09099ms) +✔ every accepted text renders to nine cells on every row (N8) (30.500822ms) +✔ genesis: the map refuses an owner among its row's reviewers; replay doesn't (2026-10-04) (0.604006ms) +✔ times and dates must be calendar values, not just the shape (2026-10-04) (1.779968ms) +✔ replay holds every op id to the caller's rule (N11) (7.113606ms) +✔ note: owner, listed reviewer or privileged; empty clears (1.540375ms) +✔ assign moves the claim with the owner; done clears it (2.812568ms) +✔ render is byte-stable and escapes pipes (0.538688ms) +✔ view classification: current, genuine stale, edited stale marker, changed current body, markers (0.692321ms) +✔ next: resume, then review, then start, then wait, then nothing; lowest id first (17.828541ms) +✔ canonical args make a retry's identity independent of list order (0.308093ms) +✔ manifests, headings and blob ids (0.412858ms) +✔ the migration map: one queue-map block, exact keys (0.552853ms) +✔ every call but `queue` reaches the seat CLI exactly as before A2 (804.147865ms) +✔ `queue` reaches the queue CLI with the rest of the arguments (295.722132ms) +✔ the pre-A2 fixture is the script A2 changed (0.470191ms) +✔ acquire publishes the record by link; release removes only its own lock (14.890177ms) +✔ a kill between the temp write and the link leaves no lock (65.73674ms) +✔ a short or failed temp write refuses and leaves no lock and no temp (10.501895ms) +✔ a link error other than EEXIST refuses (10.166399ms) +✔ an error after the link releases the lock: unreadable gate, failing temp stat (22.229286ms) +✔ a release that fails on a gate path is reported, never a stack trace (P1) (28.664565ms) +✔ a paused holder: another writer waits 10 s, then refuses naming it live (10139.893336ms) +✔ two concurrent unlockers: the second refuses on the gate (54.781002ms) +✔ a writer publishing during an unlock, lock first: unlock sees it live and refuses (70.240457ms) +✔ a writer publishing during an unlock, gate first: the writer releases and refuses (87.401918ms) +✔ a gate swapped while held is left in place and reported, on success and on refusal (N1) (82.533562ms) +✔ a reused pid within one boot is mismatch; unlock removes the lock and never signals the process (26.135671ms) +✔ the same pid and start on a different boot is mismatch (0.461054ms) +✔ a foreign host is unknown whatever the local pid says; unlock refuses (110.488811ms) +✔ unreadable /proc: classification is unknown and acquire refuses (0.749191ms) +✔ invalid records: empty, unparsable, wrong keys, bad start or boot (0.208151ms) +✔ a stale gate blocks writers; --check-gate says mismatch for a reused pid (33.269405ms) +✔ a delayed release by a dead owner, after unlock and a new owner: the inode check keeps the new lock (32.334008ms) +✔ release checks the inode too: a byte-identical lock file with a new inode is left in place (15.667112ms) +✔ unlock refuses a live, unknown or invalid lock, and does nothing without one (52.241849ms) +✔ the migration map validates and renders the golden genesis table (4.663539ms) +✔ the marked QUEUE.md holds every row and parked item between its markers (1.591298ms) +✔ map-check reports each kind of drift (5.444821ms) +✔ a request posts once as the requester; a retry sends nothing (1064.346952ms) +✔ each transport answer maps to posted, failed or uncertain (8.9 step 3) (5261.987012ms) +✔ the pre-send checks: GET user must name the requester, under the deadline (1842.87173ms) +✔ the lead's request refuses a token for login sage (1200.862475ms) +✔ the credential file: the seat's own, 0600, no symlink, never the shared default (1442.138917ms) +✔ an unresolved request blocks a new request, a new round, waiting-on-jason and done (2940.29315ms) +✔ a same-op retry after a kill sends nothing, even with a stale view (7119.351208ms) +✔ a held lock at the outcome exits 3 and names what the transport said (898.409724ms) +✔ late outcomes: after an abandon, and after a resolve with the same or another id (3340.371403ms) +✔ resolve checks the comment: issue, markers, round, candidate and author (1940.283066ms) +✔ the lead resolves a seat's request: the comment's author is the requester, fetched with the lead's token (828.082544ms) +✔ validateRow checks a request round's shape, which every replayed entry must keep (528.324032ms) +✔ request, changes, a new candidate, approval: every round pinned; no review files (1807.647723ms) +✔ a row with no reviewers opens a round that posts nothing (1379.509751ms) +✔ verify-commit: a prospective tree must hold exactly the candidate's paths (1567.982266ms) +✔ semantics: v1 entries replay as before; review entries need v2 (592.904042ms) +✔ set reviewers refuses the row's owner (2026-09-28) (380.040787ms) +✔ the owner records no verdict, even as a listed reviewer (635.322725ms) +✔ a request comment over the length limit is not sent (737.345262ms) +✔ a late POST on a closed row leaves a conflict nothing can resolve, and resolve asks nothing (688.463801ms) +✔ a Jason-gated row reaches waiting-on-jason only on every reviewer's approval (3749.621101ms) +✔ genesis: refusals before anything is written (587.74823ms) +✔ genesis: the map must be committed, well formed, with committed briefs and seats (826.0597ms) +✔ genesis: markers, a stray witness, once only; a retry returns the receipt (713.940647ms) +✔ genesis: a file holding genesis alone with no witness is confirmed by sync or a retry (473.417922ms) +✔ canonical checks: worktree, second clone, detached HEAD, wrong branch, GIT_DIR, foreign code; a symlink works (784.678148ms) +✔ --by that differs from MOSAIC_AGENT_NAME warns on stderr and logs nothing more (N12) (1071.98683ms) +✔ op ids: missing, too long, reserved; a retry answers; another payload refuses (888.989873ms) +✔ a retried add returns the id it first allocated, after reassignment and after done (1085.59566ms) +✔ Rocko's S4 schedule: a lost result, another writer, then the retry opens no second round (844.657744ms) +✔ the review issue and the evidence round through the CLI (lead decision 23, 8.7) (1497.029569ms) +✔ claims and add defaults through the CLI; candidates are manifests or reachable commits (1054.298666ms) +✔ add, set reviewers and assign refuse the row's owner as a reviewer (777.115222ms) +✔ the working-brief check: a changed working copy refuses the start and flags next (875.330423ms) +✔ next: resume first, then nothing for an idle seat; needs a seat (391.124341ms) +✔ view stale: new ops and verify refuse naming the unshown op; retries answer; reads warn; render fixes (898.135557ms) +✔ view unknown: a hand edit, an old marker over an edited body, missing or duplicate markers (1324.996601ms) +✔ a hand edit to queue.json refuses every verb, reads included (831.879171ms) +✔ verify and render --check leave bytes and mtimes unchanged (1160.179129ms) +✔ render is byte-stable across runs and repositories (1305.820508ms) +✔ snapshot and verify --snapshot (2480.182337ms) +✔ usage errors exit 4 (1021.919086ms) +✔ a short write, ENOSPC or a file fsync failure: nothing visible, temp removed (357.402798ms) +✔ a rename failure: nothing visible, temp removed (243.387888ms) +✔ a directory fsync failure: uncertain, exit 3, no receipt; the tail refuses new ops; a retry confirms (322.220165ms) +✔ a directory fsync failure, then sync names the op (503.320478ms) +✔ a witness write failure: uncertain, durable, exit 3; the view is untouched (273.888381ms) +✔ the .git fsync after the witness rename fails: uncertain, exit 3, the witness says so (219.385393ms) +✔ confirming a tail fsyncs queue.json and docs/plans before the witness; either failure changes nothing (259.005141ms) +✔ the docs/plans fsync after the view rename fails: the op stands, the view is written, a warning says so (211.529693ms) +✔ a lock swapped while held is left in place and reported, on a receipt and on a refusal (264.742249ms) +✔ a lock that cannot be released after an op is reported, on a receipt and on a refusal (242.657359ms) +✔ unlock prints a swapped gate's warning on stderr, the result on stdout (195.864438ms) +✔ a view write that fails keeps the op and reports a stale view (262.82204ms) +✔ SIGKILL before the rename: nothing recorded; the retry removes the leftover temp (758.014233ms) +✔ SIGKILL after the rename, before the witness: the tail refuses new ops and sync names the op (787.537175ms) +✔ SIGKILL after the witness, before the view: the stale refusal names the op (708.651878ms) +✔ SIGKILL after the view, before the receipt: the retry returns the receipt (729.177763ms) +✔ git checkout between steps 1 and 7: step 7 refuses and nothing is written (278.079412ms) +✔ git stash restoring an older valid pair: history lost; accept-history needs privilege, a reason and --yes (1272.927575ms) +✔ a deleted witness: refused after the locked recheck; accept-history records it absent (372.724295ms) +✔ a header edit during a write: the op stands, the view write is skipped with a warning (288.878156ms) +✔ a reader paused between the witness and the file while a writer finishes: no lost-history report (294.123846ms) +✔ rows: every row as show prints it, in list order; writes nothing; same notes and refusals as list (329.091403ms) +✔ file-then-witness order forced by a hook: the locked recheck prevents a false report (313.610048ms) +✔ a writer paused before and after the witness rename: readers see a tail, then a match (330.849298ms) +✔ a true rollback is reported only after the locked recheck; a held lock names its holder instead (692.622594ms) +✔ an accept-history in progress: an unlocked reader waits on the lock and never reports lost history (722.805732ms) +✔ the platform check refuses other filesystems (208.31301ms) +✔ tmpfs passes only a test layer that allows it (N5) (314.598247ms) +✔ unlock keeps a multi-line lock record on stdout (P3) (235.596901ms) +ℹ tests 149 +ℹ suites 0 +ℹ pass 149 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 40044.001884 diff --git a/agents/darkwing/work/queue-54-review/r2/out/node-webui.txt b/agents/darkwing/work/queue-54-review/r2/out/node-webui.txt new file mode 100644 index 00000000..b0efbfea --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/out/node-webui.txt @@ -0,0 +1,48 @@ +✔ browser edge states: loading, empty, malformed, stale, hostile/long values, in-flight reply and appearance fallback (7252.442116ms) +Rendered contrast: {"failures":[],"count":330,"lowest":4.504658476260286} +✔ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (7570.044946ms) +✔ S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes (8645.654568ms) +✔ bus routes serve the four reads from the reader view, unescaped JSON for the page to escape (276.602827ms) +✔ bus routes are GET-only, have no write verb, and keep the same-origin checks (162.697506ms) +✔ bus refusals map to statuses and never carry a path or a stack (76.11843ms) +✔ humanCall speaks the human transport protocol without blocking the server (2487.781435ms) +✔ busReader takes --business, else the live bus host, else refuses (304.325182ms) +✔ humanCall kills a transport that runs past its timeout (546.765936ms) +✔ serve refuses a --business value that is not a business id (248.712632ms) +✔ conversation view: full history, collapsed tools, hidden thinking, inert hostile content, malformed and reconcile markers (8001.69256ms) +✔ conversation view: a fork keeps the open branch, says so, and opens the new one on request (3916.153617ms) +✔ conversation view: a newer session with no readable history keeps the marker (2920.014454ms) +✔ conversation view: seats without history say so and offer no reply (1475.215119ms) +✔ Discord row through real board/WebUI: independent brake/liveness, no Reply, literal content (7907.271843ms) +✔ return flow through the conversation view: send, tool call, delayed result, peer message, exact long answers, relaunch (56492.845932ms) +✔ redactor: config, dataRoot, any absolute path, Discord ids and the JSON parser quote (3.422064ms) +✔ credential state from the date alone, as the bus states it (0.255447ms) +✔ queue: rows, one row, ids and methods, notes; no path or id from a row (2152.928432ms) +✔ queue: a refused read fails closed with the store's text, redacted (2327.77963ms) +✔ queue: a store that fails to load, or a child that dies, gives a fixed message with no path or stack (4467.156753ms) +✔ business: names, vars on the allowlist, authority, credential metadata only (16.773128ms) +✔ business: missing or invalid file refuses with the module's text, redacted (34.747153ms) +✔ business without --business: the live bus host, else no-bus-host; no system config: not-configured (8.901497ms) +✔ settings: release, board, loopback address, notifier binding name only (842.515593ms) +✔ both presentations replace old activity with relaunch notice, label retained history, then resume after new activity (7453.127284ms) +✔ reported return flow and relative Age: reply sent from the inspector, then the new answer appears there without manual refresh (23286.027865ms) +✔ loopback host and board origin fail closed (10.905805ms) +✔ real board fixture passes through WebUI; assets and isolated seen/reply work (184.751015ms) +✔ proxy preserves exact request bytes, status and receipt, rejects forms and malformed JSON, never follows redirect (143.484502ms) +✔ unreachable board reports URL; CLI rejects unsupported options (1569.395099ms) +✔ tokens.css and icons.svg are byte copies of docs/design (1.293783ms) +✔ JetBrains Mono files match the digests in their sources file, with the OFL text (2.433668ms) +✔ shipped strings are unchanged, and the web keeps its write boundary (2.203302ms) +✔ shell in a browser: System default, seeded states, 400px, focus and the Ctrl+K palette (8551.629939ms) +✔ five states on Board, Inbox, Tasks, Agents and Trail (4222.220475ms) +✔ Queue, Business and Settings in their five states, with no move button (7880.478858ms) +✔ seeded secrets, Discord ids and paths reach no response and no page; business refusals in the module's words (4765.605609ms) +✔ the server log names no config path when the system config refuses (214.442483ms) +ℹ tests 39 +ℹ suites 0 +ℹ pass 39 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 57075.901167 diff --git a/agents/darkwing/work/queue-54-review/r2/out/summary.txt b/agents/darkwing/work/queue-54-review/r2/out/summary.txt new file mode 100644 index 00000000..692ae1db --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/out/summary.txt @@ -0,0 +1,16 @@ +start 2026-10-10T21:18:07Z +node-webui exit=0 ℹ pass 39 ℹ fail 0 +node-queue exit=0 ℹ pass 149 ℹ fail 0 +node-business exit=0 ℹ pass 60 ℹ 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-10T21:21:30Z +DONE diff --git a/agents/darkwing/work/queue-54-review/r2/out/test-auth.txt b/agents/darkwing/work/queue-54-review/r2/out/test-auth.txt new file mode 100644 index 00000000..ac228760 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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-54-review/r2/out/test-conductor.txt b/agents/darkwing/work/queue-54-review/r2/out/test-conductor.txt new file mode 100644 index 00000000..d947c364 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/out/test-conductor.txt @@ -0,0 +1,55 @@ +Note: switching to '6637bca54b95cf4936c1ecac9e9b6ca2bbada3bf'. + +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 '6637bca54b95cf4936c1ecac9e9b6ca2bbada3bf'. + +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-54-review/r2/out/test-config.txt b/agents/darkwing/work/queue-54-review/r2/out/test-config.txt new file mode 100644 index 00000000..76c05ef7 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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-54-review/r2/out/test-discord.txt b/agents/darkwing/work/queue-54-review/r2/out/test-discord.txt new file mode 100644 index 00000000..b013f9ff --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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-54-review/r2/out/test-extension-package.txt b/agents/darkwing/work/queue-54-review/r2/out/test-extension-package.txt new file mode 100644 index 00000000..c7369795 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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: 1836275 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-54-review/r2/out/test-foundation.txt b/agents/darkwing/work/queue-54-review/r2/out/test-foundation.txt new file mode 100644 index 00000000..6338e1e6 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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-54-review/r2/out/test-queue.txt b/agents/darkwing/work/queue-54-review/r2/out/test-queue.txt new file mode 100644 index 00000000..f557b72d --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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 149 +ℹ pass 149 +ℹ 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/r54b/papply) 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-54-review/r2/out/test-release-docker.txt b/agents/darkwing/work/queue-54-review/r2/out/test-release-docker.txt new file mode 100644 index 00000000..5d95aa44 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/out/test-release-docker.txt @@ -0,0 +1,17 @@ +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 +exit=0 diff --git a/agents/darkwing/work/queue-54-review/r2/out/test-release.txt b/agents/darkwing/work/queue-54-review/r2/out/test-release.txt new file mode 100644 index 00000000..1d6ed050 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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-54-review/r2/out/test-task.txt b/agents/darkwing/work/queue-54-review/r2/out/test-task.txt new file mode 100644 index 00000000..cd89fe9b --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/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-54-review/r2/probes/e12-check.sh b/agents/darkwing/work/queue-54-review/r2/probes/e12-check.sh new file mode 100755 index 00000000..4b9010f7 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/e12-check.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# E12 at the child: queue-read.mjs with the null check dropped, beside a store whose errors.mjs is missing. +export TMPDIR=~/darkwing-scratch/r54b/tmp +D=$TMPDIR/e12; rm -rf "$D"; mkdir -p $D/packages/webui/src $D/packages/queue/src +sed 's/const refused = QueueError !== null \&\& err instanceof QueueError;/const refused = err instanceof QueueError;/' ~/darkwing-scratch/r54b/papply/packages/webui/src/queue-read.mjs > $D/packages/webui/src/queue-read.mjs +echo "mutated lines: $(grep -c 'const refused = err instanceof' $D/packages/webui/src/queue-read.mjs)" +echo 'export function rows() { return { rows: [], err: [] }; }' > $D/packages/queue/src/store.mjs +(cd $D/packages/webui/src && node queue-read.mjs ../out.txt 2> ../err.txt); echo "exit=$?" +echo "stdout bytes: $(wc -c < $D/packages/webui/out.txt)" +echo "stderr, home shown as ~:"; head -6 $D/packages/webui/err.txt | sed "s#$HOME#~#g" diff --git a/agents/darkwing/work/queue-54-review/r2/probes/e12-check.txt b/agents/darkwing/work/queue-54-review/r2/probes/e12-check.txt new file mode 100644 index 00000000..714c9a6e --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/e12-check.txt @@ -0,0 +1,10 @@ +mutated lines: 1 +exit=1 +stdout bytes: 0 +stderr, home shown as ~: +file://~/darkwing-scratch/r54b/tmp/e12/packages/webui/src/queue-read.mjs:18 + const refused = err instanceof QueueError; + ^ + +TypeError: Right-hand side of 'instanceof' is not an object + at file://~/darkwing-scratch/r54b/tmp/e12/packages/webui/src/queue-read.mjs:18:23 diff --git a/agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.test.mjs b/agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.test.mjs new file mode 100644 index 00000000..8883d3a7 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.test.mjs @@ -0,0 +1,97 @@ +// Darkwing row 54 round 2 browser probes: the round 1 set on the seeded fixture, then B5 on the real queue. +// B1: the Business view's Arbiters line. B2: focus on a Settings mirror select across the 10 s refresh. +// B3: focus on the H1 across the 10 s refresh. B4: navigation clears the due refresh. +// B5: After, Required and Note on real rows, reads rooted at ROOT (the canonical checkout, rows() writes nothing). +// Run from a worktree's packages/webui: node --test with WT set to that worktree. +import { test, after } from 'node:test'; +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 { consoleReads } = await import(u('src/reads.mjs')); +const { REPO_ROLES } = await import(pathToFileURL(`${WT}/packages/business/tests/helpers.mjs`).href); +const { seeded, queueRepo } = await import(u('tests/reads-fixture.mjs')); +const out = []; +const note = (k, v) => { out.push(`${k}: ${JSON.stringify(v)}`); }; +after(() => console.log(out.join('\n'))); + +const PROBE = '(()=>{const st=setTimeout,ct=clearTimeout;window.refreshes=new Map();window.setTimeout=(fn,ms,...a)=>{if(ms!==10000||!String(fn).includes("render(false)"))return st(fn,ms,...a);const id=st(()=>{refreshes.delete(id);fn()},ms);refreshes.set(id,fn);return id};window.clearTimeout=id=>{refreshes.delete(id);return ct(id)};window.fireRefresh=()=>{const due=[...refreshes];refreshes.clear();for(const[id,fn]of due){ct(id);fn()}return due.length}})();'; + +test('probes, seeded fixture', { timeout: 120000 }, async t => { + const s = seeded(t), repo = queueRepo(t); + note('fixture arbiters', s.doc.arbiters); + const web = await startServer({ port: 0, board: 'http://127.0.0.1:9', reads: consoleReads({ root: repo.root, env: repo.env, system: s.system, configDir: s.configDir, rolesDir: REPO_ROLES, business: 'acme' }) }); + const b = await browser(); + try { + const wait = expr => b.evaluate(`(async()=>{for(let i=0;i<200;i++){if(${expr})return true;await new Promise(r=>setTimeout(r,50))}throw new Error('Condition timed out: '+${JSON.stringify(expr)})})()`); + const go = async (hash, h1) => { await b.evaluate(`location.hash=${JSON.stringify(hash)}`); await wait(`document.querySelector("#bus-view h1")?.textContent.startsWith(${JSON.stringify(h1)}) && !document.querySelector("#bus-view [aria-busy]")`); }; + await b.call('Page.addScriptToEvaluateOnNewDocument', { source: PROBE }); + await b.viewport(1200, 900); + await b.navigate(`http://127.0.0.1:${web.address().port}/`); + await wait('document.querySelectorAll("#sections a").length===7'); + + // B1 + await go('#/business', 'Business acme'); + note('B1 api arbiters', await b.evaluate('fetch("/api/business").then(r=>r.json()).then(j=>j.business.arbiters)')); + note('B1 Arbiters dd', await b.evaluate('(()=>{const dt=[...document.querySelectorAll("#bus-view dt")].find(e=>e.textContent==="Arbiters");return dt?.nextElementSibling?.textContent})()')); + + // B2 + await go('#/settings', 'Settings'); + const sels = await b.evaluate('[...document.querySelectorAll("#bus-view select[data-mirror]")].map(e=>e.dataset.mirror)'); + note('B2 mirrors', sels); + for (const m of sels) { + await b.evaluate(`document.querySelector('#bus-view select[data-mirror="${m}"]').focus()`); + note(`B2 ${m} before`, await b.evaluate('[document.activeElement.tagName, document.activeElement.dataset?.mirror]')); + note(`B2 ${m} due refreshes`, await b.evaluate('window.refreshes.size')); + note(`B2 ${m} fired`, await b.evaluate('window.fireRefresh()')); + await wait('!document.querySelector("#bus-view [aria-busy]")'); + await new Promise(r => setTimeout(r, 300)); + note(`B2 ${m} after`, await b.evaluate('[document.activeElement.tagName, document.activeElement.dataset?.mirror ?? document.activeElement.id]')); + } + // B2b: change a mirror and see the command bar select follow + const m0 = sels[0]; + note('B2b before', await b.evaluate(`[document.getElementById("${m0}").value, [...document.getElementById("${m0}").options].map(o=>o.value)]`)); + await b.evaluate(`(()=>{const s=document.querySelector('#bus-view select[data-mirror="${m0}"]');const v=[...s.options].map(o=>o.value).find(v=>v!==s.value);s.value=v;s.dispatchEvent(new Event('change',{bubbles:true}));})()`); + note('B2b after', await b.evaluate(`[document.getElementById("${m0}").value, document.querySelector('#bus-view select[data-mirror="${m0}"]').value]`)); + + // B3 + await go('#/queue', 'Queue'); + await b.evaluate('(()=>{const h=document.querySelector("#bus-view h1");h.tabIndex=-1;h.focus()})()'); + note('B3 before', await b.evaluate('document.activeElement.tagName')); + note('B3 fired', await b.evaluate('window.fireRefresh()')); + await wait('!document.querySelector("#bus-view [aria-busy]")'); + await new Promise(r => setTimeout(r, 300)); + note('B3 after', await b.evaluate('[document.activeElement.tagName, document.activeElement.textContent.slice(0,20)]')); + + // B4 + await go('#/queue', 'Queue'); + note('B4 due on queue', await b.evaluate('window.refreshes.size')); + await go('#/business', 'Business acme'); + note('B4 due after nav', await b.evaluate('window.refreshes.size')); + } finally { await b.close(); await close(web); } +}); + +test('B5 real queue rows', { timeout: 120000 }, async () => { + const web = await startServer({ port: 0, board: 'http://127.0.0.1:9', reads: consoleReads({ root: process.env.ROOT }) }); + const b = await browser(); + try { + const wait = expr => b.evaluate(`(async()=>{for(let i=0;i<200;i++){if(${expr})return true;await new Promise(r=>setTimeout(r,50))}throw new Error('Condition timed out: '+${JSON.stringify(expr)})})()`); + const go = async (hash, h1) => { await b.evaluate(`location.hash=${JSON.stringify(hash)}`); await wait(`document.querySelector("#bus-view h1")?.textContent.startsWith(${JSON.stringify(h1)}) && !document.querySelector("#bus-view [aria-busy]")`); }; + const dd = k => b.evaluate(`(()=>{const dt=[...document.querySelectorAll("#bus-view dt")].find(e=>e.textContent===${JSON.stringify(k)});return dt ? dt.nextElementSibling.innerHTML : null})()`); + await b.viewport(1200, 900); + await b.navigate(`http://127.0.0.1:${web.address().port}/`); + await wait('document.querySelectorAll("#sections a").length===7'); + const ids = [8, 35, 47]; // from probe-realq.txt: the rows whose reads carry + note('B5 rows with ', ids); + for (const id of [9, 38, 54, ...ids]) { + await go(`#/queue/${id}`, `Row ${id}`); + note(`B5 #/queue/${id} After`, await dd('After')); + note(`B5 #/queue/${id} Required`, await dd('Required')); + const n = await dd('Note'); + note(`B5 #/queue/${id} Note has `, n === null ? null : n.includes('<path>')); + } + note('B5 page text has /home/ or ~/', await b.evaluate('/\\/home\\/|~\\//.test(document.body.innerText)')); + } finally { await b.close(); await close(web); } +}); diff --git a/agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.txt b/agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.txt new file mode 100644 index 00000000..7d5d6d5c --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/probe-browser-r2.txt @@ -0,0 +1,49 @@ +✔ probes, seeded fixture (1956.123482ms) +fixture arbiters: {"delivery":"pm","technical":"cto"} +B1 api arbiters: {"delivery":"pm","technical":"cto"} +B1 Arbiters dd: "pm (delivery), cto (technical)" +B2 mirrors: ["palette","mode"] +B2 palette before: ["SELECT","palette"] +B2 palette due refreshes: 1 +B2 palette fired: 1 +B2 palette after: ["SELECT","palette"] +B2 mode before: ["SELECT","mode"] +B2 mode due refreshes: 1 +B2 mode fired: 1 +B2 mode after: ["SELECT","mode"] +B2b before: ["harbor",["harbor","carmine","atlantic","terracotta","aubergine","mineral","cobalt","rosewood","graphite","grove"]] +B2b after: ["carmine","carmine"] +B3 before: "H1" +B3 fired: 1 +B3 after: ["H1","Queue"] +B4 due on queue: 1 +B4 due after nav: 1 +B5 rows with : [8,35,47] +B5 #/queue/9 After: "none" +B5 #/queue/9 Required: "yes since " +B5 #/queue/9 Note has : false +B5 #/queue/38 After: "36 done, 37 done" +B5 #/queue/38 Required: null +B5 #/queue/38 Note has : null +B5 #/queue/54 After: "53 done" +B5 #/queue/54 Required: null +B5 #/queue/54 Note has : null +B5 #/queue/8 After: "none" +B5 #/queue/8 Required: null +B5 #/queue/8 Note has : true +B5 #/queue/35 After: "38 done" +B5 #/queue/35 Required: null +B5 #/queue/35 Note has : true +B5 #/queue/47 After: "40 done" +B5 #/queue/47 Required: null +B5 #/queue/47 Note has : true +B5 page text has /home/ or ~/: false +✔ B5 real queue rows (3610.152182ms) +ℹ tests 2 +ℹ suites 0 +ℹ pass 2 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 5659.612321 diff --git a/agents/darkwing/work/queue-54-review/r2/probes/probe-r2.mjs b/agents/darkwing/work/queue-54-review/r2/probes/probe-r2.mjs new file mode 100644 index 00000000..635f71dc --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/probe-r2.mjs @@ -0,0 +1,54 @@ +// Row 54 round 2 node probes (Darkwing). Run with WT=. +import { mkdtempSync, writeFileSync, mkdirSync, realpathSync, rmSync, copyFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { tmpdir } from 'node:os'; +const WT = process.env.WT; +const { redactor, queueReader, consoleReads } = await import(`${WT}/packages/webui/src/reads.mjs`); +const out = (k, v) => console.log(`${k}: ${JSON.stringify(v)}`); + +// Q1: the round 1 P2 shapes and new ones through the round 2 redactor. +const r = redactor({ configDir: '/home/u/.config/mosaic-dev', dataRoot: '/home/u/.mosaic-dev' }); +for (const s of [ + 'config:/home/u/secret/x.token', 'open "/home/u/secret/x.token"', 'path', 'see file:///home/u/x.token', 'at ~/secret/x.token', + 'in ./secret/x.token', 'C:\\Users\\u\\x.token', 'url https://discord.com/channels/123456789012345678/223456789012345678', + 'id:123456789012345678', 'id_123456789012345678', 'tab\t/home/u/x', '/home/u/.mosaic-dev.bak/x', '[/home/u/x]', '{/home/u/x}', + 'https://git.example/org/repo/issues/1', 'ssh://git@host/org/repo', 'file://localhost/home/u/x', 'file:/home/u/x', 'http://', + 'no `~/.mosaic` changes', 'key=~/k', 'a~/b', 'origin/refactor', 'note: origin/refactor', '12:/x', 'see:~/x', '~', '~user/x', + 'git@host:org/repo.git', 'http://127.0.0.1:3773/x/y', '/x', 'a /home/u/my dir/x', +]) out(`Q1 ${JSON.stringify(s)}`, r(s)); + +// Q2: the real queue-read.mjs when its imports fail or the store refuses at load. +const base = realpathSync(mkdtempSync(join(tmpdir(), 'dw-r54b-'))); +const ERR = 'export class QueueError extends Error { constructor(m, c = 1) { super(m); this.code = c; } }'; +const cases = [ + ['syntax', ERR, 'export function rows( {'], + ['missing', ERR, null], + ['errors-missing', null, 'export function rows() { return { rows: [], err: [] }; }'], + ['errors-syntax', 'export class QueueError extends {', 'export function rows() { return { rows: [], err: [] }; }'], + ['load-refusal-2', ERR, "import { QueueError } from './errors.mjs'; throw new QueueError('queue.json is invalid at ' + new URL('q.json', import.meta.url).pathname + ' and ' + import.meta.url, 2);"], + ['load-plain-error', ERR, `throw new Error('boom at ' + import.meta.url);`], + ['rows-throws-plain', ERR, `export function rows() { throw new Error('bad at ' + import.meta.url); }`], +]; +for (const [name, errors, store] of cases) { + const root = join(base, name); + mkdirSync(join(root, 'packages/webui/src'), { recursive: true }); mkdirSync(join(root, 'packages/queue/src'), { recursive: true }); + copyFileSync(join(WT, 'packages/webui/src/queue-read.mjs'), join(root, 'packages/webui/src/queue-read.mjs')); + if (errors) writeFileSync(join(root, 'packages/queue/src/errors.mjs'), errors); + if (store) writeFileSync(join(root, 'packages/queue/src/store.mjs'), store); + try { await consoleReads({ root }).queue(); out(`Q2 ${name}`, 'resolved'); } + catch (e) { out(`Q2 ${name}`, { code: e.code, message: e.message.replaceAll(base, ''), leaksBase: e.message.includes(base) }); } +} + +// Q3: fake children: exit 1 and 3 with Node-style stderr, exit 2 with a path. +const fake = (name, body) => { const root = join(base, name); mkdirSync(join(root, 'packages/webui/src'), { recursive: true }); writeFileSync(join(root, 'packages/webui/src/queue-read.mjs'), body); return root; }; +const settle = async p => { try { await p; return 'resolved'; } catch (e) { return { code: e.code, message: e.message.replaceAll(base, ''), leaksBase: e.message.includes(base) }; } }; +out('Q3 exit 1 with stack', await settle(consoleReads({ root: fake('one', `process.stderr.write("Error: x\\n at file://${base}/a.mjs:1:1\\n");process.exit(1)`) }).queue())); +out('Q3 exit 3 with stack', await settle(consoleReads({ root: fake('three', `process.stderr.write("at file://${base}/a.mjs:1:1");process.exit(3)`) }).queue())); +out('Q3 exit 2 with file:// path', await settle(consoleReads({ root: fake('two', `process.stderr.write("refused at file://${base}/q.json");process.exit(2)`) }).queue())); +out('Q3 exit 2 with ~/ path', await settle(consoleReads({ root: fake('two2', `process.stderr.write("refused at ~/x/q.json");process.exit(2)`) }).queue())); +out('Q3 exit 2 empty stderr', await settle(consoleReads({ root: fake('two3', `process.exit(2)`) }).queue())); + +// Q4: settings with no system config, with and without a named business. +out('Q4 settings, no system, no business', (await consoleReads({ root: base }).settings()).notifier); +out('Q4 settings, no system, business acme', (await consoleReads({ root: base, business: 'acme' }).settings()).notifier); +rmSync(base, { recursive: true, force: true }); diff --git a/agents/darkwing/work/queue-54-review/r2/probes/probe-r2.txt b/agents/darkwing/work/queue-54-review/r2/probes/probe-r2.txt new file mode 100644 index 00000000..dbe2c246 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/probe-r2.txt @@ -0,0 +1,46 @@ +Q1 "config:/home/u/secret/x.token": "config:" +Q1 "open \"/home/u/secret/x.token\"": "open \"\"" +Q1 "path": "path<>" +Q1 "see file:///home/u/x.token": "see file:" +Q1 "at ~/secret/x.token": "at " +Q1 "in ./secret/x.token": "in ./secret/x.token" +Q1 "C:\\Users\\u\\x.token": "C:\\Users\\u\\x.token" +Q1 "url https://discord.com/channels/123456789012345678/223456789012345678": "url https://discord.com/channels//" +Q1 "id:123456789012345678": "id:" +Q1 "id_123456789012345678": "id_123456789012345678" +Q1 "tab\t/home/u/x": "tab\t" +Q1 "/home/u/.mosaic-dev.bak/x": "" +Q1 "[/home/u/x]": "[]" +Q1 "{/home/u/x}": "{}" +Q1 "https://git.example/org/repo/issues/1": "https://git.example/org/repo/issues/1" +Q1 "ssh://git@host/org/repo": "ssh://git@host/org/repo" +Q1 "file://localhost/home/u/x": "file://localhost/home/u/x" +Q1 "file:/home/u/x": "file:" +Q1 "http://": "http:" +Q1 "no `~/.mosaic` changes": "no `` changes" +Q1 "key=~/k": "key=" +Q1 "a~/b": "a~/b" +Q1 "origin/refactor": "origin/refactor" +Q1 "note: origin/refactor": "note: origin/refactor" +Q1 "12:/x": "12:" +Q1 "see:~/x": "see:" +Q1 "~": "~" +Q1 "~user/x": "~user/x" +Q1 "git@host:org/repo.git": "git@host:org/repo.git" +Q1 "http://127.0.0.1:3773/x/y": "http://127.0.0.1:3773/x/y" +Q1 "/x": "/x" +Q1 "a /home/u/my dir/x": "a dir/x" +Q2 syntax: {"code":"read-failed","message":"the queue read failed (exit 1)","leaksBase":false} +Q2 missing: {"code":"read-failed","message":"the queue read failed (exit 1)","leaksBase":false} +Q2 errors-missing: {"code":"read-failed","message":"the queue read failed (exit 1)","leaksBase":false} +Q2 errors-syntax: {"code":"read-failed","message":"the queue read failed (exit 1)","leaksBase":false} +Q2 load-refusal-2: {"code":"queue-refused","message":"queue.json is invalid at and file:","leaksBase":false} +Q2 load-plain-error: {"code":"read-failed","message":"the queue read failed (exit 1)","leaksBase":false} +Q2 rows-throws-plain: {"code":"read-failed","message":"the queue read failed (exit 1)","leaksBase":false} +Q3 exit 1 with stack: {"code":"read-failed","message":"the queue read failed (exit 1)","leaksBase":false} +Q3 exit 3 with stack: {"code":"read-failed","message":"the queue read failed (exit 3)","leaksBase":false} +Q3 exit 2 with file:// path: {"code":"queue-refused","message":"refused at file:","leaksBase":false} +Q3 exit 2 with ~/ path: {"code":"queue-refused","message":"refused at ","leaksBase":false} +Q3 exit 2 empty stderr: {"code":"queue-refused","message":"the queue refused the read","leaksBase":false} +Q4 settings, no system, no business: {"refused":"not-configured","message":"the Console has no system config, so it knows no business"} +Q4 settings, no system, business acme: {"refused":"not-configured","message":"the Console has no system config, so it knows no notifier config"} diff --git a/agents/darkwing/work/queue-54-review/r2/probes/probe-realq.mjs b/agents/darkwing/work/queue-54-review/r2/probes/probe-realq.mjs new file mode 100644 index 00000000..60ff80dc --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/probe-realq.mjs @@ -0,0 +1,18 @@ +// Q5: every row of the real queue (ROOT, the canonical checkout, which holds the candidate; rows() writes nothing) through +// /api/queue and /api/queue/:id reads: does any absolute or ~/ path survive the redactor? +const WT = process.env.WT; +const { consoleReads } = await import(`${WT}/packages/webui/src/reads.mjs`); +const reads = consoleReads({ root: process.env.ROOT }); +const list = await reads.queue(); +const bad = re => JSON.stringify(list).match(re); +const PATH = /(^|[^\w.<>:-])(~\/|\/(home|mnt|srv|tmp|etc|var|root|Users)\/)/; +let hits = [], redacted = 0; const withLabel = []; +for (const r of list.rows) { + const one = JSON.stringify(await reads.row(r.id)); + if (PATH.test(one)) hits.push(r.id); + if (one.includes("")) { redacted++; withLabel.push(r.id); } +} +console.log(JSON.stringify({ rows: list.rows.length, listHit: !!bad(PATH), rowHits: hits, rowsWithPathLabel: redacted, withLabel })); +// Q5b: the same rows, a plain substring count with no prefix rule. +const all = JSON.stringify(list) + (await Promise.all(list.rows.map(r => reads.row(r.id).then(JSON.stringify)))).join(''); +console.log(JSON.stringify(Object.fromEntries(['/home/', '/mnt/', '~/', 'file:', 'jwoltje'].map(k => [k, all.split(k).length - 1])))); diff --git a/agents/darkwing/work/queue-54-review/r2/probes/probe-realq.txt b/agents/darkwing/work/queue-54-review/r2/probes/probe-realq.txt new file mode 100644 index 00000000..d2c5ef86 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/r2/probes/probe-realq.txt @@ -0,0 +1,2 @@ +{"rows":61,"listHit":false,"rowHits":[],"rowsWithPathLabel":3,"withLabel":[8,35,47]} +{"/home/":0,"/mnt/":0,"~/":0,"file:":0,"jwoltje":0} diff --git a/agents/darkwing/work/queue-54-review/review-r2.md b/agents/darkwing/work/queue-54-review/review-r2.md new file mode 100644 index 00000000..e922d814 --- /dev/null +++ b/agents/darkwing/work/queue-54-review/review-r2.md @@ -0,0 +1,196 @@ +# Row 54, read-only console views, round 2 review (Darkwing) + +Issue #1543, request comment 27187, packet comment 27188. Base +`d64f434f`. Candidate manifest sha256 +`afb2ae0e66e6388a35b4bedf915080d876a3d8576f79ae2ab660e81188a3a215`, 14 +files. The packet manifest and the checkout both check 14 OK, and +`row54.patch` applied at `6637bca5` gives the same 14 files. `6637bca5` +is `d64f434f` plus queue revs 373 to 380, the round 1 review packets and +SESSIONS lines. None of those touch `packages/`. + +Verdict: **approve**. Both round 1 blockers are fixed and tested. So are +the D29, D20 and D21 test gaps, and the views.test :167 failure has a +cause I can follow. Filbert's items that I could check from outside +(After, the redactor, Required, the settings refusal) behave as stated on +the real queue as well as on the fixture. Every suite is green. 40 of 45 +mutants die; three new survivors are small test gaps, none blocking +(notes 4 to 6). + +## Method + +- Detached worktrees `papply` and `mutwt` at `6637bca5` with + `row54.patch` applied and staged. Both check 14 OK. `mutwt` still + checks 14 OK after the mutant runs (`r2/mut/manifest-after.txt`). +- `r2/gate.sh`, the same gate as round 1: the `packages/webui`, + `packages/queue` and `packages/business` node suites, + `build-tokens.mjs --check`, then every `scripts/test-*.sh` with + `DOCKER_HOST=unix:///nonexistent.sock`, 21:18:07Z to 21:21:30Z. Then + `test-release` with Docker. +- 45 mutants (`r2/mut/mutate.py`, `r2/mut/run.sh`): my 31 from round 1, + with D07 moved onto the new redactor, and 14 new ones (E01 to E14) on + round 2's changes. Each runs against the full `packages/webui` suite, + D31 against `packages/queue`, 21:22:02Z to 22:07:37Z. +- Node probes (`r2/probes/probe-r2.mjs`, output `probe-r2.txt`): the + round 1 redactor strings plus URL, `~/` and `:` shapes (Q1); the real + `queue-read.mjs` beside a broken, missing or refusing store, and a + broken or missing `errors.mjs` (Q2); fake children that print a stack + and exit 1 or 3, or refuse with a path (Q3); settings with no system + config (Q4). +- A sweep of the real queue (`r2/probes/probe-realq.mjs`, output + `probe-realq.txt`): `/api/queue` and every `/api/queue/:id` read for all + 61 rows, with the candidate's reads rooted at the canonical checkout, + because the store refuses a linked worktree. `rows()` writes nothing + (decision 83). +- Browser probes in Chromium through the candidate's `tests/browser.mjs` + (`r2/probes/probe-browser-r2.test.mjs`, output `probe-browser-r2.txt`): + round 1's B1 to B4 on the seeded fixture, and B5 on real rows 8, 9, 35, + 38, 47 and 54. +- Read `row54-r1-to-r2.patch` line by line, and Dewey's round 2 evidence. + +Node v26.8.1, `TMPDIR=~/darkwing-scratch/r54b/tmp`. No tracker request. + +## Suites + +| Suite | Result | +|---|---| +| packages/webui (node) | 39/0 | +| packages/queue (node) | 149/0 | +| packages/business (node) | 60/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 | + +As in round 1, I didn't run test-task with real Docker, because it makes +live model calls. + +## Round 1 items + +| Item | Result | +|---|---| +| Required 1, Arbiters | Fixed. B1 on the seeded fixture: the API gives `{"delivery":"pm","technical":"cto"}` and the page shows "pm (delivery), cto (technical)". The seeded views test asserts that line. E07 (back to `names()`) dies | +| Required 2, import leak | Fixed, both ways I suggested. Q2: a store with a syntax error, a missing store, a missing or broken `errors.mjs`, a store that throws a plain error at load, and `rows()` throwing all give `read-failed` "the queue read failed (exit 1)", with no base path. Q3: exit 1 and exit 3 with a `file://` stack give the fixed message. E01 (static imports) and E02 (forward any exit) die | +| D29 mirror focus | Test added. D29 dies | +| D20 output cap, D21 timeout | Tests added. Both die | +| D22 host state `.live` | No test, follow-up. Still survives | +| :167 | Explained (below) | +| Note 4, `GROUPS =[[` | Fixed | + +A store that refuses at load with exit 2 still has its message forwarded, +which is right: that text is the store's own. Q2 `load-refusal-2` throws +a `QueueError` with an absolute path and a `file://` URL in it, and both +come out as `` and `file:`. + +The :167 account holds together. With reads and no bus, the palette's +`/api/bus/inbox` and `/api/bus/tasks` reads answer 503 `not-configured`, +which is a refusal, and row 53's rule forgets every read on a refusal, +`api:queue` included. Whether the queue rows were listed then depended on +which finished first. Dewey's `views-no-bus` mutant drops the test's stub +bus and dies at that check, which is the evidence I'd want. In round 1, +D06, D07 and D09 also timed out at :167, though D07 and D09 can't reach +that test. A race explains that and a timeout didn't. The product +question Dewey raises, whether +`not-configured` on a bus route should forget the queue read, belongs to +Sage and row 53, and I agree it isn't row 54's to change. + +## Filbert's items, checked from outside + +I didn't review these as Filbert's reviewer; I checked what my probes +reach. + +| Item | Result | +|---|---| +| B1, After | B5 on real rows: row 38 shows "36 done, 37 done" and row 54 "53 done", each id a link. E08 and E14 die | +| R1, redactor | Q1 below. Over all 61 real rows the reads carry no `/home/`, `/mnt/`, `~/`, `file:` or user name; rows 8, 35 and 47 carry `` where their notes had `~/` paths, and B5 shows the same on their pages | +| N1, settings with no system config | Q4: `not-configured`, "the Console has no system config, so it knows no notifier config". E11 dies | +| N2, Required | B5 row 9: "yes since 2026-09-13" (27 d ago). E09 dies; E10 survives, note 4 | + +## Probes + +| Probe | Candidate | +|---|---| +| Q1 redactor | `config:/…`, `file:/…`, `file:///…`, `~/…`, `key=~/k`, `see:~/x`, `` `~/.mosaic` `` and `` become ``. `https://`, `ssh://`, `http://127.0.0.1:3773/x/y`, `git@host:org/repo.git`, `origin/refactor`, `a~/b`, `~` and `~user/x` are unchanged. `./…`, Windows paths and `id_` are unchanged, as in round 1. Notes 1 and 2 | +| Q2 import and load failures | all seven cases: fixed `read-failed` or the store's refusal, no base path | +| Q3 fake children | exit 1 and 3 fixed; exit 2 forwards with `file:` and ``; exit 2 silent gives "the queue refused the read" | +| Q4 settings, no system config | no business: "knows no business"; `--business acme`: "knows no notifier config". Both `not-configured` | +| Q5 real queue sweep | 61 rows; no absolute or `~/` path in the list or any row | +| B1 Arbiters | "pm (delivery), cto (technical)" | +| B2 mirror focus | kept on `palette` and `mode`; a mirror change moves the command bar | +| B3 H1 focus | kept | +| B4 navigation | one refresh due after it, as in round 1 | +| B5 real rows | After, Required and Note as in the table above; the last page's text has no `/home/` or `~/` | + +## Mutants + +40 of 45 killed (`r2/mut/summary.txt`). I checked each kill site in its +output against its diff, and each one fails at the assertion meant for +it. The round 1 mutants not in the table die at the same assertions as in +round 1, at the current line numbers. + +| Mutant | Change | Result | +|---|---|---| +| D14 | role vars not allowlisted | survived, equivalent as in round 1 | +| D20 | no output cap | killed, "the queue read printed too much", `reads.test.mjs:105` | +| D21 | timeout times 1000 | killed by the test's own 60 s timeout, `reads.test.mjs:87` | +| D22 | host state without `.live` | survived, the follow-up | +| D29 | `keep()` without the mirror | killed, "the refresh keeps focus on the mirror select", `views.test.mjs:198` | +| E01 | static imports in `queue-read.mjs` | killed, the child's output, `reads.test.mjs:93` | +| E02 | non-2 exit forwards the child's stderr | killed, the 503 body, `reads.test.mjs:97` | +| E03 | redactor without the `:` prefix | killed, redactor test `reads.test.mjs:31` and the seeded page check | +| E04 | `:` prefix without the URL lookahead | killed, `reads.test.mjs:25` and the business read at `:116` | +| E05 | no `~?` | killed, `reads.test.mjs:29` and the seeded page check | +| E06 | no `<` prefix | killed, `reads.test.mjs:31` | +| E07 | Arbiters back to `names()` | killed, `views.test.mjs:169` and `:228` | +| E08 | After back to `qLink` | killed, `views.test.mjs:219` | +| E09 | Required shows the raw value | killed, `views.test.mjs:220` | +| E10 | "since" on any truthy `requiredSince` | **survived**. Note 4 | +| E11 | no notifier `dataRoot` check | killed, `reads.test.mjs:197` | +| E12 | `instanceof` without the null check | **survived**. Note 5 | +| E13 | Arbiters without `\|\| none` | **survived**. Note 6 | +| E14 | After without `when` | killed, `views.test.mjs:219` | + +`mutwt` checks 14 OK after the run (`r2/mut/manifest-after.txt`). The +browser probe ran during D01 and D02, and both died at their own +assertions (`views.test.mjs:158` and `:103`), so the extra load didn't +make a false kill. + +## Notes (not blocking) + +1. `file://localhost/home/u/x` passes through, because a `:` followed by + `//` and a host reads as a URL. Node writes `file:///…` with an empty + host, which is redacted, so I don't see a way for this to reach a + page today. The README's rule describes it. +2. `path` becomes `path<>`, and `http://` alone becomes + `http:`. Both are cosmetic. +3. D22 stays untested, as Dewey says. P5c in round 1 showed the read + works. +4. E10. The store allows `requiredSince: "unknown"` on a required row + (`checkTime` with `unknown: true`, `queue.mjs:330`). The candidate + shows "yes" for it, and the mutant would show "yes since" with a + `