Plan page for #1508: queue as data, pieces A-E, Gate G; QUEUE rows 9-13 link to it

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
2026-09-12 19:45:14 -05:00
co-authored by Claude Fable 5.1
parent cbf24b01b0
commit 0e77cfd10a
2 changed files with 132 additions and 5 deletions
+126
View File
@@ -0,0 +1,126 @@
# Queue as data: the process stops being prose (#1508)
Owner of the plan: Jason. Coordinator: the Claude session. Builder: darkwing.
Tracking: #1508. Rows 9 to 13 in `docs/plans/QUEUE.md`, state `required`.
Jason, 2026-09-13: "It all starts out great, then goes off the rails. I want
this iron-clad." This page is the plan, the decomposition, and the briefs.
It is not a design discussion. Each piece below has one owner, one gate,
and one commit-sized scope. Nothing on this page is optional and nothing
moves to DEFERRED.md; a piece that cannot ship gets a Blocked line in
QUEUE.md with the reason.
## Problem, in one paragraph
The entry point for "what is next" was prose in four files (AGENTS.md,
CURRENT.md, ROADMAP.md, CONDUCTOR.md), edited by hand by any seat in one
shared checkout. State lived in sentences, so it drifted: three "Next
action" paragraphs, edits swept into other seats' commits, 160 review files
invented as a side channel, and Jason unable to find the next step. The fix
is the same fix already applied to decisions (`brain.py` is the only writer)
and to seat identity (`registration.json` is the only record): the queue
becomes a record with one writer and checks that fail loudly.
## Ordering and preconditions
Starts after piece 5 (darkwing on point, QUEUE row 6) reaches Gate F or is
blocked, whichever comes first. Runs before the fleet migration (row 8).
Pieces A to E below ship in order; each is one issue comment on #1508 and
one QUEUE row move. Nothing on this page waits for the WebUI, the comms MVP,
or the orchestrator to be finished.
## Piece A: queue record and `mosaic queue` (QUEUE row 9)
**Owner:** darkwing. **Reviewer:** filbert. **Package:** `packages/queue`,
same shape as `packages/seat`. **Files owned:** `packages/queue/**`,
`scripts/mosaic` (subcommand dispatch only), `docs/plans/QUEUE.md`.
**What ships**
- One file, `<repo>/docs/plans/queue.json`, committed. It is the queue.
Array of rows: `id` (integer, never reused), `piece` (one line), `owner`
(seat name, `jason`, `coordinator`, or `unassigned`), `issue` (integer or
null), `state` (`queued` | `briefed` | `in-progress` | `in-review` |
`waiting-on-jason` | `done` | `blocked` | `parked` | `required`), `gate`
(one sentence), `brief` (repo path plus optional section), `updatedAt`,
`updatedBy` (from `MOSAIC_AGENT_NAME`, or `--by`, else refused), `note`
(one line, optional), `blockedReason` (required when state is blocked).
- `scripts/mosaic queue list [--owner SEAT] [--json]`, `queue next [SEAT]`
(prints the one row that seat should work on, or "nothing" with exit 0),
`queue add --piece --owner --gate --brief [--issue]`, `queue move ID STATE
[--reason]`, `queue assign ID SEAT`, `queue note ID TEXT`. All writes
through the CLI; the CLI validates the transitions below and refuses
anything else with one line on stderr and exit 2.
- Transitions: queued→briefed→in-progress→in-review→waiting-on-jason→done;
any→blocked (reason required) and blocked→previous; required→in-progress
only; parked only from queued or briefed and only with `--by jason`;
done and parked rows never change. A seat may move only rows it owns;
`coordinator` and `jason` may move any row.
- `docs/plans/QUEUE.md` becomes a rendered view: `mosaic queue render`
writes the table between two marker comments and the CLI runs it after
every write. The header text above the markers stays hand-written.
- Tests: fixtures for every transition and every refusal; render is
byte-stable; `queue next` picks the first row by id, not by file order.
**Out of scope:** Gitea sync, board display, the ledger, hooks, any change
under `packages/seat`, `packages/control-board`, `packages/ledger`.
**Gate G (Jason):** a seat launched fresh, with no prior session, is told
only "run `mosaic queue next` and do it". It finds its piece, opens the
brief the row names, and starts, with zero further human messages. Jason
watches from the board. Pass or fail, one sentence on #1508.
## Piece B: seats read the queue, not CURRENT.md (QUEUE row 10)
**Owner:** coordinator. **Done 2026-09-13** for the cadence and pointer
lines in AGENTS.md (cbf24b01). Remaining under this piece, after Piece A:
the cadence line says `mosaic queue next` instead of naming the file, and
`agents/*/AGENTS.md` or context files that still point at CURRENT.md for
"what now" are changed to the command. One commit. No gate; verified by
Gate G.
## Piece C: brief template (QUEUE row 11)
**Owner:** darkwing, as part of Piece A's review round. **File:**
`docs/plans/BRIEF-TEMPLATE.md`, one page, these headings only: Problem,
Owner and reviewer, Files owned, What ships, Out of scope, Gate (who says
yes, on what evidence). `mosaic queue add` refuses a `--brief` path that
does not exist. The pieces on this page are written in that shape and are
the first three uses. Passing: Piece A's brief and one later brief are
accepted by Jason without a follow-up question about scope.
## Piece D: reviews through a channel, not files (QUEUE row 12)
**Owner:** darkwing. **After Piece A.** Review requests and receipts go as
issue comments on the piece's issue (`scripts/gitea-api.sh` exists) or as
board messages once the comms MVP has a record; no new files under
`docs/plans/reviews/`. The existing 160 files stay as history. `mosaic
queue move ID in-review` posts the request comment itself from the row's
data, so the seat does not write one. Passing: one full review round on a
later piece with zero new files under `docs/plans/reviews/`.
## Piece E: ledger checks the queue (QUEUE row 13)
**Owner:** darkwing. **Reviewer:** filbert. **After Piece A.** `packages/
ledger` gains a "queue" section: every open Gitea issue with a `#N` in a
queue row has that row not done; every `in-progress` or `in-review` row has
an owner seat with a live registration; every `done` row's issue is closed;
every `required` row older than 14 days is listed by name. Violations print
above the weekly table and in `--json`. First run Monday 2026-09-21 with the
weekly number. Passing: zero violations, or every violation has a row moved
within the day.
## What "iron-clad" means here, so it can be checked
1. The queue has one writer (`mosaic queue`) and refuses bad transitions.
2. Seats are told a command, not a file, so nothing to reinterpret.
3. Every row names an owner, a gate, and a brief that exists.
4. The ledger reports drift weekly, next to the number Jason already reads.
5. `required` rows cannot be parked; only Jason moves them.
If any of the five stops being true, that is a finding on #1508, reopened.
## Log
- 2026-09-13 — page written by the coordinator after Jason's "iron-clad"
ruling; #1508 opened; QUEUE rows 9 to 13 point here.
+6 -5
View File
@@ -34,11 +34,11 @@ Gaps found while working go to `docs/plans/DEFERRED.md`, not here.
| 6 | Darkwing on point: darkwing assigns and gates filbert's work (piece 5 on the plan page) | darkwing | none yet | briefed; Jason: send the start message from the board on Sunday 2026-09-13 | F: filbert's item closes with zero human messages from Jason | plan page, "Piece 5: darkwing on point" | | 6 | Darkwing on point: darkwing assigns and gates filbert's work (piece 5 on the plan page) | darkwing | none yet | briefed; Jason: send the start message from the board on Sunday 2026-09-13 | F: filbert's item closes with zero human messages from Jason | plan page, "Piece 5: darkwing on point" |
| 7 | Weekly ledger run and rails number | Jason | — | recurring, end of Monday 2026-09-14 | under 10 human messages per closed issue for the week of 2026-09-13 | `packages/ledger/README.md` | | 7 | Weekly ledger run and rails number | Jason | — | recurring, end of Monday 2026-09-14 | under 10 human messages per closed issue for the week of 2026-09-13 | `packages/ledger/README.md` |
| 8 | Fleet seats (`~/.mosaic`) onto `mosaic launch` | unassigned | — | queued; not before row 6 is done | Jason's call | none yet | | 8 | Fleet seats (`~/.mosaic`) onto `mosaic launch` | unassigned | — | queued; not before row 6 is done | Jason's call | none yet |
| 9 | Queue as data: JSON registry, `mosaic queue` is the only writer (list, add, move, assign) | darkwing | #1508 | required; starts when row 6 is done, before row 8 | G: a fresh seat with no prior context finds and starts its piece from the queue alone, zero human messages | #1508 | | 9 | Queue as data: `docs/plans/queue.json`, `mosaic queue` is the only writer | darkwing; filbert reviews | #1508 | required; starts when row 6 is done, before row 8 | G: a fresh seat told only "run `mosaic queue next` and do it" starts its piece with zero human messages | `2026-09-13_queue-as-data.md`, Piece A |
| 10 | AGENTS.md cadence reads the queue first; CURRENT.md is narrative only | coordinator | #1508 | done 2026-09-13 (AGENTS.md cadence and pointer lines) | — | #1508 | | 10 | Seats read the queue, not CURRENT.md (AGENTS.md cadence, seat context files) | coordinator | #1508 | required; AGENTS.md lines done 2026-09-13, rest after row 9 | verified by Gate G | `2026-09-13_queue-as-data.md`, Piece B |
| 11 | Brief template: goal, gate, owner, out of scope, files owned; one page, linked from the row | darkwing | #1508 | required; with row 9 | rows 9 and 12 use it | #1508 | | 11 | Brief template `docs/plans/BRIEF-TEMPLATE.md`; `queue add` refuses a missing brief | darkwing | #1508 | required; with row 9 | two briefs accepted by Jason with no scope question | `2026-09-13_queue-as-data.md`, Piece C |
| 12 | Reviews and receipts through the board or issue comments, not files in `docs/plans/reviews/` | darkwing | #1508 | required; after row 9 | one review round with no new file under reviews/ | #1508 | | 12 | Reviews as issue comments posted by `queue move ID in-review`, not files in `docs/plans/reviews/` | darkwing | #1508 | required; after row 9 | one review round with no new file under reviews/ | `2026-09-13_queue-as-data.md`, Piece D |
| 13 | Ledger checks: open issue has a row; in-progress row has a live seat; done row has a closed issue | darkwing | #1508 | required; after row 9 | violations printed with the weekly number, first run Monday 2026-09-21 | #1508 | | 13 | Ledger "queue" section: issue/row/seat drift printed with the weekly number | darkwing; filbert reviews | #1508 | required; after row 9 | first run Monday 2026-09-21, zero violations or every one moved same day | `2026-09-13_queue-as-data.md`, Piece E |
Start message for row 6, sent from the board to darkwing: Start message for row 6, sent from the board to darkwing:
"Read docs/plans/QUEUE.md, then the plan page section "Piece 5: darkwing on "Read docs/plans/QUEUE.md, then the plan page section "Piece 5: darkwing on
@@ -61,3 +61,4 @@ Gate F or when blocked."
- 2026-09-13 — rows 9 to 13 added (#1508): the process itself becomes data with one writer and ledger checks. Jason: "I want this iron-clad." Required, not parked; rule: these rows cannot be moved to parked, only to done. - 2026-09-13 — rows 9 to 13 added (#1508): the process itself becomes data with one writer and ledger checks. Jason: "I want this iron-clad." Required, not parked; rule: these rows cannot be moved to parked, only to done.
- 2026-09-13 — dewey: WebUI row advanced to Jason-owned Gate E after Filbert approval, exact committed-tree 208/208 and remote-verified ea00ec66 publication. No other row changed. - 2026-09-13 — dewey: WebUI row advanced to Jason-owned Gate E after Filbert approval, exact committed-tree 208/208 and remote-verified ea00ec66 publication. No other row changed.
- 2026-09-13 — rows 9 to 13 now point at the plan page `2026-09-13_queue-as-data.md` (pieces A to E, Gate G).