The main session (supervisor)

What only the main session does: the session that starts the agents, talks to the owner and holds the versions. Builders do not need this file; the rules for everyone are in CLAUDE.md. Since the owner removed the architect role (2026-11-01) the supervisor also writes the briefs, keeps the lanes and the issues and decides obvious language gaps (Language decisions); anything else goes to the owner. The cycle and the hand-over between main sessions are below, under Running the lanes; briefs and reports under Briefs and reports.

Watching CI

Trunk, CI and issues

Moved from CLAUDE.md (2026-11-01); there each rule has its short form.

Versions and error codes

Agents in the shared checkout

Decision rounds with the owner

Some sessions only prepare and take decisions; another session builds them. What the owner expects from such a round:

Running the lanes

Moved from the former docs/architect.md (2026-10-31). nikaia here means target/fast/nikaia.

Roles

Moved from the former docs/architect.md (owner, 2026-11-01: the architect role is removed; its duties are the supervisor’s).

Role Who Job
Owner the person Sets goals, stages and priorities; decides what is theirs
Main session (supervisor) the session the owner started, all tools Talks to the owner; decides what is built next and how; writes ADR and specification text, briefs and issues; runs scripts/drive.nika; raises versions; watches CI and cost; improves the process
Builder .claude/agents/builder.md, no GitHub Builds one or two steps, commits locally after cheap checks, reports, ends; the driver runs the suite and pushes
QA .claude/agents/qa.md, Sonnet, no GitHub Started by the driver on a red suite; reads the unpushed briefs and reports, fixes forward, commits locally

The supervisor coordinates by briefs, and drive.nika runs them. A builder that hit an error does not go on: its report comes to the supervisor, whose next brief is the repair (the compiler defect first, CLAUDE.md’s Fix, do not work around), then the blocked step.

Pushing from a checkout that is behind (a dirty shared tree, so no rebase): push a merge, T=$(git merge-tree --write-tree HEAD origin/develop), then git commit-tree $T -p HEAD -p origin/develop and push that sha. Never rebuild your files on origin/develop’s tree with a scratch index: a file another session changed there is overwritten (2026-10-31: the y21 probe rule, restored by f96bb09a). Chain such steps with &&, never ;.

Language decisions (owner, 2026-10-31)

Language principles (owner, 2026-10-31), the measure for every language decision: complexity goes into the compiler, not to the user; whoever uses something pays for it, nobody else; consistency and harmony with what the language already says; and a look at how other languages solve it, to do it better.

Reported defects are filed (owner, 2026-10-31)

Every report with Result: partial|blocked and a Found: defect with a probe is filed by the supervisor when it reads the report: a GitHub issue in brief form (ready, the probe, To build) and a bug brief docs/briefs/bugs/b<N>-<issue>-<topic>.md with a Blocks: line, appended to docs/briefs/bugs/batch.txt, issue labelled wip. An open issue that already holds the defect gets the new probe as a comment instead.

Driver, suite and QA (owner, 2026-10-31)

Builders commit locally and push nothing. After each batch the driver has CI run the complete suite (one at a time per checkout, lock target/suite.lock: it pushes the tested sha to ci/<lane>, and the whole workflow runs on exactly that commit); green, it pushes the tested commit; red, it writes qa-input.txt and starts QA (docs/briefs/qa-task.md), at most two rounds, then ESCALATE. CI stays the final gate for what other sessions push meanwhile.

Lanes

The score in priorities.md decides; every brief names its score terms in 2-3 lines. Each lane has its own DIR with batch.txt, its own driver run:

The focus rotation (owner, 2026-11-01): drive.nika -- --focus runs the lanes of docs/briefs/focus.txt (main and bugs) in turn, a block of up to block briefs each, a Blocks: bug brief before any block. CUT and RED stop the driver for the supervisor’s next briefs; an area with no unrun brief is skipped. docs/briefs/focus-log.md holds one line per block.

Briefs and reports

A brief is one file DIR/<topic>.md, tracked (never a scratchpad: a fresh session has none). scripts/agent.nika starts the agent with Read your brief at <path>. It opens with this frontmatter (defaults builder, sonnet, 120, 20, medium):

---
agent: builder
model: sonnet
max_turns: 100
budget_usd: 20
effort: low
---

effort (passed to claude --effort) is low where the pattern is known (a form done before, a named test, a mechanical edit) and medium otherwise; high is accepted but not written into briefs; any other value stops the run.

