Operating

How work flows

The board is the queue and git holds the state. A merged pull request is the only thing that changes status. This page covers plans, features, issues, lanes and specs, and explains why no check can stop a merge.

Updated

Prompt 1

Learn how work flows from plan to merge

Reads this page, explains the three words, the five derived steps and the advisory gates back to you, then tests you on real scenarios. Writes nothing.

Prompt 2

Map your work loop onto plan → issue → merged PR

Surveys your tracker and repo for thin tasks, typed status and second trackers, then proposes spec/plan templates and a merged-PR finish line. Writes only after you confirm.

One principle sits under all of it. We keep no stored copies of state and run no resident processes, and the documents are the config. We delete anything that can drift instead of monitoring it. Anything that runs unattended reports on the board, which is where the founder already looks, so nobody can mistake silence for health.

The three words

There are three layers and one word for each. People confuse these words more often than any others, so the fleet retired a fourth word, "task", which used to mean two of them at once.

LayerWordWhat it isExample id
Above the boardPLANOne thinking session: a document, its research, and the open questions it settledPLAN-178
On the boardFeatureA body of shippable work with ordered child issues#5878
On the boardissueOne unit of work you can dispatch, run until its pull request merges#5882

A PLAN is not a Feature. A PLAN references Features but is not one. One PLAN can produce several Features, and some of what a PLAN decides never turns into work at all.

The five steps

1 BRIEF · 2 LOOP ⟳ ‖ 3 FILE · 4 DISPATCHED · 5 DONE
#StepWhat it means
1BRIEFThe founder's rough note, restated. No research has happened yet
2LOOP ⟳Research and questions alternate until the plan is complete
3FILEAt least one issue exists for this plan
4DISPATCHEDA master is doing the work
5DONEEvery referenced issue is closed

Nobody reports a step. The system works each one out. It reads steps 3 to 5 off the board every time it renders, and it reads steps 1 and 2 from events on the plan's own entry. Nothing anyone writes moves a step forward. A merged pull request does, because merging closes an issue. There is no status field for a human to set, so there is no status field for a human to forget.

Step 4 has a mode, and neither mode is "blocked". The two modes are DISPATCHED (unattended) and EXECUTING (interactive), where a human takes part but does not hold the work up. Being stuck is not a state. If you are stuck, you write a comment on the issue that says exactly what blocks you, and then you exit cleanly. The one outcome we do not accept is stopping without saying anything.

The loop, end to end

PLAN (a thinking session)
  └─ Feature issue  +  ordered sub-issues  +  a committed brief
       └─ the Architect DISPATCHES  (starting the run IS the assignment)
            └─ a master executes to merged + live
                 └─ git moves the board
                      └─ the founder glances at truth

The board

We use exactly one tracker, a GitHub organization project board. Every open issue in the knowledge repository is on it. When we measured on 2026-08-16, no work existed off the board.

Work that becomes a board issue lives on the board and nowhere else. In particular, it does not also go into an agent harness's private to-do list, because two trackers cannot both be correct.

Each row on the board has the issue, its Lane (the master that serves it), its Priority, its Portfolio, and a Status. The system works the Status out. Nobody types it.

Lanes, and the failure mode nobody expects

A lane sends an issue to a master. What matters most is what happens without one. If an issue has no lane, or sits on a lane that no master serves, no master can ever pick it up. This holds permanently, it happens without any warning, and it does not matter how idle the fleet is.

People misread this signal more than any other in the system. A board with plenty of open work and nothing dispatchable looks exactly like a capacity problem. People have gone looking for a broken scheduler while the scheduler printed the real cause every five minutes. On 2026-08-16 we found thirteen open issues that no master could pick up. Eleven had no lane at all, and two were on a lane that no sweeper reaches. That is a routing defect, and more compute does not fix it.

One command shows the cause:

# on novaserver, from the knowledge clone
bash _infra/scripts/sweep-dispatch.sh --explain

Board hygiene, honestly

We measured two weaknesses, and we record them here as they are:

  • Closed rows from other repositories never get cleaned up. The reconciler archives rows only for the repository it runs in, so closed items from sibling repos pile up. On 2026-08-16 they made up most of the rows on the board.
  • A row can have no lane and no status at all. Nothing rejects a row like that when someone creates it, and routing cannot see it.

Thick tasks: never work a thin one

A dispatched issue is more than one sentence. Its brief lives in the repository, next to the work:

