From f7c2d5cfe37eb415ec280cd8659c51a68036e580 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 10 Oct 2026 03:55:13 -0500 Subject: [PATCH] test: commit.test close wait and test-task recall Docker skip (#1534, row 48) pausedCommit waits for the child's `close`, not `exit`, so the `cannot lock ref 'HEAD'` match sees git's stderr. The test-task live recall pair runs only when `docker info` succeeds, like the three live blocks above it; otherwise it prints a skip line and counts as neither a pass nor a failure. Dewey built it. Darkwing (27099) and Filbert (27100) approved round 1 on manifest 285a4ec1 (3 files). Sage's gate on 560373c3 plus the candidate: queue 148/0, conversation 182/0, webui 22/0, control-board 124/0, every scripts/test-*.sh 0 failed; test-task 98/0 with Docker and 26/0 without, with the recall-pair skip line. Co-Authored-By: Claude Opus 5.5 --- .../work/queue-48/candidate-manifest.sha256 | 3 + agents/dewey/work/queue-48/evidence.md | 90 +++++++++++++++++++ packages/queue/tests/commit.test.mjs | 2 +- scripts/test-task.sh | 24 +++-- 4 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 agents/dewey/work/queue-48/candidate-manifest.sha256 create mode 100644 agents/dewey/work/queue-48/evidence.md diff --git a/agents/dewey/work/queue-48/candidate-manifest.sha256 b/agents/dewey/work/queue-48/candidate-manifest.sha256 new file mode 100644 index 00000000..eb8bc767 --- /dev/null +++ b/agents/dewey/work/queue-48/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/dewey/work/queue-48/evidence.md b/agents/dewey/work/queue-48/evidence.md new file mode 100644 index 00000000..2b89555c --- /dev/null +++ b/agents/dewey/work/queue-48/evidence.md @@ -0,0 +1,90 @@ +# Row 48 (#1534): commit.test exit wait and test-task Docker skip + +Dewey, 2026-10-10. Brief: `docs/plans/2026-10-10_s5-follow-up-and-hygiene.md`, +section "Test hygiene: commit.test exit wait and test-task Docker skip" +(blob 24ceb88c). Base 2d935f59. Candidate: two files, uncommitted. + +## Change + +- `packages/queue/tests/commit.test.mjs` (`pausedCommit`, line 172): the + paused commit's child is awaited on `close` instead of `exit`. `close` + fires after the child's stdio streams have closed, so every `data` + event on stderr has been delivered before `childErr` is matched against + `cannot lock ref 'HEAD'`. `exit` can fire first. Nothing else in the + test changes; `close` resolves with the same exit code. +- `scripts/test-task.sh` (live recall pair, the two checks "user recall + run succeeds" and "recalled user name"): the pair runs only when + `docker info` succeeds, the same test the three live blocks above it + use. Otherwise it prints + `skip live recall pair: user recall run, recalled user name (docker daemon unavailable)` + and touches neither `PASS` nor `FAIL`. The recall task, prompt and both + checks are unchanged, only indented into the `if`. With Docker present + a failed run still fails both checks. + +Not changed: "no agent identity on headless run" stays outside the `if`, +as the brief names only the pair. It reads `system-prompt.md`, which the +run writes, and passes when the file is absent, so without Docker it is +as weak as on base. + +## Tests + +Docker made unreachable with `DOCKER_HOST=unix:///nonexistent/docker.sock` +(`docker info` exits 1, and run-task.sh can't reach a daemon either). +Outputs: `~/dewey-scratch/r48/out/`. + +| Run | Tree | Docker | Result | +|---|---|---|---| +| base-nodocker | 2d935f59 | no | 26 passed, 2 failed: "user recall run succeeds (exit 1)", "recalled user name (response: )". Darkwing's 26/2 on rows 51 and 52. | +| cand-nodocker | candidate | no | 26 passed, 0 failed, rc 0; the skip line printed after the three existing ones | +| cand-docker | candidate | yes | 98 passed, 0 failed; "user recall run succeeds", "recalled user name (response: Jason)" | +| mut-docker-fail | candidate, recall run replaced by `false` | yes | 96 passed, 2 failed, rc 1: both recall checks fail | +| cand-queue-node | candidate | – | `node --test packages/queue/tests/*.test.mjs` 148 pass, 0 fail | + +The skip never counts: 26 passed both without the pair (candidate) and +with it failing (base), so the two checks leave `PASS` alone and only +`FAIL` differs. + +### exit versus close (commit.test) + +The race doesn't show on a fast machine, so I made it deterministic in a +scratch copy: the paused commit is spawned through +`sh -c 't=$(mktemp); git "$@" 2>"$t"; s=$?; (sleep 0.5; cat "$t" >&2; rm -f "$t") & exit $s'`, +which exits with git's status at once while a background subshell holds +stderr and writes git's message 0.5 s later. + +| Wait on | `--test-name-pattern="F1: a"` | +|---|---| +| `exit` (base) | 6 pass, 2 fail: both paused-commit tests, `childErr` empty against `/cannot lock ref 'HEAD': …/` | +| `close` (candidate) | 8 pass, 0 fail | + +Outputs: `~/dewey-scratch/r48/out/demo-exit.txt`, `demo-close.txt`. + +## Gate + +Worktree at 2d935f59 plus the two candidate files (`cmp` identical to +the canonical copies), TMPDIR in scratch, suites sequential, +2026-10-10T08:37:42Z to 08:40:41Z. Outputs: `~/dewey-scratch/r48/gate/out/`. + +| Suite | Result | +|---|---| +| `node --test packages/queue/tests/*.test.mjs` | 148 pass, 0 fail | +| test-auth | 15 passed, 0 failed | +| test-conductor | 17 passed, 0 failed | +| test-config | 24 passed, 0 failed | +| test-discord | 66 passed, 0 failed | +| test-extension-package | 18 passed, 0 failed | +| test-foundation | 44 passed, 0 failed | +| test-queue | 27 passed, 0 failed (verify and render --check skip outside the canonical root; run in the canonical checkout: `ok verify rev 317`, `view current at rev 317`) | +| test-release | 14 passed, 0 failed | +| test-task, Docker present | 98 passed, 0 failed | +| test-task, `DOCKER_HOST` unreachable | 26 passed, 0 failed; four skip lines, the last the new recall-pair skip | + +## Follow-ups (not in scope) + +- In the mutant run the name check printed `response: mosaico`: when the + recall run writes no run record, `FR` picks the newest one, here the + fork child's. The check still fails, but the message names another + run's response. That's the recall check's content, which the brief + leaves out. +- "no agent identity on headless run" passes vacuously when the run + wrote no `system-prompt.md` (see above). diff --git a/packages/queue/tests/commit.test.mjs b/packages/queue/tests/commit.test.mjs index c254dce5..23fa3335 100644 --- a/packages/queue/tests/commit.test.mjs +++ b/packages/queue/tests/commit.test.mjs @@ -169,7 +169,7 @@ async function pausedCommit(t, form) { const child = spawn("git", ["-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/scripts/test-task.sh b/scripts/test-task.sh index 9d3a1f5e..41bf9e8c 100755 --- a/scripts/test-task.sh +++ b/scripts/test-task.sh @@ -511,15 +511,21 @@ grep -q "name: Jason" "$ONB/user/USER.md" \ grep -q "## Skillset" "$ONB/user/USER.md" && grep -q "## Pets" "$ONB/user/USER.md" \ && check "canon sections present" 0 || check "canon sections present" 1 -# Live recall: real pi, real phrasing - assert containment, not exactness -printf '{"taskVersion":1,"id":"t-user","prompt":"What is the user name? Reply with only the name.","session":"onb-check","timeoutSeconds":180}' > "$SANDBOX/recall-task.json" -RC=0 -scripts/run-task.sh run "$SANDBOX/recall-task.json" >/dev/null 2>&1 || RC=$? -[ "$RC" -eq 0 ] && check "user recall run succeeds" 0 || check "user recall run succeeds (exit $RC)" 1 -FR="$(ls -dt "$SANDBOX/data/runs"/r-* | head -1)" -RESP="$(node -e 'try{const r=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"));console.log(r.response||"")}catch{console.log("")}' "$FR/result.json" 2>/dev/null)" -echo "$RESP" | grep -qi "jason" \ - && check "recalled user name (response: $RESP)" 0 || check "recalled user name (response: $RESP)" 1 +# Live recall: real pi, real phrasing - assert containment, not exactness. +# Needs Docker like the live task cases above. Without it the pair prints +# a skip and counts as neither a pass nor a failure. +if docker info >/dev/null 2>&1; then + printf '{"taskVersion":1,"id":"t-user","prompt":"What is the user name? Reply with only the name.","session":"onb-check","timeoutSeconds":180}' > "$SANDBOX/recall-task.json" + RC=0 + scripts/run-task.sh run "$SANDBOX/recall-task.json" >/dev/null 2>&1 || RC=$? + [ "$RC" -eq 0 ] && check "user recall run succeeds" 0 || check "user recall run succeeds (exit $RC)" 1 + FR="$(ls -dt "$SANDBOX/data/runs"/r-* | head -1)" + RESP="$(node -e 'try{const r=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"));console.log(r.response||"")}catch{console.log("")}' "$FR/result.json" 2>/dev/null)" + echo "$RESP" | grep -qi "jason" \ + && check "recalled user name (response: $RESP)" 0 || check "recalled user name (response: $RESP)" 1 +else + echo "skip live recall pair: user recall run, recalled user name (docker daemon unavailable)" +fi # headless run must NOT carry an agent identity section ! grep -q 'AGENT IDENTITY' "$SANDBOX/data/system-prompt.md" 2>/dev/null \ && check "no agent identity on headless run" 0 || check "no agent identity on headless run" 1