Working the Queue

How the Principal runs it

An item's life starts on Define, as a conversation that ends in a committed spec. The moment that spec exists, it's on the queue — this page is what happens from there: what the Principal actually looks at each time he decides what happens next, how he keeps a growing pile of AI sessions from turning into a growing pile of tokens, and how he keeps two of those sessions from quietly overwriting each other's work.

Every open item is a file with a header — state:, owner:, blocked_by:, files:. Nobody reads forty of those by hand. A board reads them for him.

What gets looked at

The board, not the backlog

One command, run constantly, computes the state of everything from the spec headers themselves — never from a person's memory of where things stand.

Principal — any session

python3 tools/board.py --next

A real morning's output, 2026-08-02:

NEXT: /review T36

2 verdicts left: T36, T91

then 10 startable: T84, T89, T95, T56, T67, T68, T71, T93, T77, T94 (22.25h)

NEEDS YOU: T7, T9

25 open, 41.2h total

Five lines answer the only question that matters: what's next, what's waiting on a verdict, what's safe to run at the same time, and — the line read first — what needs a decision only he can make.

The same data renders as a page inside the app, for the same reason a phone bill has a summary line before the itemized detail: /admin/docs/board, labeled PM in the admin nav. Both read the identical headers; neither is more current than the other.

What that decides

Verdicts first, then whatever unblocks the most

The board ranks; it doesn't choose blindly by number. Four rules, applied in order, stop at the first one that fires:

  1. An unreviewed build outranks a new one. A commit sitting without a verdict blocks its own spec from archiving, and often blocks other work behind it — four queued verdicts is a queue, not a backlog.
  2. Whatever unblocks the most work goes next. An item three others are waiting on outweighs a standalone item twice its size.
  3. A kicked-back item before a fresh one. The work is already mostly done and already verified once; what's left is usually the cheapest hours on the board.
  4. Only then, by value — not by ID number. The board's own "startable" list is deliberately greedy and unordered beyond that; judging which of those is actually worth doing next is why this is a decision a person makes, not a script.

What gets typed

One command per handoff

Sequencing takes four commands, and none of them require judgment about the code — only about order. /projectplan shows the state above from inside an Architect session; /nextdev and /nexttw write the actual briefing to a file and hand back a short summary; /build is what a fresh session types to pick that briefing up and take the role it names.

The full command reference — including /review, /accept, and /checkpoint — lives on Build; this page only covers the four that decide sequence.

Managing the cost

One session, one item, then a fresh one

Every AI session costs tokens for as long as it stays open, and a long-running conversation costs more the longer it runs — context accumulates whether or not it's still useful. So the Principal doesn't keep one session alive across a whole day of items.

The pattern: dispatch an item, let the session build or review it, get the one-line result, and close that session. The next item opens in a blank one. This only works because of Define's core property — every handoff is a committed file, not a conversation — so a fresh session with zero memory of anything that came before can still pick up exactly where the last one left off, just by reading what's on disk.

The same discipline applies inside a single item, not just between them: a session that has already built or reviewed one thing starts fresh for the next rather than chaining, and a role never widens mid-build to cover work outside its own spec. Both rules are stated on Meet the team; here they're the reason token cost stays roughly flat as the queue grows, instead of climbing with every item added to it.

Running several sessions at once adds a second problem: two of them touching the same file. A spec declares exactly which files it owns before anything is dispatched, and those lists are checked against each other — an item whose files overlap with whatever is already running does not get handed out, even if nothing else about it is wrong. The check runs on blocked_by too, not just files: an item is only offered once everything it depends on is actually done, never "probably done by the time this finishes."

Without this

What goes wrong when nobody's holding the schedule

This isn't hypothetical. Before the board existed, the Architect hand-scheduled one day's work eight separate times and got it wrong five of those times:

Sent toWhy it was wrong
/build on an undispatched itemno briefing existed yet — never actually assigned
/build on a paused itemits own spec said no rework was wanted; the builder refused
/build on a held itemthe dispatch note itself said ON HOLD
/build with no briefingnothing to read; nothing to build
marked "waiting" on the wrong itema phantom blocker — the two items shared no files at all

Every one of those was information already sitting in the repo — a session just had to read five files to find it, and didn't. The other failure mode is worse: two windows were handed the same item, on the same filesystem, at the same time — the exact collision the file-ownership check above exists to make impossible. Without something holding the whole schedule in view, picking "what's next" by memory or by gut degenerates into exactly this: real conflicts, real overwritten work, caused by a dependency nobody re-checked before typing the command.

The PM page, working as designed

What it should show, in a perfect world

This is the target the admin PM page is built toward — not a status report on today, a description of what the page is for. Four things, always visible at once: what's done, what's next, what's running right now, and roughly when the running work clears.

What's done and what's next is the one table underneath everything else — every open item, grouped WIP / SPRINT / BACKLOG, sorted group then phase then ID, no prose in the cells. A glance says where the work is, not a paragraph explaining it.

What's running right now is a strip of windows, each one an ID and a clock:

Window A [ T74 ] started 15:08 · 47 min [done]

Window B [ T82 ] started 15:44 · 11 min [done]

Window C [ ] → next: /build T66 [save]

A slot nobody remembered to clear still shows its clock running — it looks stale rather than looking busy, which is the entire point. The scheduler that fills an empty slot never suggests an item whose files overlap with anything already running, and never suggests the same ID to two windows at once — the exact two failures the table above documents happening by hand. When nothing is eligible, it says why and when the next slot opens, rather than just "nothing available":

Nothing eligible. T28 frees when T29 finishes in B (est 1.0h, started 15:44, ~14 min left).

Roughly when it clears is already real today, in the plain board output — not a mockup, this ran on 2026-08-02:

SPRINT — phase 1 (3, 7.00h)

wave 1: T83, T100

wave 2: T84

→ 7.00h serial, 6.25h at 2 windows, 6.25h wall-clock if unlimited parallel

Three numbers, one line: how long it takes one window, how long with the windows actually open today, and the floor if every eligible item ran at once. The PM page's job is to put that estimate next to the windows that are live right now, instead of a separate command someone has to remember to run.