A line Facts: <heading>, <heading> (or facts: in the frontmatter) names the ## / ### sections of docs/builder-facts.md the builder needs; agent.nika puts their text into its prompt under Facts for this brief, so it does not read the file whole. A heading ending in a parenthetical is named without it (Moving Rust into Nikaia); an unknown one stops the run.

Issues are written in brief form (owner, 2026-10-25): frontmatter, facts, Locations, To build steps with tests, rules, report form, so a builder can start on one directly. Builders have no GitHub access: a brief copies the issue’s problem, probe and To build steps.

A brief names the place (owner, 2026-10-31):

Before a brief is written, the supervisor checks (each tag is the run that paid for the rule):

Brief rules:

A move brief (owner, 2026-10-28) hands over its draft: one Cut: crates/<crate>/src/<file>.rs:A-B line per range (400-600 lines a brief), one Convert: --profile check|check-free|emit [--prefix X_] line (--prefix whenever the target file prefixes its names, P4b) and one Shape: line. agent.nika converts before the agent starts and names the draft. The brief names the callees’ locations, the syntax gaps the draft hits, the tests between steps, and the callers of what moves including crates/nikaia/tests/it/ (P4b).

A move is faithful unless a named reason forces a redesign (owner, 2026-10-29):

The report

The builder writes exactly <full brief path>.report.md, these fields only:

Result: done | noop | partial | blocked   (noop: nothing to change; batch.nika counts it done)
Files: <paths of the commit, space-separated>   (for scripts/commit.nika)
Commit: <subject line>
Body: <one paragraph for the commit message>   (optional)
Fixes: #N[, #M] | Part: #N   (optional)
Pushed: <sha> | rejected | none   (drive.nika rewrites `rejected` when it pushed the commit itself)
Tests: <test filters run> - pass | <failing names>
Gate: green | red <tests>   (#852; batch.nika cuts on red, #862)
Deviation: none | <one sentence>   (bare `none`, no note after it: batch.nika cuts on anything else)
Found: none | <one sentence, issue number if filed>
Needs: none | <NK code, supervisor decision, owner decision>
Changelog: none | <one sentence for the version heading>
Owner: none | <one question for the owner, never a role>   (batch.nika: `OWNER <brief>: <text>`; cycle.nika writes the first to DIR/QUESTION, a second while it exists prints `OWNER second: ...`)
Cache: none | <large entries newly created, MB>
Disk freed: <GB>
Measure: <builds=.. clippy_with_tests=.. ...>   (never under Found)
Attribution:   (last, the builder's trailer lines below it)

The builder ends its report with Attribution: and its own commit trailer lines; a brief carries none. The builder’s final answer is one line: done <sha>, report <path>, BLOCKED: <reason>, report <path> or PUSH REJECTED <sha>, report <path>, plus NEEDS: <short> when Needs is not none.

The supervisor reads the reports’ fields before the next batch. It files or updates issues from Found, comments on or reopens an issue a Deviation leaves open, lists what the change decided for the supervisor’s version heading, and picks the next batch.

Batches

Two or three briefs per batch (owner, 2026-10-25), in order. The driver starts the next brief when one says done; Found, a Deviation other than none, partial, blocked or Gate: red cuts the batch, and the briefs left come back to the supervisor with the reports, which writes the next batch.txt. The brief is the work order.

Stages

The owner sets the stage. 1 Serial: one builder at a time; a defect found on the way is repaired first. 2 Two: a second builder on files the first does not touch. 3 More: by the owner, with stage 2’s figures. Now (owner, 2026-10-26, widened by docs/bootstrap.md 3): stage 1 within each lane, the lanes side by side; throughput comes from scripts; the main session is woken only on an escalation.

Self-optimisation

Every cycle the supervisor looks at the reports for waste (polling, repeated builds, a missed rule, a chafing tool, a missing script), changes the rule or the tool at the source, and notes the figure in tokenspeed.md: tokens and turns per finished step, steps per day; counted, not timed.

State

Current state only, rewritten (not appended) by the supervisor: open lanes, what blocks what, figures, decisions in force that no ADR or issue holds. What happened is in git log and the issues. 2026-11-01 (after fb4c04b6). Self-hosting: 83.2 % of the toolchain as committed (scripts/self_hosting.py). Plan: docs/bootstrap.md, rows and Cut: lines in docs/selfhosting-plan.md.

This site is open source. Improve this page.