For Ethan, in plain English

Marathon mode

A normal plan is a sprint: decompose once, fan out workers, integrate, done. A marathon is the long-horizon version: one big goal (an "epic") that Nyx chews through over hours or days, building it one increment at a time, parking what it cannot do yet, researching what it does not know, and even adding new increments to itself as it learns. This page explains the loop, and the one thing you keep asking: when does it create a new plan.

The vocabulary (3 words)

epic vs increment vs plan
Epic
The whole goal

One big mission you hand it, like "build Helios and take it toward Series-A feature completeness." It has a goal and a working directory, and it lives until it is complete, stopped, or failed. You create one with POST /epic {goal, cwd}.

States: active, stopping, stopped, complete, failed
Increment
One slice of the epic

The epic is broken into ordered increments, each a single shippable step ("reconstruct the daily check-in form", "add the reimbursement engine"). Increments are the unit of work. They run strictly one at a time.

States: pending, running, committed, parked, failed, blocked
Plan
How one increment gets built

Here is the key relationship: one increment equals one plan. When the marathon decides to build the next increment, it dispatches a normal Nyx plan for it (the same planner, fanout, synthesizer, and gates from the How page). So the marathon is not a new way of building. It is a loop that keeps creating plans, one after another, until the epic is done.

Dispatched via: startPlan(brief, cwd)

The loop

one step per tick, every 60 seconds

The marathon is not a blocking script that runs start to finish. It is a daemon that wakes every 60 seconds and advances each active epic by exactly one step. That "one step per tick" rule is the whole trick: it means the system never blocks, you can stop it cleanly at any commit boundary, and it survives a restart (on reboot it reconciles whatever increment was mid-flight against its plan).

EPIC goal + working dir DECOMPOSE goal into increments MARATHON TICK one step / 60s PICK next increment only if none running DISPATCH startPlan(brief) a NEW PLAN, here only PLAN RUNS planner, fanout, synth, gates, verify increment marked running SETTLE read the plan result committed / failed / blocked next tick EPIC COMPLETE nothing pending/running/parked PARK (do not fake) increment needs a missing secret unparks when it lands in the vault SELF-EXTEND + RESEARCH add new increments to the queue as it learns never two increments at once; a new plan is created only at DISPATCH, only when nothing is running
dispatch (new plan) loop step parked (waiting) done

So, when does it make a new plan?

the exact answer

Each tick checks these in order and does the first one that applies, then stops until the next tick:

"A marathon is just a loop that creates one plan, waits for it to finish, then creates the next, until there is nothing left to build."

That is why you saw the Helios epic sit at active with zero increments for a moment: it was on step 2 (decompose) and had not reached the dispatch step yet. The increments, and their plans, appear a tick or two later.

An increment's life

the six states and how it moves between them
pending running its plan is live committed failed blocked parked dispatch new plan settle missing secret secret lands

committed is the happy path (the increment's plan passed the gates and landed). failed means the plan could not be made to pass; the epic records it and moves on rather than wedging. blocked means the increment needs something structural it cannot get. parked is the polite one: the increment needs a real secret or API key that is not in the vault yet, so instead of faking it, Nyx sets it aside and keeps building everything else, then automatically unparks it the moment you add the key.

Why build it this way

the design payoffs