Skip to content

Human in the lead, not just in the loop.

Give your agents a sprint. They report back for your approval.
Agree the goal. Sign the page.

You

Agree

You approve the goal and the plan once, and that approval opens the run; after that it does not stop to ask.

sprint.py plan --write
  1. 01 / Plan

    Checks each unit is scoped and sized, orders the batch against the agreed goal, and forecasts what it will cost.

    sprint.py plan
  2. 02 / Build

    Builds each unit test-first and runs its acceptance criteria.

    verify_ac.py run
  3. 03 / Review

    One reviewer who did not write the unit judges it, in at most two rounds.

    critic.py brief
  4. 04 / Close

    Closes the run in one pass and files a one-page report of what shipped and what did not.

    sprint.py close
  5. 05 / Learn

    Turns what went wrong into failure classes the next plan and briefs carry.

    retro.py extract

Return belt Learn back to Plan

You

Sign

You read one page and sign it once, which moves each unit to Done or Fixed; the sign command refuses anyone who wrote or reviewed a unit.

sprint.py sign

A factory can run with the lights off when nobody needs to stand on the floor: the line checks its own work and stops itself when something goes wrong. The dark factory is this project’s name for the aim of running a v6 sprint like that: you agree the goal at one end and sign the report at the other, and the stations in between plan, build, review, close and learn without you. The rest of this page says how far that holds today: what runs by itself, where you step in, and what stops the line.

It is a way of running a sprint, not a command or a mode. You start it as you start any v6 sprint, with sprint.py plan, and the sprint pages teach the loop step by step.

What it is not:

  • Not unattended from start to finish. During the run that shipped v6.0.0 its operator ruled 8 times. Some decisions are yours by design, and where that line falls is a written rule the run is told to keep, not a check the tool makes: it stops for a push, tag, release or delete, or for anything outside the repository and the approved batch.
  • Not a goal the machine checks. The goal is one sentence you agree. Whether it was met is judged against the batch units’ own acceptance criteria and recorded as the goal verdict when the run closes.
  • Not autonomy outside the sprint. Choosing what to build, shaping the backlog, releasing and deploying stay with you.
  • Not a finished safety system. The andon cord, the stop that would halt the line and wake you before an irreversible action, is not built. What stops the line says what does stop it today.

Each mechanism the site tracks carries a plate naming the release it shipped in, read from the site’s data rather than typed into the page.

in 6.0
Ships in the release its plate names (6.0 or 6.1). Where this page describes it, it names the command that runs it.

Two touchpoints are designed in. A third is raised only when the run meets a question it may not answer for you.

You

Agree

The Plan station orders and sizes the batch and forecasts its cost. You approve a one-sentence goal and that plan, once, and the approval opens the run. Planning runs by itself; approving it is yours.

sprint.py plan --writein 6.0

You

Sign

You read the one-page report and sign it once. The signature moves each unit to Done or Fixed through its own gate. The sign command refuses a principal who wrote or reviewed a unit in the run.

sprint.py signin 6.0

You, when asked

Questions deferred to you

A question only you can answer sets its unit aside without halting the batch, and the run puts every such question to you together. The release run for v6.0.0 did not use this path: its operator ruled 8 times, as each question came up.

sprint.py decision listin 6.0

Once you approve the plan, the stations in the band above run in order. Each unit is built test-first against its acceptance criteria, reviewed by one reviewer who did not write it, and either approved or, still rejected after its second round, carried to a later run. The close runs every step once and draws the report. A step that fails is handed to you as a known issue on the report rather than holding the page back.

The report is the one page you sign, and it is written for someone who was not in the room. This is the shape of the report the v6.0.0 release run handed over.

RPT0011

Sprint report, RUN-01M3HR74

  1. 01 / Goal

    The one sentence you agreed, and the goal verdict recorded at the close.

    v6.0.0 ships: Maya and Jonah install, upgrade and learn it from docs and notes that match the code.

    Judged achieved

  2. 02 / Estimates

    Forecast against actual for points, minutes and tokens, each cell naming its source.

    Tokens spent against the forecast: 0.5x. Wall-clock span: 29.5h.

  3. 03 / Delivered to plan

    Planned, delivered, added mid-run, dropped and carried, with each unit's review rounds.

    Points delivered: 131.

  4. 04 / Known issues

    Every open finding the run raised, by id and priority, handed over rather than hidden. A step of the close that failed is listed here too, instead of holding the page back.

  5. 05 / Sign-off

    Who signed, when, and the fingerprint of the page they signed.

