Files

5.7 KiB

Filbert review, row 155 (Q169) round 1: approve

Candidate manifest 949873cfda99a2e3d418efee0066fa1438e1c12f69b9d2dfa9413ee089a79183 (31 paths). I applied r1/build.patch (4dda2fc2b7b2...) with --index to 7ce156259, which is origin/refactor. All 31 manifest lines matched, the diff is +801 -104, and git diff --cached --check was clean. The public/bus.js diff in the worktree equals agents/darkwing/work/queue-155/busjs-7ce156259.diff (9f9ce31b...), the diff Mos's decision 123 go names.

This was a static review. I read the brief section (blob b2aeba0364dd), every source diff, every test diff, and the README, docs/TOOLS.md and roles/chief-of-staff.md diffs. I ran no tests, mutants or probes.

Brief items, checked

  1. What configuring changes. packages/business/src/launch-settings.mjs:

    • :140 refuses organization-not-assistant when the target isn't THREAD_DEFINITION;
    • :145 refuses organization-definition-refused for any other given definition;
    • holder and credentials aren't accepted keys;
    • :154-157 then refuses any change to any instance's definition (dewey-0546).

    THREAD_DEFINITION and END_PROTECTED now live in vocabulary.mjs, and the business hard-waits test pins that END_PROTECTED is frozen and holds the assistant.

  2. Who configures. The human and the chief of staff take the same writer through organization.set and limits.set, and changes.jsonl logs the actor. pm, coder and assistant get decision-required. A stale revision gets revision-conflict. Both are in the bus chief-of-staff test and the business launch-settings Q169 tests. The CLI passes assistants through unchanged (limits.test).

  3. Seat name. The chief of staff's set_name tool is offered only to instance.name holders. untyped is back to [] in tools.test and bundle.test. The Console's /api/name uses row 141's human writer.

  4. Removing the assistant.

    • broker.mjs:1494-1498: a threaded target revokes the latest held claim of each thread through #threadHolders (:277). That happens only after #protectedEnd or #consumeAuthority, and not-held rolls the action back.
    • :748 compares the holder run with ?? null on both sides.
    • assistant.stop (:2136) is human-only and revokes only the human's own threads.
  5. Tests. I matched each of the ten required tests to a test body:

    • bus chief-of-staff, hard-waits and threads;
    • business launch-settings;
    • harness tools, bundle and runner;
    • webui assistant, settings-write and settings-form.

    The hard wait is covered: a chief-raised revoke of the assistant, cited or uncited, technical or delivery domain, routes to the human, and a reviewer's resolve gets human-required. After a human resolve the revoke stops the thread, and a reuse gets decision-consumed. The existing arbiter-resolved refusal stays.

Mos's bus.js notes, ruled

  • a) get('names') swallows every error (bus.js:678): follow-up, not blocking. The usage read earlier in settingsView rethrows 403 and signed-out, so a signed-out page doesn't reach this line in practice. A names failure only leaves the field empty with "could not be read", and a later Save name still goes through the route's own sign-in check, which refuses it. Rethrowing 403 and signed-out there, as the other reads do, is a consistency fix for a later row.
  • b) The assistant save updates api:settings but not settingsSnapshot (bus.js:666 vs :587): follow-up, not blocking.
    • The stale revision occurs only when a limits draft is open during an assistant save, because :563 re-snapshots when there are no limits drafts.
    • The server refuses it with revision-conflict, and the page keeps the draft and says so. That fails closed and costs the human one reread.
    • The limits save at :587 doesn't refresh assistantSnapshot either, which is the same issue in reverse. Both would be fixed by one shared snapshot.

Neither ruling asks for a bus.js change in this row, so the go conditions on the +/- lines are unaffected by my verdict.

Non-blocking notes

  1. The dewey-0546 loop (launch-settings.mjs:154-157) is unreachable today and untested. No accepted key writes a definition except assistants, which :140 and :145 already pin. The brief's test, which gives another instance an END_PROTECTED definition, is covered by the :140 refusal. A test of the loop itself would need a future key or a fault injection. I accept it as defense in depth.
  2. What a revoke decision binds to. A threaded revoke binds to the target with a null holder run, not to a set of runs, so a human-resolved decision ends whichever thread runs hold claims when it is used. Its single use (decision-consumed) limits it to one end. That is in line with the brief's "end every assistant thread run". The security reading is Dewey's, and BUILD.md asks Dewey.

I also checked:

  • A JSON null, array or primitive body on /api/name and /api/assistant-stop can't reach Object.keys in seatSend (serve.mjs:241). body() refuses it first (serve.mjs:46, "body must be a JSON object") inside the :240 try, so the answer is 400.
  • roles/chief-of-staff.md has no "Jason" (the chief-of-staff.test.mjs:140 ban).
  • The README, docs/TOOLS.md and role text match the code: the routes, statuses, assistants semantics, tracker: null, the revision coming from the human until row 134, and {revoked:true,threads:N}.

Ran by me

Nothing. I used no slot this round.

Not mine

Darkwing's run (BUILD.md "Row 125 landed", sage-0890), 2026-10-18T20:30:29Z to 20:31:58Z: 39 files run singly, 300 pass, 0 fail, 0 skipped, with shell.test.mjs 5/5. I did not rerun it. The full gate (bus, business, harness, cli and webui suites and every scripts/test-*.sh) is Sage's at landing.