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

109 lines
5.8 KiB
Markdown

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