<portfolio>/specs/<issue#>-<slug>/spec.md    objective · acceptance · scope · grounding
<portfolio>/specs/<issue#>-<slug>/plan.md    phases → checkbox items

The checkboxes in plan.md are the live state of the work. Tick each one through [ ] → [~] → [x] and commit as you go. This is not a report you write afterwards. After a context reset, a peer taking over or the founder looking in, everyone reads the same file. This has worked in practice. One master's run hit its cap, and a different master finished the work from that file alone.

Two rules keep the brief from going stale:

  1. The issue body must contain the literal spec path. A runner reads a spec only if the issue names it. If the issue does not name the spec, the master doing the work never sees it. This line matters more than any other in the pipeline, and it is the easiest one to leave out.
  2. If the spec refers to prerequisites that no longer exist, or there is no spec, stop cleanly and explain why on the issue. Do not keep working from a stale brief. A spec can cite machinery that no longer exists without anyone meaning harm, so whoever acts on it checks every reference again in that session.

A non-trivial architecture choice gets a decision record next to the work, in <portfolio>/specs/<issue#>-<slug>/decisions/. When you supersede one, edit the old record's Superseded-by header in the same commit. A decision that becomes invalid without anyone recording it is the failure this fleet repeats most.

Communication

One master reaches another by @mentioning a GitHub account in a comment on the relevant issue. There is no other mechanism. At the start of a master's next dispatched run, the system injects its unread mentions. Each mention arrives at least once, the read state persists, and the conversation happens where the founder already looks.

We run no chat system, no message bus and no inbox service. We had a NATS bus and deleted it. See Decisions.

We work out presence from observable work, such as a last commit or a last comment. Agents never report their own presence. A heartbeat that an agent writes about itself is a claim, not evidence.

Gates: all of them are advisory

Nothing gates main. On this GitHub plan tier, branch protection and rulesets both return 403 in every repository. We are not exploiting a loophole. That is the real configuration, and we built the fleet's process to state it openly.

So when a check is red, missing or never started, treat it as information and keep going.

The rule is to fix forward. When a check fails, find the real failure. A broken build or a genuine security finding is real, so fix it. Infrastructure being down is not, so use the documented fallback and carry on. Never wait for a human to unblock a merge.

GateIf it fails
Secret scanThis is the one hard stop. If the workflow cannot run, run the same pinned scanner locally (see Operations), and merge only after that
A real build, typecheck or deploy failureReal. Fix the code
Shell syntax checkReal, and cheap to fix. A script that the shell cannot parse cannot run. Read backwards from the reported line, because the shell reports an unbalanced quote at the next paren, not where the mistake is
A lint on a title, a filename, or a doc conventionNot real. It never blocks a merge

A merge never waits on a human. If a merge does not go through, read the actual error and act on it. Rebase a branch that conflicts, or use gh pr merge <n> --squash --admin. Escalating a merge with lines like "needs eyes" or "should I force it?" is banned. You can reverse a merge in git, and a pull request left open is what actually costs us.

We forbid two gate designs outright, because we tried both:

  • A gate that blocks on content keywords or on a generated map. Gates like that blocked documentation by mistake and reverted their own cleanup.
  • Resident processes, heartbeat polls and scheduled "health checks". The board is the queue, and the failure we guard against is silence.

Finishing

Work is finished when a pull request whose body says Closes #N merges. The merge closes the issue and moves the board. Nobody types a status, so the board cannot disagree with what git already recorded.

Turning on auto-merge does not finish the work. If the pull request is still open when the run exits, the work is not done, and the run's close-out comment must say so. Once, fifteen pull requests piled up unnoticed because runs treated an armed auto-merge as finished.

What the loop actually produced

We measured on 2026-08-16. Over the previous seven days the fleet closed 745 issues. Over the previous twenty-four hours it made roughly 157 dispatch runs, and two of them failed. Both failures filed their own board issue automatically through systemd's OnFailure path.

That last detail is the useful one. We did not design the system to avoid failure. We designed it so a failure reports itself within seconds, in a place a human already reads.

The uncomfortable part

Our doctrine says "the board is the ONLY tracker" and also "the plan.md checkboxes ARE the work state". We depend on both statements, and they contradict each other. If we count honestly, one body of work has four parallel trackers. They are the board, a plan registry, the plan documents themselves, and the checkboxes in each spec's plan.md. Some plan documents have no registry entry. The command center reads only entries, so it cannot see those documents.

We publish this instead of hiding it. A wiki that claims one tracker while the fleet runs four is exactly the kind of document this site exists to replace.

On this page