Appendix: tokens by model, delivery measures, calibration, rulings, waivers in force, what each gate refused, and the lessons in force.

The release run's report, section by section. Read RPT0011 as signed.

A question inside a seat’s lens (engineering, product or QA) is ruled by that seat and recorded, citing any earlier ruling on the same subject, so the run does not wait for you. Under D0232 a seat’s ruling binds inside the sprint’s boundary and is only advice at its edge, so a seat can never approve a step outside it.

  • A question in a seat's lens is ruled by that seat, citing any earlier ruling on the subject, so the run does not wait for you.

    decisions.py rule
  • A question only you can answer sets its unit aside without halting the batch, and every such question is put to you at once.

    sprint.py decision defer

The line between a seat’s question and yours is drawn by the agent following the sprint docs, not by a check in the tool.

A seat’s ruling does not need a fresh, independent context (D0235). That decision makes the ruling’s record its audit trail and asks it to carry the seat, the reasoning and the option turned down; decisions.py rule records the seat, the question, the ruling and the reason. Independence is kept where the work itself is judged: the review of each unit and your signature.

Each signed report counts who ruled. No budget caps the questions put to you yet (D0234): the count is measured and reported every run first.

Questions ruled, per signed report
ReportRuled by a seatRuled by the operator
RPT000640
RPT000720
RPT000830
RPT000940
RPT001020
RPT001108

The first five runs recorded no operator ruling at all. The release run, RPT0011, was the other way round: 0 ruled by a seat and 8 by the operator. They were: which evals gate the release and what counts as their evidence (D0279, D0280, D0282, and D0283 restating D0279); which findings to fix before the cut (D0284); and one unit’s extra review round (D0285) for BG0818, which then landed past the review cap by force (D0286) and through a one-call config change (D0287). A release asks for decisions that are yours to make.

Nothing in 6.1 halts a run to wake you. What it does is set a failing unit aside, carry a rejected one, park a question for you, and let you end a run on the record.

Today, in the release

  • A unit that keeps failing, or fails the same way twice, is flagged to be marked Blocked while the run goes on; a declared appetite stops the run at a unit boundary once it is spent. The appetite is a ceiling on the run’s wall-clock time or its units that you declare; the stop leaves every unit in its true status.

    loop_guard.py budget
  • Each unit is judged by one reviewer who did not write it, briefed by the shipped tool, in at most two rounds; a unit still rejected at the cap is carried as a bug.

    critic.py brief
  • The reviewer whose REJECT carried a unit at the review cap can discharge it with an APPROVE, and the unit moves to Done or Fixed with no force. An extra round for a unit that was never carried is still granted by raising review.max_rounds under a recorded decision. In the 6.0.0 release run one unit, BG0818, was granted a third review round by its operator (D0285), and its approval landed past the cap by force (D0286): the gap BG0850 closed.

    critic.py record
  • A question only you can answer sets its unit aside without halting the batch, and every such question is put to you at once.

    sprint.py decision defer
  • A run can be stopped; while a unit is unanswered the stop is refused unless forced, and a forced stop names each unit it waived.

    sprint.py stop

What went wrong in one run is carried into the next plan and the next review briefs. That much ships. Proving a lesson stuck does not.

  • The cost per point is re-measured from the newest runs at every plan, and you can set it by hand.

    sprint.py plan
  • What went wrong in a run is recorded as a failure class, and its rule is carried into the next plan and each review brief.

    lessons.py classes
  • A class that repeats twice after it was recorded files one change request to fix its failing path, and reads graduating.

    sprint.py close
  • Once the change request a graduating class filed ships, the close marks the class graduated, with no hand edit; a class whose request was rejected is retired instead, so a later repeat revives it.

    sprint.py close

The token forecast now tends to run high: in four of the six v6 runs below, the run spent about half of what was forecast. The time forecast is newer, and it has missed in both directions.

A class being recorded is not proof it stops recurring. In the release run’s report, the most frequent class, “criterion words outrun the fixture”, was already graduating with its change request filed, and it still recorded hits in that same run.

