Files
stack/agents/dewey/work/queue-90/r2/build.md
T
jason.woltjeandClaude Opus 5.5 2f367900ea dewey: row 90 round 2 packet, 21 paths on b8539480, manifest 95611274
Round 1 rebased on row 63 (b8539480) plus one RUNNER_FILES line in
packages/seat/src/sandbox.mjs for row 92 (decision 127).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 18:30:26 -05:00

5.8 KiB

Row 90 (#1584): The approved requirement ids as data, round 2

Owner: Dewey. Reviewer: Filbert, then Sage's gate. Round 1 approved by Filbert (comment 28021, rev 826) on candidate 26d1fbdf…, base 23338c7b. Round 2 is the rebase that lead decision 125 asks for: row 63 landed first, as b8539480 (rev 838), and row 90 now sits on it. No behaviour of row 90 changed from round 1.

Base b8539480. build.patch is git diff --cached --binary b8539480 -- the 21 paths in candidate-manifest.sha256: round 1's twenty plus packages/seat/src/sandbox.mjs. Apply it with git apply --index to a detached worktree of b8539480; the manifest then checks 21/21 OK. No commit from b8539480 to refactor HEAD touches packages/, scripts/, roles/ or contracts/.

What changed from round 1

Three files. The other 18 have the same hunks as round 1 (compared per file with hunk line numbers ignored), verbs.mjs, tools.mjs and tools.test.mjs included: row 63 touched them too, but in other places.

File Round 2 change Why
packages/tasks/README.md the task.create paragraph merges both sides (below); the other hunks are round 1's row 63 changed the same paragraph
packages/tasks/tests/verbs.test.mjs the import line, a context line in round 1, now reads import { world, sleep, SCOPES } from './world.mjs'; as row 63 left it; row 90's added lines are unchanged row 63 changed the same line
packages/seat/src/sandbox.mjs RUNNER_FILES gains "packages/tasks/src/requirements.mjs", one line row 92 landed between the bases (below)

The README merge. At round 1's base the paragraph had one sentence on requirement. Row 63 added three sentences after it on project. Round 1 replaced the requirement sentence with the requirements.json text and added two sentences: unknown-requirement, and that request is the request field of a received message. Round 2 keeps both: round 1's requirement and request sentences first, then row 63's project sentences word for word, then the unchanged task.created sentence. The paragraph is rewrapped to the file's width. No word of either side is dropped or changed.

The sandbox line. Row 92 (57948a81, #1586) landed after round 1's base. A role session's runner now runs in a bwrap sandbox that binds only RUNNER_FILES, the files on the runner's import walk, and packages/seat/tests/sandbox.test.mjs fails unless the list equals that walk exactly. The runner's bus/src/client.mjs imports BusError from broker.mjs, and row 90's broker.mjs imports ../../tasks/src/requirements.mjs, so on b8539480 with only the twenty paths a sandboxed runner can't load the module and dies at start. The rebased gate's first run showed it: seat 4 and cli 8 failing (the RUNNER_FILES walk test, and the launcher's PM, coder, kill and host-restart tests, whose runners ended failed). No line of either side conflicted, and a path drift check on the twenty paths was clean; only the gate found it. The sandbox line is the semantic fix (decision 127). requirements.json stays out of the sandbox: the runner never constructs a Broker, and only the Broker constructor reads the file.

Row 91 (Darkwing, #1585, in build) doesn't touch sandbox.mjs or RUNNER_FILES and adds no file to the runner's import walk (Darkwing's reply to me, about 23:29Z). It does change prompt() in packages/harness/src/bundle.mjs, which row 90 changes too, on other lines; whichever row lands second reruns the rebase check.

The rebase checks: row 63's six paths at b8539480 are byte-identical to the scratch stack I rebased on (row 63 round 2's candidate on cca5f23e), and git diff 23338c7b b8539480 on the twenty paths is exactly row 63's own diff on them.

Gate (my run on the round 2 candidate)

Two runs, sequential, in a detached worktree of b8539480 with node_modules symlinked. gate.sh and gate-summary.txt (run 1) and gate-rerun.txt (run 2) are in the packet; the full logs are not.

  1. The twenty paths, 23:15:51-23:20:59Z, manifest 20/20. Green: tasks 89, bus 111, harness 66, webui 101, business 60, control-board 124, and every scripts/test-*.sh: auth 15, conductor 17, config 24, discord 66, extension-package 18, foundation 44, queue 27, release 14, task 26 (DOCKER_HOST at a dead socket). Red: cli 112/120 (8 failing) and seat 29/33 (4 failing), the sandbox failures above.
  2. With the sandbox line, the 21-path candidate, 23:26:31-23:26:50Z: seat 33/33 and cli 120/120, rc=0.

Not rerun on the 21-path candidate: the other suites. The sandbox line changes only RUNNER_FILES, which seat and the cli launcher load; harness names sandbox.mjs in a comment only. Per decision 127, Filbert's review and Sage's landing gate run every suite on the 21-path candidate, harness included.

Counts against round 1's gate (base 23338c7b): tasks 79 to 89 (row 63's tests), webui 86 to 101, cli 115 to 120 and seat 27 to 33 (rows 77 and 92 landed between the bases).

Mutants

Round 1's 44 (mutants.py, the same swaps, run in a scratch copy of the twenty-path candidate against the bus, harness and tasks suites, each run in its own process group with a 300 s limit), 23:20:59-23:25:39Z: 44 of 44 killed, none hung (mutants.txt). Afterwards the copy matches the manifest's twenty paths again. The sandbox line has no mutant of its own: the seat walk test fails when it is missing, as the first gate run showed.

Round 1 follow-ups

Filbert's three non-blocking test notes from round 1 stay follow-ups: the title check accepts \r; in for Object.hasOwn survives; and an allowlist holding only the first and last ids plus REQ-TASK-1 survives. None is in round 2, which changes only what the rebase forced.

Round 1's build.md (agents/dewey/work/queue-90/build.md) still holds the design, the decisions and the limits. Round 2 changes none of them.