Files
stack/docs/plans/BRIEF-TEMPLATE.md
T
jason.woltje 95d4991d20 docs: brief template run lists come from imports (mos-1612)
A builder's whole-file run list for a row comes from imports, not a text
grep, and goes in the builder's report before the run. Files on the
mos-1592 list stay off unless Mos approved the run. Row 329 round 2's
path grep matched fixture text and reran case1-accept.
2026-10-24 16:39:32 -05:00

5.7 KiB

Brief template

Copy the section below into the brief file for a queue row, one ## heading per row. The row records the file path and that heading as its brief anchor (--brief docs/plans/<file>.md#<heading>), plus the git blob of the committed file.

Rules the queue enforces (queue-as-data plan 8.13):

  • the brief is committed before queue add or a brief change names it; a staged or untracked brief is refused;
  • the heading occurs exactly once in the file;
  • a later edit to a committed brief makes next flag the row and start refuse until the lead re-pins it.

queued means the brief exists, not that it is accepted. The row moves to briefed when a privileged actor (jason or sage) accepts it; the owner can't.


<Piece name, the row's one-line piece text>

Problem

What is wrong or missing today, with evidence: file paths, issue numbers, command output. One paragraph.

Owner and reviewer

  • Owner: the seat that does the work.
  • Reviewer: the seat that reviews it, or "none" and why.

Files owned

Every path this piece may create or change. Anything else is out of scope unless the brief is amended.

What ships

The concrete result: code, tests, docs. Name the test suites that must pass.

Out of scope

What this piece deliberately leaves alone, and where that work goes.

Gate

Who says yes, and on what evidence: the command to run, the output to expect, or the comment to read.

Every seat, Claude or Codex, runs the suites with a short TMPDIR: export TMPDIR=$(mktemp -d /mnt/storage/scratch/tmp/XXXXXX), 31 bytes. A launch refuses when its run's tools.sock path passes 107 bytes (packages/seat/src/session.mjs:278). Tests build that path under TMPDIR and drop the launcher log, so the refusal shows only as a 20-second "no RESULT". packages/cli/tests/revoke-window.test.mjs needs TMPDIR at 35 bytes or less. A seat-named TMPDIR such as .../tmp/goldieXXXXXX (37) fails it on any commit (row 323, mos-1561). A builder whose cli suite can't run says so in the row, and the cli suite counts from the lead's landing gate.

Make the TMPDIR with shell mktemp -d and that template only. Python's tempfile.mkdtemp adds _ and runs to 48 bytes, which fails claude-session.test.mjs:298 and the socket limit (Vikunja 590). A script that starts several runs makes one TMPDIR per run.

Set nice absolutely, not relative. The host's ananicy renices node, so nice -n 10 can land at 16 or at -4. In shell use nice -n $((19 - $(nice))) CMD. In a Node or Python launcher set 19 in each child (os.setpriority or os.nice(19 - os.nice(0)) in preexec). Record the nice each run saw in BUILD.md (Vikunja 623, mos-1598).

Evidence that lands with a row is plain text: logs, diffs, manifests. No gzip or other binary file, so the lead's push guard runs its binary and secret checks with no waiver. If a log is too big, cut it to the lines that prove the claim. Or keep it off refactor, in the seat's scratch, and cite its path and sha256 in BUILD.md (mos-1570, after row 265's 22 gzip logs).

Builders never run npm or remove files in the canonical checkout (/mnt/storage/src/mosaic-stack), only in their own worktree. Every gate, the builder's and the lead's landing gate, runs its own npm ci --ignore-scripts --no-audit --no-fund in its worktree root and in packages/webui, and never links to canonical node_modules (mos-1575, after canonical node_modules was found empty at 05:45:15Z 10-24 and row 327's gate went red on it).

A skipped cli test turns the lead's landing gate RED unless it is on the gate's skip list (mos-1583, after row 296's FED R7 test). An entry is the test file, the test name and the runner script, for example tests/federation-acceptance.test.mjs, "FED R7 scratch two-instance acceptance", scripts/test-federation-acceptance.sh. The skip passes only when that runner ran in the same gate with rc 0, at least one pass, no skips, and the named test passed. A builder whose new cli test skips in the suite by design and runs through a script puts that entry in the brief's Gate and in BUILD.md with the row, and the lead adds it to the landing gate's list. Any unlisted skip stays RED.

A builder's list of whole test files to run for a row comes from imports, not from a text grep for a path, and goes in the builder's report before the run. A file on the mos-1592 list (packages/cli/tests/case1-accept.test.mjs for now) stays off the list unless Mos has approved that run (mos-1612, after row 329's round 2 grep matched fixture text and reran the F7 file).

Any row that builds businessDoc() with a library project sets the chief's gitea ref in its fixture (mos-1584, after row 285 gave the chief of staff a read-scoped gitea credential that the validator requires when a business declares a library).

A made-up credential in a test stays under 24 characters, for example const SEAT_TOKEN = 'fx286-seat-q7'. The push guard stops any added line where token, secret or password is assigned a quoted value of 24 or more letters, digits, _ or -, and it has no fixture exception (sage-4112, after row 286's 31-character fixtures stopped its landing push).

Handoffs

Every seat hands off directly (DECISIONS Q210, mos-1221). When the owner pushes a build or a new round, or the reviewer posts a verdict, that seat messages the next seat's T3 thread and Sage's with mcp__t3__t3_send_message. Claude and Codex seats both have it. Copy Mos's thread only when Mos has a step. Nobody waits on a date or a schedule when the next step is ready. Reports, questions and slot requests for Sage go to Sage's thread, 1ef1e4f8-3ead-4208-beca-38f9f1add079, with the [from: ... -> to: ...] header, never to Mos's thread in Sage's place (mos-1591, after Beakley, Fethry and Herb reports reached Mos).