Six v6 sprints, each run by this project on its own code and closed with a signed report. The span is wall-clock, so waiting counts. These are one project’s runs on itself, not a benchmark.

The v6 runs, from each signed report
ReportSpanPoints deliveredTokens against forecastGoal verdictSprint goal
RPT00068.7h581.14xJudged achievedA sprint runs start to finish on its own, learns from itself, and hands you one page.
RPT00075.4h420.5xJudged partialCommits clear in about a minute, and the sprint learns from repeated mistakes without being told.
RPT00087.2h321.03xJudged partialA commit clears in ninety seconds, and every commit lane left standing shows what it caught.
RPT00097.0h1110.51xJudged partialMaya's units are reviewed once against their files' history, and the review paperwork nobody reads is deleted.
RPT001027.3h1020.53xJudged achievedMaya runs the lean loop on a fresh v6 project, and the release candidate ships.
RPT001129.5h1310.5xJudged achievedv6.0.0 ships: Maya and Jonah install, upgrade and learn it from docs and notes that match the code.

v6.0.0 shipped with 35 open Medium defects and no open Critical or High one, each listed by id on its known-issues page. v6.1.0 ships with two, one Medium and one Low, listed on the 6.1.0 known-issues page.

Before v6, measured 23 September 2026

  • A v5-era run stood open for 14.5 to 59.6 hours.
  • 82% of the last 116 v5 sprint units built or repaired the sprint, review and gate machinery rather than the product.
  • The v5 token forecast missed by 4.07x on geometric mean.

From the back-to-basics review that set v6’s shape. It describes the process v6 replaced; it is not the other half of a before-and-after trial, because the runs above differ in size and kind.

An eval runs a fresh agent session on a prepared project, and a separate session grades its transcript. Two scenarios speak to the dark factory. Read the caveats with the results.

09-lean-sprint

A fresh agent runs a lean sprint

On 6.0.0's code
Pass

A fresh agent, with the shipped docs alone, ran a sprint on a small project from the plan to the stop for the signature.

  • Its prompt approved the plan in advance, so the Agree touchpoint was not exercised.
  • Two small stories, one run.
  • One advisory fail: the report’s token actual read NOT MEASURED.

06-independence-gate

The work is judged by someone else

On the release candidate
Fail
On 6.0.0's final skill
11 of 11 behaviours

On the candidate, the worker approved its own fix with no separate reviewer. The guidance it followed named none, and that was fixed.

  • The final result is one fresh run, recorded once.
  • Three earlier attempts were discarded and disclosed: one loaded the old skill beside the new one, one ran on a fixture whose test could not fail, and one passed on a fixture hardened after it was graded.
  • The worker handed its reviewer a trimmed brief, which the bug docs allowed.
  • The two recorded runs used different harnesses.

The other scenarios ran on the release candidate and were not re-run on 6.0.0. The v6.0.0 release notes give every scenario’s result.

The idea was set out in RFC0060, The dark factory: a sprint that decides for itself, accepted on 21 September 2026. It began with this project’s own runs. One recorded its goal achieved while a High finding it had filed showed part of that goal unmet. One session stopped for fourteen operator rulings, of which about four needed a person. The RFC asked for four things: a goal the close could check, a written boundary for the sprint, seats with authority inside it, and an andon cord for the edge.

The rulings on it are in the decisions log: a seat’s ruling binds inside the boundary (D0232); the andon cord carries two conditions, an irreversible action and a step outside the boundary (D0233); no budget on your rulings until they are measured (D0234); a seat’s ruling needs no independent context (D0235). The boundary was dropped from the run meant to build it (D0240), and on 1 October 2026 the operating domain was ruled to be this repository plus the approved batch, with nothing built to record it (D0290).

Why the clause-checked goal was taken out. RFC0060 first made the goal a contract: numbered clauses, each with its own check, and a verdict the close derived by running them. Two days later the back-to-basics review found that it had turned goals into plans, and none of them named an outcome for a user. D0253 replaced it with one sentence of user value, twenty words or fewer, judged by the batch units’ own acceptance criteria and recorded as the goal verdict at the close (D0254). The cost is plain: the verdict is judged, not derived. From RFC0060 these stand: a seat’s authority inside the boundary (D0232), the andon cord’s two conditions (D0233), kept as a written rule rather than a mechanism (D0290), and the ruling that a seat’s ruling needs no independent context (D0235).