Files
stack/agents/darkwing/work/queue-86-review/review-r1.md
T
jason.woltjeandClaude Opus 5.5 459c4fc681 darkwing: row 86 round 1 review packet, approve (#1580)
Review notes and the rerun of S1, S2, S4, S8, S9 and S0 in a detached
worktree of ad0bdc20. Verdict comment 27986, rev 803 (swept in 85fd3286).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 17:32:48 -05:00

5.8 KiB

Row 86 round 1 review (Darkwing): approve

Verdict: approve, commit ad0bdc20 of agents/researcher/work/i1-spikes/, candidate manifest 0381c233794f61aa98765b8b7c69bc9dd25b2e31702ab7beca556da73c4a586e. The packet does what the brief's "I1 spikes" section asks, inside its rules, and I found nothing that contradicts decisions 105 to 108. Nothing blocks. The notes below are for Sage's gate rerun and the design row.

What I checked

  • Tree. sha256sum -c MANIFEST.sha256 from the packet directory gives 32 of 32 OK, and the manifest's own sha256 is the candidate. git log ad0bdc20..4835a8e2 on the packet and on the brief is empty.
  • Read. All of REPORT.md, lib.sh, s0 to s9 and the nine files under tools/, against the brief's rules:
    • every docker call goes through D(), which names unix:///run/user/1000/docker.sock, and spike_begin refuses with exit 2 unless the info lists name=rootless. The one call to the system socket is S1's info, which the brief asks for;
    • the node image is pinned by digest. Dockerfile.clis installs @anthropic-ai/[email protected] and @earendil-works/[email protected] inside the image. package.json pins pi at 0.85.1, and ~/.local/bin/claude --version prints 2.1.296;
    • every bind source is under the spike's mktemp -d scratch directory. No named volume, no --privileged, no engine socket in a container, no daemon change;
    • no credential. S4's one capability is a throwaway the temp broker issues for a made-up business, on a temp dataRoot under the scratch directory;
    • every container, network and image carries mosaic.i1spike=<spike>, and spike_end removes them and the scratch directory, then turns any leftover into exit 2.
  • Citations. packages/bus/src/server.mjs:8-11 and 43-56, packages/bus/src/runtime.mjs:66-70, packages/seat/src/session.mjs:63 (ANTHROPIC_BASE_URL is in ENV_ALLOW) and the close() path in packages/cli/src/launcher.mjs:393-411 all say what the report quotes.
  • Decisions. I read 105 to 108 in docs/plans/2026-09-26_lead-decisions.md. I agree there's no contradiction. The report's four open items are the right ones for the design row, and the first one, how a containerized broker authenticates a human once the pid proof can't run, is the hard one.
  • Committed outputs. All ten out/*.out files end in result: pass with no FAIL line.

My rerun

In a detached worktree of ad0bdc20 under ~/darkwing-scratch/rv86/, with TMPDIR there, after a busy check that aborts. I ran the spikes that need no build and no provider traffic, then S0 to clean up:

Spike Exit Assertions UTC
S1 endpoint pin 0 6 ok 22:29:05Z to 22:29:06Z
S2 uid mapping 0 23 ok 22:29:06Z to 22:29:17Z
S4 hostile client 0 21 ok 22:29:17Z to 22:29:24Z
S8 stdin capability 0 18 ok 22:29:24Z to 22:29:42Z
S9 hardening 0 32 ok 22:29:42Z to 22:29:47Z
S0 clean images 0 7 ok 22:29:47Z

Each count matches the committed output, with no FAIL line. S2 pulled the node image by digest first; S1 needs no image. The script and its outputs are in r1/ here.

I left S3, S5, S6 and S7 to Sage's gate. S6 and S7 build the CLI image and reach the providers, and S5 reaches the network. Afterwards ps -a showed no rows, network ls showed bridge host none, and image ls -a showed alpine:3, the same end state the report gives.

Notes (non-blocking)

N1. A rerun in place rewrites tracked files. spike_begin tees into $HERE/out/$SPIKE.out, and "How to run" says to cd into the packet and run there. In the canonical checkout that leaves the ten committed outputs modified. For the gate, run in a detached worktree of ad0bdc20 (REPO is four levels up from the packet, so a worktree keeps S4's broker import working), then compare result: lines. That's what I did, and the worktree came out with those six files modified, as expected.

N2. S0 checks the whole daemon. It asserts no container of anyone, only bridge host none, no volume, and it runs builder prune -f, which empties the whole build cache. That's true and harmless today, since the daemon held only alpine:3 before the spikes. Once I2 or anything else uses the rootless daemon, S0 fails, or deletes someone else's build cache. Scope its checks to the label, or retire S0, before that.

N3. One stale line. REPORT.md:38 says "Nothing was committed or posted". The packet is committed at ad0bdc20.

N4. S6 sends key-shaped strings to the real providers. The brief says "with no credential". The FAKE and OAT values aren't credentials, and the report explains why a key-shaped value is needed: with none, neither CLI makes a model request. I accept it. I'm naming it because it's traffic to api.anthropic.com and api.openai.com with a key-shaped header, which the brief didn't spell out.

N5. The spike tools aren't production patterns. connect-proxy.mjs reads only the first chunk (client.once("data")), so a CONNECT line split across two reads is refused as malformed, and any bytes after the header in that chunk are dropped. sockserver.mjs sets the socket's mode after listen, so for a moment it has the umask's mode. Neither matters to what the spikes measure. The design row shouldn't copy either. For the broker, choice 3's own directory per socket is the real gate, not the socket's mode.

N6. Tooling gap. scripts/mosaic queue review verify-commit 86 HEAD reports every file "missing", because the manifest's paths are relative to the packet directory and the tool resolves them from the repository root. Check this packet with sha256sum -c from the packet directory. The tool could learn to try the manifest's own directory.

N7. Dead code. RUNFLAGS() in lib.sh:51 has no caller, and its comment mentions --rm, which it doesn't print.

Approve for commit ad0bdc20 and the candidate above.