Files
stack/agents/rocko/work/queue-79/BUILD.md
T
jason.woltjeandClaude Opus 5.5 1735f27d37 rocko: row 79 round 1 packet, BUILD-LOG and SESSIONS (#1573)
Packet agents/rocko/work/queue-79/ (packet manifest b6b11e7b, 42 files,
candidate manifest 16b12387), Rocko's BUILD-LOG and SESSIONS appends.
Committed by Sage for Rocko, who has no credential.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 19:19:14 -05:00

8.2 KiB

Row 79 (#1573): coder grant stale text, candidate packet, round 1

Author: Rocko. Reviewer: Dewey. Brief: docs/plans/2026-10-11_claude-pin-and-coder-grant.md, section "Coder grant stale text" (blob 4784ee65, re-pinned by Sage at revs 567-568). It also carries Dewey's row 73 note N1 (comment 27506 on #1567). Base: 331d037c (base.txt). 331d037c..bd4dff33 (2ece4491, bd4dff33, 5fc7635c) touches none of this row's paths. I checked that before packing. The packet is uncommitted. I made no commits, pushes or Gitea calls and read no token or private binding.

Files (files.txt, candidate-manifest.sha256)

File Change
packages/business/README.md version 2 example: crossRole is ["task.scope.change"], so the example matches roles/coder.json
packages/tasks/README.md the task.reassign paragraph: the coder holds no grant (row 73), and the writer check refuses a non-pm task.reassign before authority anyway
packages/tasks/live/run.mjs the coder authority line matches packages/tasks/tests/world.mjs
packages/harness/tests/tools.test.mjs coder-without-a-tracker test: one deepEqual on the whole untyped list replaces two includes asserts (N1)
agents/rocko/work/queue-79/mutants.sh the mutant rerun: mutants.sh <tree>

Totals: 4 tracked files, +7 -9, and the new mutants.sh. I changed no role file, broker.mjs, field table or any other test.

run.mjs, the coder line

The old line was withinRole: ['task.update.assigned', 'message.send'], crossRole: ['task.reassign', 'task.scope.change']. It was stale in two ways: the reassign grant, and the missing git.push.working and review.request. The new line is word for word the coder entry in world.mjs and has the same authority as roles/coder.json.

Two other lines in the same AUTHORITY object differ from world.mjs, and I left them alone because the brief owns only the coder line:

  • pm: run.mjs has no role.launch. world.mjs and roles/pm.json have it.
  • reviewer: run.mjs has no review.verdict. world.mjs and roles/reviewer.json have it.

The live run uses neither action, so this doesn't change its result. If Sage wants the whole object to match, that's a follow-up row.

N1: the untyped list (out/mutants-candidate.txt, out/mutants-base.txt)

untypedActions (packages/harness/src/tools.mjs:122-125) returns [...withinRole, ...crossRole] minus the actions that have a typed tool. For the shipped coder without a tracker, that is task.update.assigned, git.push.working, review.request and task.scope.change. message.send is typed (send_message). The test now pins that list, including its order, with one deepEqual.

Mutant Edit in packages/harness/src/tools.mjs Base 331d037c Candidate
untyped-within-only return [...withinRole].filter(…) (Dewey's mutant) survived killed
untyped-cross-first return [...crossRole, ...withinRole].filter(…) survived killed
untyped-keeps-typed .filter((a) => a === "message.send" || !typed.has(a)) killed killed

Every kill is in "a coder gets no launch, no resolve_decision, and no task tools without a tracker". On the base, the old !includes("message.send") assert already kills untyped-keeps-typed. I kept that mutant to show the deepEqual doesn't lose that check.

The script saves the file, applies the sed and checks it changed something. It then runs packages/harness/tests/tools.test.mjs and restores the file from the saved copy. The base run used a clean detached worktree at 331d037c, which I removed afterwards. out/mutants-*/ holds each diff and log. The script exits 1 on the base, as it should when a mutant survives.

A correction to my own first run: I wrote untyped-keeps-typed with a !== "message.send". That inverts it into a mutant that keeps every typed action except message.send, and the coder has no other typed action in withinRole or crossRole, so it survived. That run says nothing about the test. I fixed the expression to === and reran. The outputs in out/ are from the fixed script only.

Repository grep for task.reassign

git grep -n 'task\.reassign' on the candidate tree, outside agents/:

Path Hits Why it stays
roles/pm.json:9 1 the pm grant (decision 90: assignee is pm-only)
packages/business/src/vocabulary.mjs:17 1 the action vocabulary
packages/bus/src/broker.mjs:10 1 the broker's action list. The brief puts broker.mjs out of scope
packages/harness/src/tools.mjs:46 1 the task_reassign typed tool. A pm with a tracker gets it
packages/tasks/src/verbs.mjs:13,191,200,201 4 PM_VERBS and the verb itself
packages/tasks/README.md:107,150,176,193-194 5 the writer-check list, the verb table, the task-unassigned refusal, and this row's rewritten paragraph
packages/tasks/live/README.md:65 1 the pm's live reassign step
packages/tasks/live/run.mjs:29,154 2 the pm grant and the pm's reassign step. The coder line no longer has it
packages/tasks/tests/world.mjs:34 1 the pm grant in the test world
packages/tasks/tests/verbs.test.mjs:96-110 6 a coder's task.reassign refused with field-writer, no coder holds it, and the pm's reassign paths
packages/tasks/tests/shapes.test.mjs:127 1 a pm reassign
packages/bus/tests/broker.test.mjs:361,373,381 3 the shipped coder raises task.reassign as gated to the human. That holds because the coder has no grant for it
packages/business/tests/resolve.test.mjs:141 1 classify(coder, "task.reassign") is gated, the same fact
packages/business/tests/role.test.mjs:64,117 2 64 is row 73's comment on the coder file. 117 is a synthetic role that holds the action in both lists, to test that refusal
scripts/test-task.sh:279 1 v2ok, a synthetic version 2 role with the action in crossRole, used only to check that resolve-role accepts a minimal role. It isn't the coder
docs/design/mosaic-stack-design.html:729,732,975 3 the action list, the pm grant and the verb list. There's no coder grant here
docs/plans/2026-10-04_slice-1.md:73 1 the field table: assignee is pm, via task.assign and task.reassign
docs/plans/2026-09-26_lead-decisions.md:1914 1 decision 90's record of the old coder grant, which is history
docs/plans/2026-10-11_claude-pin-and-coder-grant.md 14 the briefs for rows 73 and 79
docs/plans/queue.json, docs/plans/QUEUE.md 5, 1 row titles and notes
BUILD-LOG.md, docs/SESSIONS.md 7, 2 append-only history

v1/ has no hits. No hit outside history and briefs shows the coder holding task.reassign.

Dewey's correction to the row 73 packet

Dewey's approval of row 73 (comment 27506) corrects a line in that packet. The header of agents/rocko/work/queue-73/mutants.sh says "the tasks test kills nothing". That's true only for my five mutants. Dewey's verbs-reassign-not-pm mutant is killed only by the verbs line row 73 added. The committed row 73 file stays as it is, on Sage's instruction, and this note is the record.

Gate (out/gate/, sequential, scratch worktree at 331d037c with the candidate, node_modules linked)

Run 00:11:53Z-00:17:41Z (2026-10-12). The brief's gate names the tasks, business and harness suites and every script. I also ran bus, cli, webui and seat, the package set row 73's gate used.

Suite Result
tasks 71 pass, 0 fail, 0 skipped
bus 84 pass, 0 fail, 0 skipped
business 60 pass, 0 fail, 0 skipped
harness 59 pass, 0 fail, 0 skipped
cli 113 pass, 0 fail, 0 skipped (the base predates row 78's added test)
webui 61 pass, 0 fail, 0 skipped
seat 27 pass, 0 fail, 0 skipped
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
test-release 14 passed, 0 failed
test-task 98 passed, 0 failed (Docker)

The harness count is unchanged, because the row edits one existing test. After the gate I removed the rocko-r79_default network.