Filbert approved round 1 (f167b85e). Manifest 782bcb62, 21 files, plus the QUEUE.md markers and the TOOLS.md section. Lead decision 35. Co-Authored-By: Claude Opus 5.5 <[email protected]>
11 KiB
Queue A2 (#1508), candidate for review
Darkwing, 2026-09-27. A2 is migration, render and dispatch (lead decision
20), plus every item Sage carried forward from A1's review (decision 26:
N5, N8, N10, N11, N12, P1, P2, P3). Base is HEAD c9539baa; A1 is 34a72af9.
Filbert reviews. Sage commits, then installs the hook and runs genesis.
Nothing is committed, staged or pushed.
Files
build.patch (sha256 dc0be7ce74aaaaaf43deebe68af439d1b2b80c77aad6538420e929de35e2f21f) changes 13 files and adds 8.
build-manifest.sha256 (sha256 782bcb62e555659333a35888d418d986da63bdf522f38cafa447db7ddd0074b7) pins all 21 after the patch.
In a fresh clone at c9539baa the patch applies and the result matches
the manifest 21/21, file modes included. git apply warns about one
blank line at the end of fixtures/genesis-render.md. It belongs there:
the render ends with one, and the golden has to match byte for byte.
packages/queue/src/:queue.mjs(N8, N10, N11, P2),store.mjs(N12, N11's shared check, P1's helper, P3's caller),lock.mjs(P1, P3),io.mjs(N5),cli.mjs(usage comment).scripts/mosaic:queueexecspackages/queue/src/cli.mjswith the remaining arguments. Every other call reaches the seat CLI as before.scripts/test-queue.sh: syntax checks forscripts/mosaicand the new fixture;scripts/mosaic queue helpalways; after genesis,verifyandrender --checkon the live queue throughscripts/mosaic queue.packages/queue/README.md: the dispatch, N5, N7, N8, N10, N12, P2, the map andmap-check.mjs, two new test files.- Tests: 107 in A1, 122 now. New:
dispatch.test.mjs(3),migration.test.mjs(3), and 9 more in data, lock, store and write. Fixtures:mosaic-pre-a2.sh(the script before A2),queue-marked.md(QUEUE.md with the markers),genesis-render.md(the golden render). agents/darkwing/work/queue-migration-map.md: the genesis input.agents/darkwing/work/queue-a2/map-check.mjs: the drift check.agents/darkwing/work/queue-a2/carry-forward.md: the item list Sage confirmed (773dbd75), with the r1 section added after it.
Outside the patch, for Sage to apply (condition 2 keeps them out of A2):
queue-md.patch(sha2562ca8f689e1dcda5bb30e9af4c3f867242d5239d72e13001369c7b7aca7956402): the two markers, a header that points seats atscripts/mosaic queue next, and a line freezing the old log of table changes. It applies to HEAD.tools-md.patch(sha256c53aea1f6e871e17d04335ef60250adcdbe64f6466d9ff641042c00094d1c3a8): a "Work queue" section indocs/TOOLS.md. It applies to HEAD. Optional; the README already has the detail.
The five conditions
- Nothing ran against the canonical
.git. Tests use scratch repositories under the temp directory. The dry run below used/tmp/qa2-dry. Checked after all runs: nomosaic-queue*file in.git/,.git/hooks/pre-commitabsent,core.hooksPathunset in every scope, nothing staged. - No QUEUE.md, AGENTS.md or TOOLS.md edits. The two proposals are
patch files.
git statusshows none of the three modified. scripts/test-queue.shis green at a HEAD with noqueue.json: 24/24, the live checks skipped. After the dry-run genesis it ran 26/26, withverifyandrender --checkon the live queue.- H is recorded before the canary.
queue-commit.shis unchanged from A1, and its test "F1: H is recorded before the canary, so HEAD moving during the canary makes update-ref fail" passes. - The fault layer is reachable only from tests. N5 narrows this
further: tmpfs was the one fault-free path open to the CLI, and now
only a layer with
allowTmpfs: truegets it. The test assertsrealIohas no such key and that"yes"doesn't count.
Carried-forward items
| Item | Change | Test |
|---|---|---|
| N8 | piece, gate, note, move reason, brief anchor and blockedReason refuse \ and <, at the CLI and in replay |
"text the table shows refuses \ and <, everywhere it enters"; "every accepted text renders to nine cells on every row" (GFM's cell rule, no marked import) |
| N11 | Replay holds every log entry, round op and claim op to CALLER_OP_RE and refuses .outcome, genesis and accept-history included. LOG_OP_RE stays for Piece D's derived ids; no verb derives one yet |
"replay holds every op id to the caller's rule" |
| N10 | set issues moves closes only if it equalled the old issues; a narrowed closes keeps its intersection, and the receipt says (kept narrowed) |
"set issues keeps a logged narrowing of closes" |
| P2 | Each round records issue; review is {rounds} only. A later round keeps the last round's issue |
"the row schema refuses a round with a null issue, and the A1 review shape", and A1's R2 tests updated |
| P1 | Both gate paths in acquire release through releaseOrWarn; a failed release is a message naming the lock, not a stack trace |
"a release that fails on a gate path is reported, never a stack trace" |
| P3 | lock.unlock returns {result, warning}; nothing splits on newlines |
"unlock keeps a multi-line lock record on stdout" |
| N5 | tmpfs left FS_TYPES; only allowTmpfs === true admits it |
"tmpfs passes only a test layer that allows it" |
| N12 | --by still wins; a different non-empty MOSAIC_AGENT_NAME adds a stderr warning on success and on refusal. Nothing is logged |
"--by that differs from MOSAIC_AGENT_NAME warns on stderr and logs nothing more" |
The rest, as carry-forward.md records and decision 26 confirmed: N7 is a
README line (the leftover .git/mosaic-queue.lock.<pid>.<hex>.tmp is
removed by hand). N15, N16, N13-a and ext2/ext3 are won't-do.
Migration
The map (queue-migration-map.md) is built from QUEUE.md blob c8e3d34e,
which HEAD has. node agents/darkwing/work/queue-a2/map-check.mjs prints
ok: QUEUE.md matches the map (blob c8e3d34e). Run it again just before
genesis. It exits 1 and lists the rows if QUEUE.md moved.
map-check did its job once already. HEAD moved from 8dba3ff7 to c9539baa
while I worked, and it reported row 5 (the CHAT-03 brief pinned, lead
decision 33). I rebuilt row 5's note, queue-md.patch, the marked fixture
and the golden render against the new blob. No other row changed.
The map's "Choices Sage should check" has eight items. None blocks review.
The ones that change what genesis writes: row 7 stays a live row (decision
27), row 10's owner stays coordinator with queue assign 10 sage
recommended as the first op, rows 12 and 13 have Sage as gate owner, row 16
stays waiting-on-jason unless #1510 is closed, and rows 9 to 12 close
nothing so row 13 closes #1508. Rows 9 to 13 have no after: decision 29
took the wait on row 6 off them, and after: 9 done on row 10 would wait
on a gate that needs row 10.
Dry run in a shared clone (/tmp/qa2-dry), the candidate plus
queue-md.patch and tools-md.patch committed on top of c9539baa. I
reran it from scratch after the rebase:
map-check.mjs:ok: QUEUE.md matches the map (blob c8e3d34e).scripts/test-queue.sh: 24/24, live checks skipped.scripts/queue-commit.sh --install-hook --by sage: installed; canary passed.scripts/mosaic queue genesis --root /tmp/qa2-dry --branch a2-dry --map … --op genesis-2026-09-27 --by sage:ok genesis-2026-09-27 rev 0 genesis 30 rows.scripts/queue-commit.sh --genesis: committed.verify --current: briefs match HEAD.render --check: current.legacyViewequals the marked body byte for byte, andmapBlobis the map's blob.next: darkwing resumes 9, sage resumes 7, dewey resumes 5, filbert and rocko have nothing.scripts/test-queue.sh: 26/26 with the live checks.queue assign 10 sage --op assign-10-dry --by sage:ok … rev 1 row 10 owner: coordinator→sage.
The dry clone's hook is .git/hooks/pre-commit, mode 0755, blob
abdf14e7. core.hooksPath is unset there too.
Choices I made
- N8 refuses instead of escaping. An escape has to be right for every Markdown renderer that reads QUEUE.md; a refusal doesn't. No line in today's table has either character.
- P2 drops
review.issue. The last round's issue is the kept one, so a second copy could only disagree. Piece D readsrounds[].issue. - N10's edge. A
closesnarrowed to nothing stays empty whatever the new issues are.set closeswith a reason is the way to widen it again. - N12 warns on a refusal too, so a seat that mistyped
--bysees it on the error it was reading anyway. scripts/mosaic queueusesexec, so exit codes and signals are the queue CLI's own. Any first argument other than exactlyqueuegoes to the seat CLI, as before; the dispatch test compares argv, cwd, environment and stdin against the pre-A2 script.
Mutations
Each mutation ran alone in a shared clone of the candidate, with
node --test packages/queue/tests/. A killed mutation fails at least one
test.
46 mutations. Each one below failed at least one test; the number is how many.
| Item | Mutations |
|---|---|
| N8 | backslash 2, lt 2, noteVerb 1, rowNote 2, anchor 1, reason 1 |
| N11 | entryShape 1, outcome 2, genesisOnly 1, roundOp 1, claimOp 1 |
| N10 | always 2, noIntersect 1, receipt 1 |
| P2 | keptFirst 1, noCheck 1, reviewIssue 10 |
| P1 | gateErr 1, gatePresent 1, gatePresentMsg 1, withLock 1 |
| P3 | joined 2, storeSplit 1 |
| N5 | inTypes 1, truthy 1, anyType 1 |
| N12 | noWarnOk 1, noWarnErr 1, envWins 1, emptyEnv 1 |
| Dispatch | noShift 1, unsetArg 1, prefix 1, noExec 1 |
| Golden render | mapGate 1, mapState 1 |
| map-check | fixed26 1, owner 1, issues 1, lineDiff 1, parkedPiece 1 |
Five of them survived the first pass. Each now has a test that kills it:
- N11 roundOp and claimOp (replay stops checking a review round's op or a
claim's op). The N11 test now builds a claimed row and a reviewed row and
refuses an op of 73 characters and one ending
.outcomein each. - P1 withLock (the post-op release goes back to the throwing
release). New write test: the lock's unlink fails with EACCES after the op, and the receipt and a refusal both carry "cannot release the queue lock (EACCES)". - N12 emptyEnv (an empty
MOSAIC_AGENT_NAMEwarns). The N12 test now runs with it empty and expects no stderr. - Dispatch noExec (
nodewithoutexec, so a successful queue call falls through to the seat CLI). The dispatch test now runs a queue call that exits 0 and checks that only the queue CLI ran.
The map and golden-render mutations ran again after the rebase and were still killed.
Suites
All nine green at the final candidate: config 24, task 90, foundation
44, conductor 17, release 14, auth 15, discord 64, extension-package 18,
queue 24 (no queue.json at HEAD). node --test packages/queue/tests/:
122/122.
After approval (Sage)
- Check the canonical tree against
build-manifest.sha256, then commit the 21 files by path. - Apply
queue-md.patch(andtools-md.patchif wanted) and commit. node agents/darkwing/work/queue-a2/map-check.mjsmust printok.scripts/queue-commit.sh --install-hook --by sage.scripts/mosaic queue genesis --root /mnt/storage/src/mosaic-stack --branch refactor --map agents/darkwing/work/queue-migration-map.md --op <id> --by sage.scripts/queue-commit.sh --genesis -m MSG.scripts/test-queue.shruns the live checks from here on.