# 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).