From 1355592f2b9c2f9a2f7f0ce64a73dbfd1fe05edf Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 10 Oct 2026 03:49:12 -0500 Subject: [PATCH] docs(queue-48): darkwing round 1 review, approve Co-Authored-By: Claude Opus 5.5 --- .../r1/candidate-manifest.sha256 | 3 + .../darkwing/work/queue-48-review/r1/gate.sh | 16 ++ .../queue-48-review/r1/mut/delay-close.diff | 17 ++ .../queue-48-review/r1/mut/delay-close.txt | 18 ++ .../queue-48-review/r1/mut/delay-exit.diff | 13 ++ .../queue-48-review/r1/mut/delay-exit.txt | 58 +++++++ .../work/queue-48-review/r1/mut/fake-docker | 5 + .../queue-48-review/r1/mut/manifest-after.txt | 2 + .../work/queue-48-review/r1/mut/mutate.py | 19 +++ .../work/queue-48-review/r1/mut/run.sh | 23 +++ .../work/queue-48-review/r1/mut/summary.txt | 16 ++ .../r1/mut/test-task-fakedocker.txt | 134 +++++++++++++++ .../queue-48-review/r1/out/node-queue.txt | 158 ++++++++++++++++++ .../work/queue-48-review/r1/out/summary.txt | 13 ++ .../work/queue-48-review/r1/out/test-auth.txt | 17 ++ .../queue-48-review/r1/out/test-conductor.txt | 23 +++ .../queue-48-review/r1/out/test-config.txt | 26 +++ .../queue-48-review/r1/out/test-discord.txt | 70 ++++++++ .../r1/out/test-extension-package.txt | 21 +++ .../r1/out/test-foundation.txt | 53 ++++++ .../queue-48-review/r1/out/test-queue.txt | 35 ++++ .../r1/out/test-release-docker.txt | 16 ++ .../queue-48-review/r1/out/test-release.txt | 7 + .../work/queue-48-review/r1/out/test-task.txt | 32 ++++ .../work/queue-48-review/review-r1.md | 118 +++++++++++++ 25 files changed, 913 insertions(+) create mode 100644 agents/darkwing/work/queue-48-review/r1/candidate-manifest.sha256 create mode 100755 agents/darkwing/work/queue-48-review/r1/gate.sh create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/delay-close.diff create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/delay-close.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/delay-exit.diff create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/delay-exit.txt create mode 100755 agents/darkwing/work/queue-48-review/r1/mut/fake-docker create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/manifest-after.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/mutate.py create mode 100755 agents/darkwing/work/queue-48-review/r1/mut/run.sh create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/summary.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/mut/test-task-fakedocker.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/node-queue.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/summary.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-auth.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-conductor.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-config.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-discord.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-extension-package.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-foundation.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-queue.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-release-docker.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-release.txt create mode 100644 agents/darkwing/work/queue-48-review/r1/out/test-task.txt create mode 100644 agents/darkwing/work/queue-48-review/review-r1.md diff --git a/agents/darkwing/work/queue-48-review/r1/candidate-manifest.sha256 b/agents/darkwing/work/queue-48-review/r1/candidate-manifest.sha256 new file mode 100644 index 00000000..eb8bc767 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/candidate-manifest.sha256 @@ -0,0 +1,3 @@ +3107d6a48dbbd7e269bd2b65cdab47f32a7f66f9394b99d5a6c806ec804131ab agents/dewey/work/queue-48/evidence.md +ed4c1d1bdbbc0f4e087aca97a6ce47f0987dffa724c838c4e084b0c1881705ae packages/queue/tests/commit.test.mjs +8b08f75f1350ca14fe4e3879c3f7df4043b1d1dcf6a0a1a9f403193ee0f94125 scripts/test-task.sh diff --git a/agents/darkwing/work/queue-48-review/r1/gate.sh b/agents/darkwing/work/queue-48-review/r1/gate.sh new file mode 100755 index 00000000..99dc3983 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/gate.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Row 48 gate: queue node suite, then every scripts/test-*.sh with Docker unreachable. +export TMPDIR=~/darkwing-scratch/r48a/tmp DOCKER_HOST=unix:///nonexistent.sock +cd ~/darkwing-scratch/r48a/wt +O=~/darkwing-scratch/r48a/out +: > $O/summary.txt +echo "start $(date -u +%FT%TZ)" >> $O/summary.txt +node --test packages/queue/tests/*.test.mjs > $O/node-queue.txt 2>&1; e=$? +echo "node-queue exit=$e $(grep -E '^ℹ (pass|fail)' $O/node-queue.txt | tr '\n' ' ')" >> $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-48-review/r1/mut/delay-close.diff b/agents/darkwing/work/queue-48-review/r1/mut/delay-close.diff new file mode 100644 index 00000000..1dae98f2 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/delay-close.diff @@ -0,0 +1,17 @@ +diff --git a/packages/queue/tests/commit.test.mjs b/packages/queue/tests/commit.test.mjs +index c254dce5..41ee7538 100644 +--- a/packages/queue/tests/commit.test.mjs ++++ b/packages/queue/tests/commit.test.mjs +@@ -166,10 +166,10 @@ async function pausedCommit(t, form) { + const go = join(r.ctl, "editor-go"); + const editor = join(r.ctl, "editor.sh"); + writeFileSync(editor, `#!/bin/sh\n: > ${q(started)}\nwhile [ ! -e ${q(go)} ]; do sleep 0.05; done\necho "ordinary" > "$1"\n`, { mode: 0o755 }); +- const child = spawn("git", ["-C", r.root, "commit", "-e", "-q", ...form], { env: { ...r.env, GIT_EDITOR: editor }, stdio: ["ignore", "pipe", "pipe"] }); ++ const child = spawn("sh", ["-c", 'git "$@" 2>"$0"; s=$?; (sleep 0.5; cat "$0" >&2) & exit $s', join(r.ctl, "git-err"), "-C", r.root, "commit", "-e", "-q", ...form], { env: { ...r.env, GIT_EDITOR: editor }, stdio: ["ignore", "pipe", "pipe"] }); + let childErr = ""; + child.stderr.on("data", (d) => { childErr += d; }); +- const exited = new Promise((resolve) => child.on("exit", resolve)); ++ const exited = new Promise((resolve) => child.on("close", resolve)); + for (let i = 0; i < 200 && !existsSync(started); i++) sleepMs(50); + assert.ok(existsSync(started), "the editor never started"); + const locked = existsSync(join(r.gitDir, "index.lock")); diff --git a/agents/darkwing/work/queue-48-review/r1/mut/delay-close.txt b/agents/darkwing/work/queue-48-review/r1/mut/delay-close.txt new file mode 100644 index 00000000..3933a045 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/delay-close.txt @@ -0,0 +1,18 @@ +✔ F1: an ordinary commit after update-ref is refused until step 8; then it commits and the queue stays at C (1411.374746ms) +✔ F1: a plain `commit -e` whose guard ran before update-ref fails at its own HEAD update (1612.695499ms) +ℹ 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 (1669.334822ms) +ℹ git commit -e -- src.txt: index.lock held during the editor +✔ F1: a queue commit landing after H is recorded: step 1 says HEAD moved, not the guard (1485.27192ms) +✔ F1: a queue commit landing between the HEAD check and the canary: the failed clean run is reported as HEAD moved (1059.81047ms) +✔ F1: a shared-index change during the procedure is not committed (1265.621309ms) +✔ F1: a queue path staged after update-ref: step 8 stops and touches nothing (1259.89775ms) +✔ F1: a missing or a different hook refuses (870.937246ms) +ℹ tests 8 +ℹ suites 0 +ℹ pass 8 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 10712.952509 diff --git a/agents/darkwing/work/queue-48-review/r1/mut/delay-exit.diff b/agents/darkwing/work/queue-48-review/r1/mut/delay-exit.diff new file mode 100644 index 00000000..86c855d5 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/delay-exit.diff @@ -0,0 +1,13 @@ +diff --git a/packages/queue/tests/commit.test.mjs b/packages/queue/tests/commit.test.mjs +index c254dce5..b101cebc 100644 +--- a/packages/queue/tests/commit.test.mjs ++++ b/packages/queue/tests/commit.test.mjs +@@ -166,7 +166,7 @@ async function pausedCommit(t, form) { + const go = join(r.ctl, "editor-go"); + const editor = join(r.ctl, "editor.sh"); + writeFileSync(editor, `#!/bin/sh\n: > ${q(started)}\nwhile [ ! -e ${q(go)} ]; do sleep 0.05; done\necho "ordinary" > "$1"\n`, { mode: 0o755 }); +- const child = spawn("git", ["-C", r.root, "commit", "-e", "-q", ...form], { env: { ...r.env, GIT_EDITOR: editor }, stdio: ["ignore", "pipe", "pipe"] }); ++ const child = spawn("sh", ["-c", 'git "$@" 2>"$0"; s=$?; (sleep 0.5; cat "$0" >&2) & exit $s', join(r.ctl, "git-err"), "-C", r.root, "commit", "-e", "-q", ...form], { env: { ...r.env, GIT_EDITOR: editor }, stdio: ["ignore", "pipe", "pipe"] }); + let childErr = ""; + child.stderr.on("data", (d) => { childErr += d; }); + const exited = new Promise((resolve) => child.on("exit", resolve)); diff --git a/agents/darkwing/work/queue-48-review/r1/mut/delay-exit.txt b/agents/darkwing/work/queue-48-review/r1/mut/delay-exit.txt new file mode 100644 index 00000000..72b73670 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/delay-exit.txt @@ -0,0 +1,58 @@ +✔ F1: an ordinary commit after update-ref is refused until step 8; then it commits and the queue stays at C (1019.923821ms) +✖ F1: a plain `commit -e` whose guard ran before update-ref fails at its own HEAD update (987.757774ms) +ℹ 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 (1002.567379ms) +ℹ git commit -e -- src.txt: index.lock held during the editor +✔ F1: a queue commit landing after H is recorded: step 1 says HEAD moved, not the guard (1435.596039ms) +✔ F1: a queue commit landing between the HEAD check and the canary: the failed clean run is reported as HEAD moved (1023.967614ms) +✔ F1: a shared-index change during the procedure is not committed (1197.76575ms) +✔ F1: a queue path staged after update-ref: step 8 stops and touches nothing (1265.30256ms) +✔ F1: a missing or a different hook refuses (1148.064136ms) +ℹ tests 8 +ℹ suites 0 +ℹ pass 6 +ℹ fail 2 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 9135.584908 + +✖ failing tests: + +test at packages/queue/tests/commit.test.mjs:195:1 +✖ F1: a plain `commit -e` whose guard ran before update-ref fails at its own HEAD update (987.757774ms) + AssertionError [ERR_ASSERTION]: The input did not match the regular expression /cannot lock ref 'HEAD': is at 86e954928bfbe30c3845659fcbc78e6b9a6dd75d but expected 8300cce534f153bba6f53613705e7913099548c1/. Input: + + '' + + at pausedCommit (file:///home/jwoltje/darkwing-scratch/r48a/wt2/packages/queue/tests/commit.test.mjs:186:10) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r48a/wt2/packages/queue/tests/commit.test.mjs:196: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: '', + expected: /cannot lock ref 'HEAD': is at 86e954928bfbe30c3845659fcbc78e6b9a6dd75d but expected 8300cce534f153bba6f53613705e7913099548c1/, + operator: 'match', + diff: 'simple' + } + +test at packages/queue/tests/commit.test.mjs:199:1 +✖ F1: a `commit -e -- path` whose guard ran before update-ref fails at its own HEAD update (1002.567379ms) + AssertionError [ERR_ASSERTION]: The input did not match the regular expression /cannot lock ref 'HEAD': is at e80c11b19ec36f5363799f753548696214e105a7 but expected 53249eecfa65a35d8748e6b1e5b0353649f4b0e6/. Input: + + '' + + at pausedCommit (file:///home/jwoltje/darkwing-scratch/r48a/wt2/packages/queue/tests/commit.test.mjs:186:10) + at process.processTicksAndRejections (node:internal/process/task_queues:104:5) + at async TestContext. (file:///home/jwoltje/darkwing-scratch/r48a/wt2/packages/queue/tests/commit.test.mjs:200: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: '', + expected: /cannot lock ref 'HEAD': is at e80c11b19ec36f5363799f753548696214e105a7 but expected 53249eecfa65a35d8748e6b1e5b0353649f4b0e6/, + operator: 'match', + diff: 'simple' + } diff --git a/agents/darkwing/work/queue-48-review/r1/mut/fake-docker b/agents/darkwing/work/queue-48-review/r1/mut/fake-docker new file mode 100755 index 00000000..d45ecfa7 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/fake-docker @@ -0,0 +1,5 @@ +#!/bin/sh +# Fake docker for the row 48 review: "info" succeeds, everything else goes to +# the real client, which can't reach the daemon (DOCKER_HOST unreachable). +if [ "$1" = info ]; then echo "fake docker info"; exit 0; fi +exec /usr/bin/docker "$@" diff --git a/agents/darkwing/work/queue-48-review/r1/mut/manifest-after.txt b/agents/darkwing/work/queue-48-review/r1/mut/manifest-after.txt new file mode 100644 index 00000000..12362ff4 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/manifest-after.txt @@ -0,0 +1,2 @@ +packages/queue/tests/commit.test.mjs: OK +scripts/test-task.sh: OK diff --git a/agents/darkwing/work/queue-48-review/r1/mut/mutate.py b/agents/darkwing/work/queue-48-review/r1/mut/mutate.py new file mode 100644 index 00000000..eb44182d --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/mutate.py @@ -0,0 +1,19 @@ +# mutate.py : apply one named variant to commit.test.mjs (exact text, must match once). Run from the tree root. +import sys +F = "packages/queue/tests/commit.test.mjs" +SPAWN = 'spawn("git", ["-C", r.root, "commit", "-e", "-q", ...form]' +# git exits with its own status at once; a background subshell keeps the +# stderr pipe open and writes git's message 0.5 s later. +DELAYED = 'spawn("sh", ["-c", \'git "$@" 2>"$0"; s=$?; (sleep 0.5; cat "$0" >&2) & exit $s\', join(r.ctl, "git-err"), "-C", r.root, "commit", "-e", "-q", ...form]' +CLOSE = 'child.on("close", resolve)' +M = { + "delay-close": [(SPAWN, DELAYED)], + "delay-exit": [(SPAWN, DELAYED), (CLOSE, 'child.on("exit", resolve)')], +} +s = open(F).read() +for old, new in M[sys.argv[1]]: + n = s.count(old) + if n != 1: sys.exit(f"{sys.argv[1]}: {n} matches") + s = s.replace(old, new) +open(F, "w").write(s) +print(sys.argv[1], "applied") diff --git a/agents/darkwing/work/queue-48-review/r1/mut/run.sh b/agents/darkwing/work/queue-48-review/r1/mut/run.sh new file mode 100755 index 00000000..549b89f4 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/run.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Runs after the gate: commit.test variants, then test-task with the fake docker. +export TMPDIR=~/darkwing-scratch/r48a/tmp +R=~/darkwing-scratch/r48a; M=$R/mut; W=$R/wt2 +: > $M/summary.txt +echo "start $(date -u +%FT%TZ)" >> $M/summary.txt +for v in delay-exit delay-close; do + (cd $W && git checkout -q -- packages/queue/tests/commit.test.mjs && cp $R/snap/packages/queue/tests/commit.test.mjs packages/queue/tests/ && python3 $M/mutate.py $v && git diff -- packages/queue/tests/commit.test.mjs > $M/$v.diff) + (cd $W && node --test --test-name-pattern="F1: a" packages/queue/tests/commit.test.mjs > $M/$v.txt 2>&1); e=$? + echo "$v exit=$e $(grep -E '^ℹ (pass|fail)' $M/$v.txt | tr '\n' ' ')" >> $M/summary.txt +done +(cd $W && cp $R/snap/packages/queue/tests/commit.test.mjs packages/queue/tests/) +# The candidate's paused-commit tests, unmodified, ten times in a row. +for i in $(seq 1 10); do + (cd $W && node --test --test-name-pattern="F1: a" packages/queue/tests/commit.test.mjs > $M/repeat-$i.txt 2>&1); e=$? + echo "repeat-$i exit=$e $(grep -E '^ℹ (pass|fail)' $M/repeat-$i.txt | tr '\n' ' ')" >> $M/summary.txt +done +# test-task with docker info answering yes and the daemon unreachable. +(cd $W && DOCKER_HOST=unix:///nonexistent.sock PATH=$R/fakebin:$PATH scripts/test-task.sh > $M/test-task-fakedocker.txt 2>&1); e=$? +echo "test-task-fakedocker exit=$e $(grep -E 'passed, [0-9]+ failed' $M/test-task-fakedocker.txt | tail -1)" >> $M/summary.txt +(cd $W && sha256sum -c $R/manifest-mine.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-48-review/r1/mut/summary.txt b/agents/darkwing/work/queue-48-review/r1/mut/summary.txt new file mode 100644 index 00000000..97c1d272 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/summary.txt @@ -0,0 +1,16 @@ +start 2026-10-10T08:45:22Z +delay-exit exit=1 ℹ pass 6 ℹ fail 2 +delay-close exit=0 ℹ pass 8 ℹ fail 0 +repeat-1 exit=0 ℹ pass 8 ℹ fail 0 +repeat-2 exit=0 ℹ pass 8 ℹ fail 0 +repeat-3 exit=0 ℹ pass 8 ℹ fail 0 +repeat-4 exit=0 ℹ pass 8 ℹ fail 0 +repeat-5 exit=0 ℹ pass 8 ℹ fail 0 +repeat-6 exit=0 ℹ pass 8 ℹ fail 0 +repeat-7 exit=0 ℹ pass 8 ℹ fail 0 +repeat-8 exit=0 ℹ pass 8 ℹ fail 0 +repeat-9 exit=0 ℹ pass 8 ℹ fail 0 +repeat-10 exit=0 ℹ pass 8 ℹ fail 0 +test-task-fakedocker exit=1 selftest: 67 passed, 31 failed +end 2026-10-10T08:47:18Z +DONE diff --git a/agents/darkwing/work/queue-48-review/r1/mut/test-task-fakedocker.txt b/agents/darkwing/work/queue-48-review/r1/mut/test-task-fakedocker.txt new file mode 100644 index 00000000..2a8eb90c --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/mut/test-task-fakedocker.txt @@ -0,0 +1,134 @@ +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) +FAIL mock adapter: gate passes on matching mock response (exit 1, expected 0) +OK mock adapter: expect-mismatch recorded (exit 1) +FAIL mismatch reason recorded +OK unknown adapter fails closed (exit 1) +FAIL mission task runs via mock adapter (exit 1, expected 0) +grep: /home/jwoltje/darkwing-scratch/r48a/tmp/tmp.HNVro0rxF9/data/system-prompt.md: No such file or directory +FAIL mission section injected into generated prompt +FAIL retry of mission run succeeds (exit 1, expected 0) +OK retriedFrom lineage recorded +grep: /home/jwoltje/darkwing-scratch/r48a/tmp/tmp.HNVro0rxF9/data/system-prompt.md: No such file or directory +FAIL mission section present after retry (relative path resolved) +OK retry of missing run exits 4 (exit 4) +OK skill install bundled ms-tools (exit 0) +OK installed to skills-available +OK double install refuses (exit 1) +OK activate enables skill (exit 0) +OK enabled dir populated +OK uninstall while enabled refuses (exit 1) +OK deactivate moves back to available (exit 0) +OK uninstall removes from available (exit 0) +FAIL seat with enabled skill launches (exit 1) +SEATCASE stderr: +failed to connect to the docker API at unix:///nonexistent.sock; check if the path is correct and if the daemon is running: dial unix /nonexistent.sock: connect: no such file or directory +FAIL skill path delivered to adapter +OK shipped researcher contract resolves (ceiling + network) +OK resolve-role refuses a non-role document (conductor policy) (exit 2) +OK resolve-role refuses name/filename mismatch (exit 2) +OK resolve-role refuses unknown network declaration (exit 2) +OK resolve-role refuses duplicate role tool (exit 2) +OK resolve-role refuses unsupported tool (exit 2) +OK resolve-role refuses missing contract file (exit 4) +OK version 1 role prints no contract line +OK shipped version 2 roles resolve with their contracts (pm, cto, coder, reviewer) +OK resolve-role accepts a minimal version 2 role (exit 0) +OK resolve-role refuses an action outside the vocabulary (exit 2) +OK resolve-role refuses a gated-only action in a role file (exit 2) +OK resolve-role refuses a Vikunja verb no role may hold (exit 2) +OK resolve-role refuses a version 2 role whose contract is missing (exit 2) +OK resolve-role refuses a contract that is a symbolic link (exit 2) +FAIL seat launches under role ceiling (exit 1) +ROLESEAT stderr: +agent: capability policy: role 'analyst' ceiling narrowed tools -> read,bash +failed to connect to the docker API at unix:///nonexistent.sock; check if the path is correct and if the daemon is running: dial unix /nonexistent.sock: connect: no such file or directory +FAIL role ceiling narrows seat tools (read,write,bash -> read,bash) +OK narrowing recorded loudly +OK missing role contract refuses launch (exit 2) +OK missing-contract refusal names the role +FAIL empty ceiling intersection -> tool-free seat +OK tool-free outcome recorded loudly +OK overridden agents dir without seat definition refuses (exit 4) +OK seat-resolution refusal names the seat +FAIL policy: mission only -> mission tools +FAIL policy: task only -> task tools +FAIL policy: both -> intersection (task narrowed) +FAIL policy: empty intersection -> tool-free +OK invalid mission capabilities rejected (exit 2) +mosaic-task: unsupported mission tool: "sudo" (supported: read, write, edit, bash, grep, find, ls) +FAIL task run with user layer present (exit 1, expected 0) +grep: /home/jwoltje/darkwing-scratch/r48a/tmp/tmp.HNVro0rxF9/data/system-prompt.md: No such file or directory +FAIL user context dispatched into generated prompt +FAIL workspace+tools task runs via mock (exit 1, expected 0) +FAIL workspace path + tools delivered to adapter +OK persistent workspace created on host +FAIL plain task still runs (no workspace/tools) (exit 1, expected 0) +FAIL workspace var present but empty when absent +FAIL tools empty when absent +OK unknown tool exits 2 (exit 2) +OK workspace traversal exits 2 (exit 2) +FAIL live hello task succeeds with exact marker +--- latest run evidence: /home/jwoltje/darkwing-scratch/r48a/tmp/tmp.HNVro0rxF9/data/runs/r-20261010T084717Z-c421be --- +--- stderr.txt (tail) --- +OK result.json written in run dir +FAIL result.json contents are correct +FAIL wrong expectExact (exit 1, reason: 'exit-nonzero') +--- latest run evidence: /home/jwoltje/darkwing-scratch/r48a/tmp/tmp.HNVro0rxF9/data/runs/r-20261010T084718Z-fccf9d --- +--- stderr.txt (tail) --- +OK each run gets a distinct run dir (no clobber) +OK list shows both runs +FAIL fork base: teach succeeds (exit 1, expected 0) +FAIL fork child recalls ancestor context (exit 4, expected 0) +node:fs:621 + return binding.readFileUtf8(path, stringToFlags(options.flag)); + ^ + +Error: ENOENT: no such file or directory, open '/home/jwoltje/darkwing-scratch/r48a/tmp/tmp.HNVro0rxF9/data/runs/r-20261010T084718Z-5a44e7/result.json' + at Object.readFileSync (node:fs:621:20) + at [eval]:1:34 + at runScriptInThisContext (node:internal/vm:219:10) + at node:internal/process/execution:485:12 + at [eval]-wrapper:6:24 + at runScriptInContext (node:internal/process/execution:483:60) + at evalFunction (node:internal/process/execution:317:30) + at evalTypeScript (node:internal/process/execution:329:3) + at node:internal/main/eval_string:71:3 { + errno: -2, + code: 'ENOENT', + syscall: 'open', + path: '/home/jwoltje/darkwing-scratch/r48a/tmp/tmp.HNVro0rxF9/data/runs/r-20261010T084718Z-5a44e7/result.json' +} + +Node.js v26.8.1 +FAIL forked child recalled ancestor code word +OK ancestor session untouched by fork +FAIL child session dir has its own branch file +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 +FAIL user recall run succeeds (exit 1) +FAIL recalled user name (response: ) +OK no agent identity on headless run + +selftest: 67 passed, 31 failed diff --git a/agents/darkwing/work/queue-48-review/r1/out/node-queue.txt b/agents/darkwing/work/queue-48-review/r1/out/node-queue.txt new file mode 100644 index 00000000..b14b3aae --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/node-queue.txt @@ -0,0 +1,158 @@ +✔ F1: an ordinary commit after update-ref is refused until step 8; then it commits and the queue stays at C (1531.501337ms) +✔ F1: a plain `commit -e` whose guard ran before update-ref fails at its own HEAD update (1161.077924ms) +ℹ 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 (1083.010591ms) +ℹ 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 (1215.184151ms) +✔ F1: HEAD moving after the step-7 guard check and before update-ref: refused, nothing published (1184.065991ms) +✔ F1: H is recorded before the canary, so HEAD moving during the step-1 canary is refused at step 7 (1128.47923ms) +✔ F1: a queue commit landing after H is recorded: step 1 says HEAD moved, not the guard (1342.058049ms) +✔ F1: a queue commit landing between the HEAD check and the canary: the failed clean run is reported as HEAD moved (947.181707ms) +✔ F1: a shared-index change during the procedure is not committed (1130.0633ms) +✔ F1: a queue path staged after update-ref: step 8 stops and touches nothing (1040.512442ms) +✔ F1: a missing or a different hook refuses (739.480406ms) +✔ F1: same bytes without the exec bit, a symlinked hook, and core.hooksPath in the local or global scope each refuse before update-ref (1169.125226ms) +✔ F1: the canary refuses a hook that git would not run (661.843976ms) +✔ F1: the guard deactivated after step 1 is refused at the step-7 recheck (935.428692ms) +✔ bootstrap: implementation-only HEAD, the guard, genesis, the --genesis commit, then an extending commit (898.575201ms) +✔ bootstrap: --genesis with a base present, no base without --genesis, an op before the first commit, a changed map, another branch (936.249459ms) +✔ bootstrap: the archived tests and validator run outside any repository (868.280964ms) +✔ general: an unrelated staged file stays staged, and the committed blobs are the snapshot bytes (949.350742ms) +✔ general: a queue write after the snapshot is not committed (1330.564723ms) +✔ general: a snapshot whose log does not extend the base refuses (1197.082601ms) +✔ general: install-hook privilege, repair of a same-bytes hook, and its refusals (160.827838ms) +✔ general: environment overrides, a linked worktree and usage (671.473149ms) +✔ general: a queue path staged before the run refuses at step 1 (766.792514ms) +✔ general: HEAD's queue tests failing in the archive refuse (887.336513ms) +✔ genesis document serializes deterministically and replays (4.026047ms) +✔ a hand edit that stays valid JSON fails replay; a formatting-only edit fails re-serialization (2.298581ms) +✔ a tampered result, receipt or viewSha fails replay (2.147875ms) +✔ op ids: 8 to 72 characters for callers, 80 in the log for .outcome entries (0.151213ms) +✔ add: defaults for an ordinary seat, privileged extras, refusals (4.593521ms) +✔ matrix: queued→briefed privileged; briefed→in-progress owner with after satisfied (7.483789ms) +✔ matrix: release, review round, changes requested and waiting-on-jason (17.27717ms) +✔ matrix J5: in-review→done by the gate owner with evidence naming the current round (10.978861ms) +✔ review issue, lead decision 23: none refuses, one is used, several need --issue, later rounds keep it (20.602956ms) +✔ the row schema refuses a round with a null issue, and the A1 review shape (P2) (3.172689ms) +✔ matrix R1: every state × target × actor class matches 8.7, gate owner jason or not, required or not (1553.614941ms) +✔ matrix: blocked keeps the claim and returns only to previousState (3.693869ms) +✔ matrix J4: parking is Jason's, refused while required; unpark returns to queued (2.470748ms) +✔ field edits: who may change what (6.546166ms) +✔ set issues keeps a logged narrowing of closes (N10) (4.13696ms) +✔ text the table shows refuses \ and <, everywhere it enters (N8) (1.952963ms) +✔ every accepted text renders to nine cells on every row (N8) (23.261139ms) +✔ genesis: the map refuses an owner among its row's reviewers; replay doesn't (2026-10-04) (0.524363ms) +✔ times and dates must be calendar values, not just the shape (2026-10-04) (1.507788ms) +✔ replay holds every op id to the caller's rule (N11) (5.050325ms) +✔ note: owner, listed reviewer or privileged; empty clears (1.109607ms) +✔ assign moves the claim with the owner; done clears it (2.474914ms) +✔ render is byte-stable and escapes pipes (0.496042ms) +✔ view classification: current, genuine stale, edited stale marker, changed current body, markers (0.594203ms) +✔ next: resume, then review, then start, then wait, then nothing; lowest id first (22.585954ms) +✔ canonical args make a retry's identity independent of list order (0.33659ms) +✔ manifests, headings and blob ids (0.538689ms) +✔ the migration map: one queue-map block, exact keys (0.656175ms) +✔ every call but `queue` reaches the seat CLI exactly as before A2 (670.022459ms) +✔ `queue` reaches the queue CLI with the rest of the arguments (213.8728ms) +✔ the pre-A2 fixture is the script A2 changed (1.513614ms) +✔ acquire publishes the record by link; release removes only its own lock (10.159169ms) +✔ a kill between the temp write and the link leaves no lock (67.158611ms) +✔ a short or failed temp write refuses and leaves no lock and no temp (9.122205ms) +✔ a link error other than EEXIST refuses (11.688567ms) +✔ an error after the link releases the lock: unreadable gate, failing temp stat (24.423932ms) +✔ a release that fails on a gate path is reported, never a stack trace (P1) (47.551358ms) +✔ a paused holder: another writer waits 10 s, then refuses naming it live (10102.409604ms) +✔ two concurrent unlockers: the second refuses on the gate (40.058729ms) +✔ a writer publishing during an unlock, lock first: unlock sees it live and refuses (14.018763ms) +✔ a writer publishing during an unlock, gate first: the writer releases and refuses (11.026477ms) +✔ a gate swapped while held is left in place and reported, on success and on refusal (N1) (11.233607ms) +✔ a reused pid within one boot is mismatch; unlock removes the lock and never signals the process (12.211658ms) +✔ the same pid and start on a different boot is mismatch (1.345584ms) +✔ a foreign host is unknown whatever the local pid says; unlock refuses (69.410494ms) +✔ unreadable /proc: classification is unknown and acquire refuses (0.63259ms) +✔ invalid records: empty, unparsable, wrong keys, bad start or boot (0.192671ms) +✔ a stale gate blocks writers; --check-gate says mismatch for a reused pid (19.27061ms) +✔ a delayed release by a dead owner, after unlock and a new owner: the inode check keeps the new lock (21.173216ms) +✔ release checks the inode too: a byte-identical lock file with a new inode is left in place (7.482332ms) +✔ unlock refuses a live, unknown or invalid lock, and does nothing without one (31.341033ms) +✔ the migration map validates and renders the golden genesis table (4.280454ms) +✔ the marked QUEUE.md holds every row and parked item between its markers (1.700032ms) +✔ map-check reports each kind of drift (4.957619ms) +✔ a request posts once as the requester; a retry sends nothing (1027.42552ms) +✔ each transport answer maps to posted, failed or uncertain (8.9 step 3) (5056.627475ms) +✔ the pre-send checks: GET user must name the requester, under the deadline (1807.060537ms) +✔ the lead's request refuses a token for login sage (896.678358ms) +✔ the credential file: the seat's own, 0600, no symlink, never the shared default (781.945755ms) +✔ an unresolved request blocks a new request, a new round, waiting-on-jason and done (2225.736661ms) +✔ a same-op retry after a kill sends nothing, even with a stale view (2988.433742ms) +✔ a held lock at the outcome exits 3 and names what the transport said (691.126594ms) +✔ late outcomes: after an abandon, and after a resolve with the same or another id (2263.964507ms) +✔ resolve checks the comment: issue, markers, round, candidate and author (1723.878652ms) +✔ the lead resolves a seat's request: the comment's author is the requester, fetched with the lead's token (734.561187ms) +✔ validateRow checks a request round's shape, which every replayed entry must keep (532.640941ms) +✔ request, changes, a new candidate, approval: every round pinned; no review files (2188.598637ms) +✔ a row with no reviewers opens a round that posts nothing (1206.674425ms) +✔ verify-commit: a prospective tree must hold exactly the candidate's paths (1795.85522ms) +✔ semantics: v1 entries replay as before; review entries need v2 (709.091871ms) +✔ set reviewers refuses the row's owner (2026-09-28) (361.989356ms) +✔ the owner records no verdict, even as a listed reviewer (514.455279ms) +✔ a request comment over the length limit is not sent (601.634189ms) +✔ a late POST on a closed row leaves a conflict nothing can resolve, and resolve asks nothing (983.019857ms) +✔ a Jason-gated row reaches waiting-on-jason only on every reviewer's approval (4427.326493ms) +✔ genesis: refusals before anything is written (453.091743ms) +✔ genesis: the map must be committed, well formed, with committed briefs and seats (738.032363ms) +✔ genesis: markers, a stray witness, once only; a retry returns the receipt (705.369058ms) +✔ genesis: a file holding genesis alone with no witness is confirmed by sync or a retry (487.089577ms) +✔ canonical checks: worktree, second clone, detached HEAD, wrong branch, GIT_DIR, foreign code; a symlink works (713.997434ms) +✔ --by that differs from MOSAIC_AGENT_NAME warns on stderr and logs nothing more (N12) (921.685533ms) +✔ op ids: missing, too long, reserved; a retry answers; another payload refuses (800.244923ms) +✔ a retried add returns the id it first allocated, after reassignment and after done (1084.80495ms) +✔ Rocko's S4 schedule: a lost result, another writer, then the retry opens no second round (819.846ms) +✔ the review issue and the evidence round through the CLI (lead decision 23, 8.7) (1319.403243ms) +✔ claims and add defaults through the CLI; candidates are manifests or reachable commits (774.41141ms) +✔ add, set reviewers and assign refuse the row's owner as a reviewer (499.086804ms) +✔ the working-brief check: a changed working copy refuses the start and flags next (648.106951ms) +✔ next: resume first, then nothing for an idle seat; needs a seat (368.110729ms) +✔ view stale: new ops and verify refuse naming the unshown op; retries answer; reads warn; render fixes (678.034104ms) +✔ view unknown: a hand edit, an old marker over an edited body, missing or duplicate markers (1184.889423ms) +✔ a hand edit to queue.json refuses every verb, reads included (570.452253ms) +✔ verify and render --check leave bytes and mtimes unchanged (416.969308ms) +✔ render is byte-stable across runs and repositories (324.131877ms) +✔ snapshot and verify --snapshot (761.556178ms) +✔ usage errors exit 4 (503.602105ms) +✔ a short write, ENOSPC or a file fsync failure: nothing visible, temp removed (401.229971ms) +✔ a rename failure: nothing visible, temp removed (204.432783ms) +✔ a directory fsync failure: uncertain, exit 3, no receipt; the tail refuses new ops; a retry confirms (337.21166ms) +✔ a directory fsync failure, then sync names the op (424.153558ms) +✔ a witness write failure: uncertain, durable, exit 3; the view is untouched (311.285092ms) +✔ the .git fsync after the witness rename fails: uncertain, exit 3, the witness says so (232.10849ms) +✔ confirming a tail fsyncs queue.json and docs/plans before the witness; either failure changes nothing (263.277107ms) +✔ the docs/plans fsync after the view rename fails: the op stands, the view is written, a warning says so (203.425485ms) +✔ a lock swapped while held is left in place and reported, on a receipt and on a refusal (235.683469ms) +✔ a lock that cannot be released after an op is reported, on a receipt and on a refusal (235.375ms) +✔ unlock prints a swapped gate's warning on stderr, the result on stdout (150.82536ms) +✔ a view write that fails keeps the op and reports a stale view (211.642707ms) +✔ SIGKILL before the rename: nothing recorded; the retry removes the leftover temp (690.824969ms) +✔ SIGKILL after the rename, before the witness: the tail refuses new ops and sync names the op (724.641647ms) +✔ SIGKILL after the witness, before the view: the stale refusal names the op (700.191807ms) +✔ SIGKILL after the view, before the receipt: the retry returns the receipt (728.279727ms) +✔ git checkout between steps 1 and 7: step 7 refuses and nothing is written (318.332383ms) +✔ git stash restoring an older valid pair: history lost; accept-history needs privilege, a reason and --yes (1158.650713ms) +✔ a deleted witness: refused after the locked recheck; accept-history records it absent (347.20694ms) +✔ a header edit during a write: the op stands, the view write is skipped with a warning (195.357948ms) +✔ a reader paused between the witness and the file while a writer finishes: no lost-history report (209.29275ms) +✔ file-then-witness order forced by a hook: the locked recheck prevents a false report (222.653744ms) +✔ a writer paused before and after the witness rename: readers see a tail, then a match (207.50805ms) +✔ a true rollback is reported only after the locked recheck; a held lock names its holder instead (589.973193ms) +✔ an accept-history in progress: an unlocked reader waits on the lock and never reports lost history (584.936039ms) +✔ the platform check refuses other filesystems (190.20406ms) +✔ tmpfs passes only a test layer that allows it (N5) (236.81327ms) +✔ unlock keeps a multi-line lock record on stdout (P3) (217.332847ms) +ℹ tests 148 +ℹ suites 0 +ℹ pass 148 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 33598.350827 diff --git a/agents/darkwing/work/queue-48-review/r1/out/summary.txt b/agents/darkwing/work/queue-48-review/r1/out/summary.txt new file mode 100644 index 00000000..c0e58851 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/summary.txt @@ -0,0 +1,13 @@ +start 2026-10-10T08:43:13Z +node-queue exit=0 ℹ pass 148 ℹ fail 0 +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-10T08:45:19Z +DONE diff --git a/agents/darkwing/work/queue-48-review/r1/out/test-auth.txt b/agents/darkwing/work/queue-48-review/r1/out/test-auth.txt new file mode 100644 index 00000000..ac228760 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-auth.txt @@ -0,0 +1,17 @@ +OK status with missing harness credential exits 3 and still lists accounts +OK status reports harness credential (read-only) + mosaic accounts +OK api key material never reaches output +OK oauth token material never reaches output +OK unparseable credential file exits 2 +OK symlinked credential file exits 4 +OK env-side credential names reported +OK env var values never reach output +OK accounts without an accounts dir reports none and creates nothing +OK accounts lists files and marks the active one +OK loose account perms flagged in listing +OK agent --auth with missing account file refuses (exit 4) +OK agent --auth with non-0600 account file refuses +OK agent --auth with invalid account name refuses +OK auth.sh without valid config refuses + +selftest: 15 passed, 0 failed diff --git a/agents/darkwing/work/queue-48-review/r1/out/test-conductor.txt b/agents/darkwing/work/queue-48-review/r1/out/test-conductor.txt new file mode 100644 index 00000000..62afc513 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-conductor.txt @@ -0,0 +1,23 @@ +On branch refactor +Your branch is up to date with 'origin/refactor'. + +nothing to commit, working tree clean +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-48-review/r1/out/test-config.txt b/agents/darkwing/work/queue-48-review/r1/out/test-config.txt new file mode 100644 index 00000000..76c05ef7 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-config.txt @@ -0,0 +1,26 @@ +OK absent adapter defaults to pi +OK adapter mock validates (exit 0) +OK unsupported adapter exits 2 (exit 2) +OK env exports adapter +OK bootstrap creates default when absent (exit 0) +OK bootstrap wrote config file +OK bootstrap is idempotent on existing config (exit 0) +OK bootstrap did not rewrite existing config +OK validate missing config exits 3 (exit 3) +OK malformed JSON exits 2 (exit 2) +OK unsupported configVersion exits 2 (exit 2) +OK unknown top-level key exits 2 (exit 2) +OK unknown execution key exits 2 (exit 2) +OK unsupported backend exits 2 (exit 2) +OK unsupported environment exits 2 (exit 2) +OK relative dataRoot exits 2 (exit 2) +OK non-canonical dataRoot exits 2 (exit 2) +OK filesystem root dataRoot exits 2 (exit 2) +OK home directory dataRoot exits 2 (exit 2) +OK dataRoot containing config dir exits 2 (exit 2) +OK control character in provider exits 2 (exit 2) +OK symlinked config file exits 2 (exit 2) +OK env exports resolve correctly +OK failed validation modified nothing + +selftest: 24 passed, 0 failed diff --git a/agents/darkwing/work/queue-48-review/r1/out/test-discord.txt b/agents/darkwing/work/queue-48-review/r1/out/test-discord.txt new file mode 100644 index 00000000..b013f9ff --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-discord.txt @@ -0,0 +1,70 @@ +toolchain: node v26.8.1 + +OK syntax: packages/discord/src/approvals.mjs +OK syntax: packages/discord/src/authorize.mjs +OK syntax: packages/discord/src/binding.mjs +OK syntax: packages/discord/src/cli.mjs +OK syntax: packages/discord/src/connector.mjs +OK syntax: packages/discord/src/context.mjs +OK syntax: packages/discord/src/engine-pi.mjs +OK syntax: packages/discord/src/errors.mjs +OK syntax: packages/discord/src/gateway.mjs +OK syntax: packages/discord/src/git.mjs +OK syntax: packages/discord/src/journal.mjs +OK syntax: packages/discord/src/notify.mjs +OK syntax: packages/discord/src/rest.mjs +OK syntax: packages/discord/src/setspark.mjs +OK syntax: packages/discord/src/tools.mjs +OK syntax: packages/discord/src/web.mjs +OK syntax: packages/discord/bin/git-credential.mjs +OK syntax: packages/discord/extension/tools.mjs +OK syntax: packages/discord/tests/approvals.test.mjs +OK syntax: packages/discord/tests/authorize.test.mjs +OK syntax: packages/discord/tests/binding.test.mjs +OK syntax: packages/discord/tests/connector.test.mjs +OK syntax: packages/discord/tests/context.test.mjs +OK syntax: packages/discord/tests/engine.test.mjs +OK syntax: packages/discord/tests/fake-pi.mjs +OK syntax: packages/discord/tests/gateway.test.mjs +OK syntax: packages/discord/tests/git.test.mjs +OK syntax: packages/discord/tests/helpers.mjs +OK syntax: packages/discord/tests/journal.test.mjs +OK syntax: packages/discord/tests/notify.test.mjs +OK syntax: packages/discord/tests/recover.test.mjs +OK syntax: packages/discord/tests/rest.test.mjs +OK syntax: packages/discord/tests/setspark.test.mjs +OK syntax: packages/discord/tests/tools.test.mjs +OK syntax: packages/discord/tests/web.test.mjs +OK syntax: packages/discord/fixtures/claim-worker.mjs +OK syntax: packages/discord/fixtures/legacy-owner-worker.mjs +OK syntax: scripts/discord.sh +OK syntax: scripts/discord-service.sh +OK packages/discord declares no dependencies +OK no bot-token-shaped string in packages/discord +OK fixture binding uses placeholder ids only +OK fixture binding validates +OK real pi with the extension exposes exactly list_dir, read_file, search and no built-in tool +OK real pi with a writable root exposes exactly the three reads plus write_file and edit_file, and writes nothing at start +OK real pi with a web key exposes the three reads plus web_fetch and web_search, and no write tool without a writable root +OK real pi with a git root exposes the reads, writes and the four git verbs, commits nothing at start, and never shows the token +OK real pi with protocol vault adds reserve_id to the git verbs +OK real pi with a setspark key exposes the reads and the eight record verbs, no counters, and never shows the key +OK real pi refuses a git key on a read-only root (fail closed) +OK real pi with the pilot flags (--no-tools) exposes no tool at all +OK real pi exits non-zero without MOSAIC_DISCORD_TOOLS: no session, no tools (fail closed) +OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT +OK node --test packages/discord/tests/ (ℹ pass 178) +OK scripts/discord.sh --help exits 0 +OK scripts/discord.sh check without a binding exits 4 +OK scripts/discord.sh recover without a binding exits 4 +OK scripts/discord.sh reload without a binding exits 4 +OK scripts/discord-service.sh without a command exits 4 +OK service unit renders with the repository path, a supervised run as the main process, exit 3 never retried, and reload as SIGHUP +OK service install writes the rendered unit (0644) and leaves no temp file +OK service install a second time reports unchanged +OK systemd-analyze verify accepts the rendered unit +OK service uninstall removes the unit file +OK service install with an unknown flag exits 4 +OK service install with USER unset finishes and names the account for lingering + +discord suite: 66 passed, 0 failed diff --git a/agents/darkwing/work/queue-48-review/r1/out/test-extension-package.txt b/agents/darkwing/work/queue-48-review/r1/out/test-extension-package.txt new file mode 100644 index 00000000..e2be6937 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-extension-package.txt @@ -0,0 +1,21 @@ +OK initial ordinary-file install +OK installed tree matches canonical source +OK installed tree has no symlinks +OK check detects installation drift +OK sync refuses to overwrite installation drift +OK check detects an extra destination file +OK check detects an extra destination directory +OK check rejects a destination symlink +OK sync accepts a canonical source update +OK updated installation matches canonical source +scripts/test-extension-package.sh: line 14: 358493 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-48-review/r1/out/test-foundation.txt b/agents/darkwing/work/queue-48-review/r1/out/test-foundation.txt new file mode 100644 index 00000000..6338e1e6 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-foundation.txt @@ -0,0 +1,53 @@ +toolchain: node v26.8.1, python 3.12.8, jsonschema 4.26.0 + +OK syntax: scripts/foundation-inspect.mjs +OK syntax: scripts/foundation/strict-json.mjs +OK syntax: scripts/foundation/canonical.mjs +OK syntax: scripts/foundation/resolve.mjs +OK syntax: scripts/foundation/validate-record.mjs +OK syntax: scripts/foundation/fixtures/build-fixtures.mjs +OK syntax: scripts/foundation/canonical.test.mjs +OK syntax: scripts/foundation/cli.test.mjs +OK syntax: scripts/foundation/fixtures.test.mjs +OK syntax: scripts/foundation/resolve.test.mjs +OK syntax: scripts/foundation/strict-json.test.mjs +OK syntax: scripts/foundation/verify-schema.py (ast only; no bytecode written) +OK fixture generator runs +OK checked-in fixtures/bundles equal a fresh generation +OK checked-in fixtures/raw equal a fresh generation +OK checked-in fixtures/index.json equal a fresh generation +OK checked-in demo bundles equal a fresh generation +OK a failing nested test fails the run under a parent runner's NODE_TEST_CONTEXT +OK node --test scripts/foundation/ (ℹ pass 80) +OK differential schema oracle: PASS: differential schema oracle (finite corpus; compatibility evidence, not equivalence proof) + platform witness: strftime('%Y') for year 999 -> '999' (pinned checker refuses years 0001..0999) + node v26.8.1; corpus 1568 records (38 pinned fixtures, 478 unique bundle records, 1052 typeCase/mutation/lexical cases) + schema column: agree-valid 540, agree-invalid 991, DISAGREEMENTS 0; strict-only (parser-bound) cases: 27; unsupported-kind records not schema-assessed by the inspector: 10 + profile column (schema-valid records only): profile-valid 510, profile-invalid 30 + profile refusals asserted: 30 schema-agreed-valid records refused only by the strict typed-string profile (rule profile-pattern-mismatch), 12 declared by name; 73 named probes verified against declared schema/profile columns +OK oracle: zero schema-column disagreements with the pinned checker +OK oracle: strict-only profile refusals are counted and asserted +OK demo: permitted read preview exits 0 (exit 0) +OK demo: permitted file.change preview exits 0 (exit 0) +OK demo: assignment.change proposal is unresolved (exit 3) (exit 3) +OK demo: revoked registration is refused (exit 3) (exit 3) +OK demo: message is not authority (exit 3) (exit 3) +OK usage: no arguments exits 2 (exit 2) +OK io: missing file exits 4 (exit 4) +OK io: directory exits 4 (exit 4) +OK io: symlink exits 4 (O_NOFOLLOW) (exit 4) +OK bound: oversize fixture exits 2 (exit 2) +OK profile: one final LF in a typed selection id is refused before admission (exit 2) (exit 2) +OK profile: two final LFs fail the schema pattern itself (exit 2) (exit 2) +OK profile: escaped newlines in free-form text stay allowed (exit 0) (exit 0) +OK profile refusal is invalid-request/profile-pattern-mismatch with selection and operation withheld, value not echoed +OK text output starts with the disclaimer +OK json output is valid JSON with result allowed and exactly the charter §7 fields +OK json golden matches byte-for-byte +OK sandboxed bundle run (env -i, PATH=/nonexistent) produced the unresolved proposal +OK sandbox inventory (path/type/size/mode/uid/gid/inode/mtime/sha256) unchanged by runs +OK canary never printed (bundle run and credential-file run) +OK a non-bundle JSON file is refused at the shape gate, not read into output +OK no field of the non-bundle file is echoed + +selftest: 44 passed, 0 failed diff --git a/agents/darkwing/work/queue-48-review/r1/out/test-queue.txt b/agents/darkwing/work/queue-48-review/r1/out/test-queue.txt new file mode 100644 index 00000000..1c3b5aef --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-queue.txt @@ -0,0 +1,35 @@ +toolchain: node v26.8.1, git version 2.55.0 + +OK syntax: packages/queue/src/cli.mjs +OK syntax: packages/queue/src/errors.mjs +OK syntax: packages/queue/src/io.mjs +OK syntax: packages/queue/src/lock.mjs +OK syntax: packages/queue/src/queue.mjs +OK syntax: packages/queue/src/review.mjs +OK syntax: packages/queue/src/store.mjs +OK syntax: packages/queue/tests/commit.test.mjs +OK syntax: packages/queue/tests/data.test.mjs +OK syntax: packages/queue/tests/dispatch.test.mjs +OK syntax: packages/queue/tests/helpers.mjs +OK syntax: packages/queue/tests/lock.test.mjs +OK syntax: packages/queue/tests/migration.test.mjs +OK syntax: packages/queue/tests/review.test.mjs +OK syntax: packages/queue/tests/store.test.mjs +OK syntax: packages/queue/tests/write.test.mjs +OK syntax: packages/queue/tests/fixtures/fake-gitea.mjs +OK syntax: packages/queue/tests/fixtures/kill-at.mjs +OK syntax: packages/queue/tests/fixtures/lock-child.mjs +OK syntax: packages/queue/tests/fixtures/mosaic-pre-a2.sh +OK syntax: scripts/queue-commit.sh +OK syntax: scripts/git-hooks/pre-commit +OK syntax: scripts/mosaic +OK queue-commit.sh, the guard and scripts/mosaic are executable +OK packages/queue declares no dependencies +ℹ tests 148 +ℹ pass 148 +ℹ fail 0 +OK node --test packages/queue/tests/ +OK scripts/mosaic queue help +skip queue verify and render --check: this checkout (/home/jwoltje/darkwing-scratch/r48a/wt) 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-48-review/r1/out/test-release-docker.txt b/agents/darkwing/work/queue-48-review/r1/out/test-release-docker.txt new file mode 100644 index 00000000..7202b85d --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-release-docker.txt @@ -0,0 +1,16 @@ +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 diff --git a/agents/darkwing/work/queue-48-review/r1/out/test-release.txt b/agents/darkwing/work/queue-48-review/r1/out/test-release.txt new file mode 100644 index 00000000..1d6ed050 --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-release.txt @@ -0,0 +1,7 @@ +OK valid RELEASE resolves (exit 0) +OK invalid RELEASE exits 1 (exit 1) +OK missing RELEASE exits 1 (exit 1) +OK valid RELEASE leaves image tag consistent with version +skip state-machine cases (docker daemon unavailable) + +selftest: 4 passed, 0 failed diff --git a/agents/darkwing/work/queue-48-review/r1/out/test-task.txt b/agents/darkwing/work/queue-48-review/r1/out/test-task.txt new file mode 100644 index 00000000..cd89fe9b --- /dev/null +++ b/agents/darkwing/work/queue-48-review/r1/out/test-task.txt @@ -0,0 +1,32 @@ +OK valid task validates (exit 0) +OK unknown task key exits 2 (exit 2) +OK unsupported taskVersion exits 2 (exit 2) +OK invalid task id exits 2 (exit 2) +OK empty prompt exits 2 (exit 2) +OK NUL in expectExact exits 2 (exit 2) +OK out-of-range timeout exits 2 (exit 2) +OK missing mission file exits 4 (exit 4) +OK task with valid mission validates (exit 0) +OK invalid mission exits 2 (exit 2) +OK validate missing task exits 4 (exit 4) +OK validation does not modify the task file +OK prune dry-run exits 0 (exit 0) +OK dry-run deleted nothing +OK prune --keep=2 --yes removes oldest (exit 0) +OK kept exactly 2 newest runs +OK newest run kept, oldest pruned +OK append-only receipt written (3 entries) +OK sessions/workspaces untouched by prune +OK prune with invalid keep exits 4 (exit 4) +skip adapter seam cases (docker daemon unavailable) +skip workspace/capability cases (docker daemon unavailable) +skip live task cases (docker unavailable) +OK onboard without name exits 4 (non-interactive) (exit 4) +OK onboard --name renders profile (exit 0) +OK profile written +OK canon structure: required filled, optional placeholdered +OK canon sections present +skip live recall pair: user recall run, recalled user name (docker daemon unavailable) +OK no agent identity on headless run + +selftest: 26 passed, 0 failed diff --git a/agents/darkwing/work/queue-48-review/review-r1.md b/agents/darkwing/work/queue-48-review/review-r1.md new file mode 100644 index 00000000..a80ab2ca --- /dev/null +++ b/agents/darkwing/work/queue-48-review/review-r1.md @@ -0,0 +1,118 @@ +# Row 48, test hygiene, round 1 review (Darkwing) + +Issue #1534, request comment 27097, notes comment 27098, queue revs +317-319. Brief: `docs/plans/2026-10-10_s5-follow-up-and-hygiene.md`, +section "Test hygiene: commit.test exit wait and test-task Docker skip". +Base `5e87c41f`, which differs from `2d935f59` only in `docs/plans/QUEUE.md` +and `docs/plans/queue.json`. Candidate manifest sha256 +`285a4ec13d3b2a9419911e7b0cc3ffe3af99dd8e564dea69eace339319df5259`. It +lists three files: the two changed files and Dewey's `evidence.md`. All +three check OK in the canonical tree. + +Verdict: **approve**. Both changes do what the brief's "What ships" asks. +Without Docker, the recall pair prints a skip and leaves both counts +alone. When `docker info` says yes and the run fails, both checks still +fail. Waiting on `close` fixes the stderr race, and I reproduced the race +the same way Dewey did. Nothing blocks. I have three small notes. + +## Method + +- I read the diff in full and the brief's section, then compared the new + guard and skip line against the three Docker guards already in + `test-task.sh` (lines 139, 395, 442). They use the same `docker info` + test, and the skip line follows the same `skip ... (docker daemon + unavailable)` form. +- Detached worktree at `5e87c41f`, with the two files copied from a + snapshot of the canonical tree, then `sha256sum -c`: 2 OK. A second + worktree for the variants. Both of its files still check OK after the + runs (`r1/mut/manifest-after.txt`). +- A fake `docker` (`r1/mut/fake-docker`) answers `info` with exit 0 and + passes every other call to the real client, with `DOCKER_HOST` pointing + at a socket that doesn't exist. The guard sees Docker, and + `docker compose run` in `mosaic-task.mjs` fails before any container + starts. That exercises the "Docker present, run fails" path with no + model call. +- Two variants of the paused-commit tests (`r1/mut/mutate.py`): git's + stderr delayed 0.5 s by a background subshell that holds the pipe, + waited on `exit` and then on `close`. Then the unchanged candidate tests + ten times in a row, to check that `close` never hangs. + +Node v26.8.1, `TMPDIR=~/darkwing-scratch/r48a/tmp`, `gate.sh` with +`DOCKER_HOST=unix:///nonexistent.sock`, 08:43:13Z to 08:45:19Z. Variants +ran 08:45:22Z to 08:47:18Z, then `test-release` with Docker. + +## Suites + +| Suite | Result | +|---|---| +| queue (node) | 148/0 | +| 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-release-docker.txt`) | +| test-task, Docker unreachable | 26/0, four skip lines, the last the new recall-pair skip | +| test-task, fake `docker info`, daemon unreachable | 67/31, rc 1 (below) | + +I didn't run test-task with real Docker. That run makes live model +calls, and Dewey's 98/0 and Sage's 98/0 on row 52's landing already cover +it. The fake-Docker run is the one that tests the new branch with Docker +present. + +## The Docker skip + +| Run | Recall pair | Total | +|---|---|---| +| base, no Docker (rows 51 and 52) | both fail | 26/2 | +| candidate, no Docker | `skip live recall pair: ...` | 26/0 | +| candidate, fake `docker info`, run fails | `FAIL user recall run succeeds (exit 1)`, `FAIL recalled user name (response: )` | 67/31, rc 1 | + +The pass count is 26 both with the pair failing and with it skipped, so +the skip adds nothing to `PASS`. With the fake Docker, the totals add up to +98, the same number of checks as Dewey's real run. The 31 failures are +every Docker-gated check failing at `docker compose run`. The two recall +checks are among them, and no skip line is printed. + +## exit versus close + +| Variant | `--test-name-pattern="F1: a"` | +|---|---| +| stderr delayed, wait on `exit` | 6/2: both paused-commit tests, `childErr` is `''` against `/cannot lock ref 'HEAD': .../` | +| stderr delayed, wait on `close` | 8/0 | +| candidate unchanged, ten runs | 8/0 each | + +`close` resolves with the same exit code as the first argument, so +`assert.notEqual(code, 0)` still means what it did. The editor script runs +no background process, so nothing outlives git while holding the pipe, and +`close` can't hang on it. + +The other four `exit` waits in the queue tests (`write.test.mjs:368`, +`lock.test.mjs:33`, `:65`, `:151`) read no output after the wait. They +don't need the change, which matches the brief's scope. + +## Notes (not blocking) + +1. The brief's problem statement says "Docker and a model". The guard + checks Docker only. With Docker up and no model credentials, the pair + still fails, along with every other live block. That's what "What + ships" asks for, and it's consistent with the three guards above it. I + agree with it. +2. The guard asks `docker info`, but the run uses `docker compose run`. A + host with the daemon and no compose plugin would fail the pair rather + than skip it. The other three blocks share this, so it isn't this row's + problem. +3. Dewey's two follow-ups stand. The fake-Docker run shows the second one: + "no agent identity on headless run" printed `OK` after a run that never + started. The first one (`FR` picks the newest run record) showed an + empty response here, not another run's, because the fork child's run + failed too. + +## Files + +- `r1/candidate-manifest.sha256`: copy of Dewey's. +- `r1/gate.sh`, `r1/out/`: suite runs and `summary.txt`. +- `r1/mut/`: variant definitions, runner, fake `docker`, outputs, + `summary.txt`, and the manifest check after the runs.