ready/manifest.yaml is the authoritative source for what stages exist, what they mean, and which one is the default. Tools never infer stage order or purpose from directory names.
What stages are
A stage holds the product truth for one discrete phase of work — a milestone, a release, a pilot, or a product concept. Primitives declare which stage they belong to via themilestone field. Flags and artifacts live inside stage directories. A stage is not a sprint and not a ticket board; it is a durable product grouping that persists in Git.
Stage kinds
Every stage entry in the root manifest declares akind. The kind tells tools and agents what the stage is for.
| Kind | Description |
|---|---|
normal | A buildable product stage. Default-selectable when default_candidate: true. |
horizon | A future product concept shelf. Not intended for near-term implementation. |
experiment | An alternative branch or product plan. Not default-selectable. |
archive | A completed or abandoned historical stage. Not default-selectable. |
template | A reusable starter shape for new stages. Not default-selectable. |
normal stage (e.g., m1) and one horizon stage (end-state). Add more normal stages as the product grows.
The stage registry
The rootready/manifest.yaml owns all stage configuration. Each entry in the stages list requires nine fields:
| Field | Type | Description |
|---|---|---|
id | string | Stable stage id. Used in milestone fields on primitives. |
title | string | Human-readable label. |
path | string | Relative path to the stage directory. |
manifest | string | Relative path to the stage manifest file. |
kind | string | Stage kind: normal, horizon, experiment, archive, or template. |
status | string | Current lifecycle status: active, complete, horizon, etc. |
order | integer | Sort priority for default selection. Higher order = preferred. |
default_candidate | boolean | Whether this stage is eligible for automatic default selection. |
coding_claims_enabled | boolean | Whether coding agents may claim flags in this stage. |
Default stage selection algorithm
Whendefault_stage in the root manifest is absent or does not point to a valid stage, tools select the default deterministically in four steps:
Use the explicit default_stage
If
default_stage names a valid stage id, use it. This is always the first choice.Highest-order normal default candidate
If
default_stage is absent or invalid, choose the stage with the highest order value where kind: normal and default_candidate: true.Highest-order normal stage
If no normal default candidate exists, choose the highest
order stage where kind: normal, regardless of default_candidate.end-state is excluded from the default path not because of its name but because it is kind: horizon and default_candidate: false. If you rename it to vision and keep the same kind and flag, it behaves identically.The end-state (horizon) pattern
Every product tree should include a horizon stage to hold long-term product concepts that are not yet implementation work. Set it up like this:order: 9999 keeps it sorted last in any view that uses order as a hint. default_candidate: false ensures tools skip it in the default selection algorithm.
A complete stages example
Here is a root manifeststages block with three stages: two active milestones and one horizon.
default_stage: "m2" is set explicitly, tools go straight to M2. If you remove the default_stage line, the algorithm falls to step 2 and still picks M2 because it has order: 20 — higher than M1’s order: 10 — with kind: normal and default_candidate: true.
Adding a new stage
Create the stage manifest
Copy the milestone manifest template to
ready/m2/manifest.yaml and update the milestone, stage.id, stage.title, and source_root fields.Add the stage to the root manifest
Append a new entry to the
stages list in ready/manifest.yaml. Assign an order value higher than the previous active stage. Set kind: normal, status: active, and default_candidate: true for a standard buildable milestone.Moving work between stages
When a primitive belongs in a different stage, update two things: themilestone field inside the primitive’s .ready.yml file, and the file’s location in the directory tree. Keep ids stable — the id is the durable identity; the path and milestone field are refactorable.
Archiving a completed stage
When a stage is done, update its entry in the root manifest:kind to archive. The directory and its primitives remain in Git history — nothing is deleted.
The coding_claims_enabled field
coding_claims_enabled controls whether coding agents may claim flags inside a stage. Set it to true only when:
- The stage has at least one seed or delta flag with
claimable: true - The required services, credentials, and environments are confirmed available
- The workspace Coding work switch is enabled
false by default. Enabling coding claims on a stage that is not ready leads to blocked agents and incomplete work. You can enable it per-flag via claimable: true on the flag itself; the stage-level field is an additional gate.