Starting projects
Choose an entry path based on what you already know and what already exists. These skills do not require an existing active project. They create or import tracked work, although quick-start, lite, brief, and goal resume an active project of their own mode, and import writes into whichever project is active.
| Your situation | Entry skill | Result |
|---|---|---|
| Requirements need discovery and a full technical design. | oat-project-new | A spec-driven scaffold, ready to begin discovery. |
| The outcome is bounded, with optional design decisions to resolve. | oat-project-quick-start | Discovery and an executable plan, with lightweight design when needed. |
| The change fits one implementation sitting. | oat-project-lite | One approved plan with requirements and validation criteria. |
| One delivery whose outcome and design you can agree in conversation. | oat-project-brief | One reviewed, approved Project Brief whose phases carry intent and exit evidence. |
| An outcome that needs several deliveries over time. | oat-project-goal | One approved Project Brief with milestones, delivered and re-aligned in turn. |
| You already have a Markdown plan. | oat-project-import-plan | The original source preserved beside a normalized OAT plan. |
| Implementation happened without project tracking. | oat-project-capture | Retroactive discovery and implementation records from the session and commits. |
| A confirmed scope contains several coordinated projects. | oat-project-split | A coordination parent and children that resume at discovery. |
For the broader mode decision, see Choose a workflow. For an existing project's discovery, design, or plan, see Planning skills. The skill catalog provides the complete supported-skill inventory.
A few terms recur on this page. The active project is the project recorded as
activeProject in .oat/config.local.json, which project skills act on by
default. Spec-driven is the full workflow: discovery, design, plan, then
implementation. An artifact is a project file such as discovery.md,
plan.md, or state.md.
Before your first project
Check these before you start. Each one can stop or misdirect a first project in a fresh repository.
-
Initialize the repository and install the workflows pack. Run
oat init --scope project, then install the pack that contains the project skills, also with--scope project. If you leave out--scope project,oat inituses its default scope,all, and also writes under your home directory, and the pack installs to your user scope instead of the repository:oat init --scope project oat tools install workflows --scope projectSee Bootstrap and Tool packs.
-
Decide where project files live. New projects default to the
syncedscope. A synced project is stored on its own Git ref and pushed to a remote namedoriginevery time a skill saves it. In a repository with nooriginremote, creating a synced project fails with "Synced project creation requires a configured origin remote." Either add anoriginremote, or change the default before you start:oat config set projects.defaultScope sharedsharedkeeps project files in the repository and commits them on the current branch.localkeeps them on this machine only; OAT adds a.gitignorerule for them. This command writes the repository's.oat/config.json. TheOAT_PROJECTS_DEFAULT_SCOPEenvironment variable overrides the setting for one shell. -
Only
oat-project-newtakes a scope. It accepts--scope shared|local|synced. Quick-start, lite, brief, goal, import, capture, and split have no scope argument. Quick-start, lite, brief, goal, import, and capture always create projects in the default scope. Split uses the active project's scope, orsharedwhen no project is active. Set the default first if you do not wantsynced. -
Build the knowledge index before spec-driven discovery.
oat-project-discoverrefuses to start until.oat/repo/knowledge/project-index.mdexists. Run/oat-repo-knowledge-indexonce before your first spec-driven project. Quick-start, lite, brief, goal, import, and capture do not check for it. -
Know what happens when a project is already active. Check with
oat config get activeProjectbefore you start:oat-project-newandoat-project-capturecreate a new project and make it active instead.oat-project-quick-startresumes an active quick project and ignores the name and description you pass. If that plan is already implementation-ready, it goes straight intooat-project-implement.oat-project-literesumes an active lite project and ignores the name and description you pass. With any other project active, it creates a new lite project.oat-project-briefresumes an active brief project at the earliest step whose output is missing. With any other project active, it creates a new brief project.oat-project-import-planwrites into any active project, whatever its mode. It rewrites that project'splan.mdand switches it to import mode.oat-project-splitmakes its first child the active project.
To start fresh work, run
/oat-project-clear-active(or switch with/oat-project-open) first.
Before invoking an entry skill
Examples beginning with / are skill requests sent to your agent, not terminal
commands. In a provider that uses $ skill syntax, use $oat-project-new instead
of /oat-project-new, and apply the same substitution to the other names.
Blocks labelled bash contain terminal commands.
Project creation normally activates the new project in .oat/config.local.json.
Check the reported project path before continuing, especially when another
project is already active.
The new, quick-start, lite, brief, goal, and import skills check inherited Git changes before
scaffolding. Unrelated changes require an explicit disposition in interactive
runs. One exception: if the only change is .oat/sync/manifest.json, it is
committed automatically as chore: run sync. Capture does not run this check.
Do not assume starting a project also authorizes implementation or a PR.
Dispatch policy. Before a plan is marked ready, quick-start, lite, brief,
goal, and import ask you to choose a dispatch policy: the highest tier of models and
effort OAT may use when it dispatches implementation and review agents. The
choices come from oat project dispatch-ceiling choices. If your configuration
has no complete dispatch ladder (the list of models for each tier), the skill
shows the bundled recommendation and asks whether to adopt it into shared,
local, or user config. That writes a config file, so pick the scope
deliberately. The plan stays not ready until this resolves. See
Dispatch policy.
Approval checkpoints. A HiLL (human-in-the-loop lifecycle) checkpoint is
a point where a skill stops and waits for your explicit approval before it marks
a phase complete. Projects created by oat-project-new have checkpoints on
discovery and design by default. Quick, lite, brief, goal, import, and
captured projects have no workflow-phase checkpoints before implementation.
Lite still asks you to approve its plan once, brief asks you to approve its
reviewed brief once, and goal asks for that approval and then one per later
milestone. See HiLL checkpoints.
Several skills also run a configured exit gate, an optional review or command
your repository configures to run before a skill marks its work complete. When
a gate produces a review the skill can accept, the skill hands it to
oat-project-review-receive without asking.
oat-project-new
Use this entry when you need the spec-driven lifecycle but have not yet explored the requirements. This skill creates the project structure. It does not conduct discovery or draft the design.
Invocation: Send the project slug to your agent. Use --scope when the
project's storage scope must differ from the resolved default.
/oat-project-new webhook-delivery --scope sharedPrerequisites: No active project is needed; this skill creates one. You
need an initialized repository (see Before your first project).
The name accepts letters, numbers, dashes, and underscores. Omitted scope uses
projects.defaultScope, which defaults to synced. Synced projects need a Git
remote named origin, and creating one pushes the project to origin. In a
repository without origin, or if you do not want that push, pass
--scope shared or --scope local.
Example scenario: You need webhook delivery across several services, but
retry limits, ownership, and failure handling are still undecided. Create
webhook-delivery in shared scope so its artifacts live in the repository.
Choose this entry rather than quick-start because the requirements and component
boundaries need a full discovery and design pass.
Expected output: The scaffolder creates standard project artifacts, reports
their scope and path, sets the active project, and refreshes the local dashboard
when enabled. Templates resolve from the repository, then user scope, then the
bundle. The scaffold is not an approved plan. Its state.md sets HiLL
checkpoints on discovery and design.
What it does without asking: After the Git-changes check, it runs
oat project new, which creates the project directory and artifacts, makes the
new project active (replacing any active project), and refreshes .oat/state.md.
It also records the scaffold in Git: a commit in shared scope; in synced scope,
a push to origin plus a commit of the project record and of any .gitignore
rule it added; in local scope, a .gitignore rule that it leaves uncommitted.
It does not start discovery.
Next step: If .oat/repo/knowledge/project-index.md does not exist yet, run
oat-repo-knowledge-index first; discovery refuses to start without it. Then
invoke oat-project-discover to
explore the problem. The optional --force scaffold flag allows the same slug
to exist in another scope and fills missing files without overwriting existing
content. It is not a reset.
oat-project-quick-start
Use quick-start to turn a bounded request into a runnable plan without requiring separate spec and design phases. Discovery depth follows the ambiguity of the request, not the number of files you expect to change.
Invocation: Supply a name and a substantive description. A bare name prompts for the description before repository exploration begins.
/oat-project-quick-start export-filter "Add a date-range filter to CSV exports, preserving the current default output."Prerequisites: No active project is needed. The repository must contain
OAT scaffolding, including .oat/ and .agents/, and you need a task
objective. The new project uses the default scope, because quick-start takes no
scope argument. If the active project is a quick project, quick-start resumes it
and ignores the name and description you pass. If that plan is already
implementation-ready, it goes straight into oat-project-implement. To start a
different piece of work, run oat-project-clear-active (or open another
project) first. The contract does not define what happens when the active
project uses another mode, so clear or switch it first in that case too.
Example scenario: The export endpoint works, and you know which date range users need. You still need to decide where the filter belongs and how to verify unchanged default exports. Quick-start captures those constraints and either plans directly or adds lightweight design before writing tasks.
Expected output: A new or resumed quick project has discovery.md, an
execution-ready plan.md, and initialized implementation.md. The design
decision can select straight-to-plan, lightweight design.md, or promotion to
spec-driven. Lightweight design does not create spec.md and offers
collaborative or draft-and-review interaction, not selective collaborative.
Before marking the plan ready, the skill asks you to choose a dispatch policy (and, if needed, where to adopt a dispatch ladder), then records the plan-review result. It commits changed project artifacts and runs any configured exit gate. If promotion is selected during discovery, it stops with a design handoff instead of generating a quick plan.
What it does without asking: It creates the project through
oat project new in the default scope (commit or push as described under
oat-project-new) and makes it active. It commits the changed artifacts
(discovery.md, design.md, plan.md, implementation.md, state.md) before
every pause and again before handoff; in synced scope each commit is an
oat project push to origin. It runs the plan artifact review automatically,
usually in your current agent session, and may launch a separate reviewer agent
when the current model is unknown or below the reviewer tier. It applies
unambiguous Critical and High fixes to plan.md. It runs any configured exit
gate and passes an eligible result to oat-project-review-receive. When it
resumes a quick project whose plan is already ready, it starts
oat-project-implement. It asks before: proceeding with a dirty working tree,
choosing design depth (skipped for clear requests with no design questions),
confirming the requirements behind the plan, choosing a lightweight design
mode, adopting a dispatch ladder into config, choosing the dispatch policy,
enabling an extra phase gate review, and keeping or disabling configured gates
for this project.
Next step: Follow the reported handoff to oat-project-implement once the
quick plan is ready. If interrupted before readiness, run quick-start again to
continue in place. Do not use oat-project-plan to finish a quick plan.
oat-project-lite
Use lite for a change that fits one implementation sitting and needs explicit requirements, proof, and approval in one plan. Lite keeps resumable task commits and review while removing separate discovery, spec, and design documents.
Invocation: Provide the slug and the intended change.
/oat-project-lite retry-message "Show the failed request's retry delay in the CLI error message without changing retry behavior."Prerequisites: No active project is needed. You need an OAT-initialized
repository and a change intended to fit one sitting. The new project uses the
default scope, because lite takes no scope argument. If the active project is a
lite project, lite resumes it and ignores the name and description you pass.
With any other project active, lite creates a new lite project and makes it
active. To start a different piece of work while a lite project is active, run
oat-project-clear-active first. Unresolved implementation-affecting design
decisions or a larger task list trigger promotion to quick mode.
Example scenario: Users cannot tell when the CLI will retry a failed request. The retry algorithm is already correct, so the change only adds the delay to the message. Lite asks one batched round of critical questions (plus a short follow-up only if your answers raise new ones), records the message behavior and its proof, and gives you one plan to approve.
Expected output: A single sequential phase in plan.md, with Summary,
Decisions, Assumptions, Out of Scope, and executable Validation Criteria. The
selected content shape adds Product Behavior, Technical Design, or both when
needed. This example changes visible behavior, so product content is required.
The skill persists the authored plan before approval, asks you to choose a
dispatch policy, records artifact review, and runs the configured exit gate
before marking readiness. It creates no spec.md or design.md, no parallel
group, and no phase-review or HiLL checkpoint setup. If
it promotes instead, the authored plan remains available to quick-start.
What it does without asking: It creates the project through
oat project new in the default scope and makes it active. It writes
plan.md, state.md, and implementation.md and commits them three times:
after authoring (before approval), after artifact review, and at completion. In
synced scope each commit is an oat project push to origin. If its
escalation check finds that the work will not fit one sitting or a design
decision is unresolved, it runs oat project promote --to quick and stops,
pointing you to quick-start. Artifact review runs with no pause and applies only
unambiguous fixes. It runs any configured exit gate and passes an eligible result
to oat-project-review-receive. It asks before: proceeding with a dirty working
tree, the critical interview, approving the plan (approve, revise, or promote),
adopting a dispatch ladder into config, choosing the dispatch policy, and
keeping or disabling configured gates for this project.
Next step: Run oat-project-implement after the approved lite plan is ready.
If the scope grows, continue through oat-project-quick-start after promotion.
oat-project-brief
Use brief for one delivery whose outcome and design you can agree in
conversation. Brief replaces discovery, design, and a task plan with one
reviewed Project Brief in plan.md. Its phases state intent and exit evidence
instead of tasks.
Invocation: Provide the slug and the intended outcome.
/oat-project-brief export-audit "Let administrators export the audit log as CSV from the settings page."Prerequisites: No active project is needed. If the active project is a brief project, brief resumes it in place.
Example scenario: Administrators need the audit log as CSV. Brief interviews you in short rounds, settling facts from the code itself and putting the design choices to you, such as streaming against buffering the export. It writes the agreed outcomes, approach, decisions, and phases into the brief, runs artifact review and any configured gate, and asks you to approve the reviewed brief once.
Expected output: One Project Brief in plan.md with a Goal, numbered
Outcomes that each name their evidence, the Approach (with an optional
### Design subsection), Constraints and Out of Scope, Decisions with the
alternatives you rejected, Known Unknowns with the phase that settles each,
the Delivery endpoint and authority, and ## Phase pNN: blocks. Each phase
states its **Intent:**, **Exit evidence:**, and whether it is
**Provisional:**; only the first phase has to be concrete now. The skill also
initializes implementation.md as a per-phase journal with one section per
phase and no execution records yet. There is no discovery.md, spec.md, or
design.md, and no task list: tasks are recorded in the journal as the work
runs.
The interview runs in readiness rounds. The agent settles facts from the code, docs, or research itself and brings you only decisions, each with a recommendation and its tradeoff. It writes the brief once you have explicitly agreed the design, so the approval confirms a design you already accepted. Within the approved outcomes, constraints, and authority, the agent may later add, split, or reorder phases and make provisional phases concrete, and logs each change; a change to an Outcome, a Constraint, the authority, the endpoint, a Decision, or the Approach comes back to you first.
What it does without asking: It creates the project through
oat project new --mode brief in the default scope and makes it active,
commits the authored brief before any review, runs the independent artifact
review (the reviewer receives the brief and the bundled brief contract, not the
conversation), runs any configured oat-project-brief gate and records its
outcome as oat_brief_gate in state.md, and commits the approved brief and
journal. In synced scope each commit is an oat project push to origin. It
asks before: proceeding with a dirty working tree, the interview decisions,
adopting a dispatch ladder into config, choosing the dispatch policy, keeping
or disabling configured gates for this project, and the single approval
(approve, revise, or promote to quick).
Promotion to quick. Choose promote at the approval, or later run
oat project promote <project-path> --to quick, when you want a maintained,
approved up-front task plan. Promotion keeps completed execution records as
quick tasks, lists phases that still need tasks in
oat_promotion_pending_phases, and hands off to oat-project-quick-start.
Before the brief is written and committed there is nothing to promote: abandon
the scaffold and start oat-project-quick-start instead. See
Lifecycle.
Next step: Run oat-project-implement after the brief is approved.
oat-project-goal
Use goal when an outcome needs several deliveries over time. Goal writes one
reviewed Project Brief like brief does, and adds a ## Milestones table that
groups its phases into milestones. Each milestone is implemented, reviewed,
delivered as its own pull request, and followed by a short re-alignment before
the next one starts.
Invocation: Provide the slug and the intended outcome.
/oat-project-goal audit-exports "Give administrators audit exports in CSV first, then scheduled delivery."Prerequisites: No active project is needed. If the active project is a goal project, goal resumes it at the step its state calls for: authoring, milestone activation, re-alignment, or the terminal declaration.
Example scenario: Administrators need audit exports now and scheduled delivery later. Goal interviews you once for the whole outcome, splits it into milestone m01 (CSV export) and m02 (scheduled delivery), and activates m01. When m01's pull request is delivered, goal asks what changed, amends the brief with m02's phases, takes the amendment through review and approval, and activates m02 once m01 reaches the endpoint you agreed, such as merged.
Expected output: One Project Brief in plan.md with
oat_plan_source: goal, a canonical | Milestone | Phases | table in which
every phase belongs to exactly one milestone, and the first milestone approved
and activated. Each milestone's approval is recorded as its plan gate carrier
in state.md; deliveries are recorded in the oat_deliveries registry by the
delivery skills.
What it does without asking: It creates the project through
oat project new --mode goal, commits the brief before review, runs the
artifact review and any configured oat-project-goal gate, refreshes delivery
observations with oat project delivery refresh, and appends one project-log
entry at each activation and re-alignment. It asks before: proceeding with a
dirty working tree, the interview decisions and milestone split, each approval,
the re-alignment questions, and declaring the goal met.
Next step: Run oat-project-implement after the first milestone is
activated. Between milestones, oat-project-goal re-aligns and activates the
next milestone once the previous delivery reaches its agreed endpoint.
oat-project-import-plan
Use import when the plan already exists, including one produced in a provider's native plan mode. Import preserves the source before translating it into OAT task and review structure.
Invocation: Provide the local Markdown path. The provider hint records where the plan came from.
/oat-project-import-plan ./plans/cache-refresh.md --provider codex --project cache-refreshPrerequisites: No active project is needed. The external file must exist,
contain content, and use .md unless you explicitly confirm another Markdown
extension. OAT repository scaffolding must be available.
If any project is active, import writes into that project, whatever its
mode: it normalizes the plan into its plan.md and switches it to import mode.
That includes a spec-driven project in the middle of design. --project is read
only when no project is active. To import into a new project, run
oat-project-clear-active first.
In the default synced scope, the import contract can resolve the wrong
project directory for a new project: it looks for the new project under
projects.root (.oat/projects/shared by default) while the scaffolder creates
it under .oat/projects/synced. Until that is fixed, set projects.defaultScope
to shared before importing into a new project, or create the project first and
import into it while it is active. Confirm the reported project path afterwards.
Example scenario: You drafted cache-refresh work in Codex plan mode and now
want stable task IDs and tracked execution. Your repository's default scope is
shared and no project is active, so import creates cache-refresh and
imports the saved file into it. Choose import instead of quick-start because
the plan's intent and ordering already exist and need preservation, not another
discovery conversation.
Expected output: references/imported-plan.md preserves the source.
plan.md contains normalized phases, stable pNN-tNN tasks, verification,
review rows, and imported provenance. The source file remains unchanged.
Replacing an existing source snapshot requires confirmation. A timestamped
snapshot preserves a later import.
The skill asks you to choose a dispatch policy, records import-aware plan review, initializes the implementation tracker, persists artifacts, and runs any configured exit gate. A normalized single-phase plan with no parallel group can offer lite execution. Accepting that offer preserves import provenance. A single phase alone does not mean the work fits one sitting, so keep import mode for longer-running work.
What it does without asking: With no active project, it creates one through
oat project new --mode import in the default scope, or activates an existing
project of that name under projects.root. It copies the source into
references/, writes the normalized plan.md, sets the project's workflow mode
to import (or lite if you accept the offer), creates implementation.md if
missing, makes the project active, and refreshes .oat/state.md. Plan review
runs automatically and applies unambiguous Critical and High conformance fixes.
It then commits references/, plan.md, implementation.md, and state.md;
in synced scope that is an oat project push to origin. It runs any
configured exit gate and passes an eligible result to oat-project-review-receive.
It asks before: proceeding with a dirty working tree, naming the project when no
project is active and --project is absent, picking a plan file when you gave
no path, accepting a non-.md extension, the lite offer, adopting a dispatch
ladder into config, choosing the dispatch policy, enabling an extra phase gate
review, and keeping or disabling configured gates for this project.
Next step: Use oat-project-implement after the import handoff completes.
Resolve missing verification detail before execution. Normalization can expose
TODO-style gaps rather than invent a proof for the external author.
oat-project-capture
Use capture after implementation happened outside OAT tracking. Capture records why the work happened from the conversation and what changed from Git history. It does not invent a retroactive execution plan.
Invocation: Invoke the skill in the session that knows the work's context. You can explain the goal in the same conversation.
/oat-project-capture
Capture the retry middleware we implemented in this session as a project, ready for review.Prerequisites: No active project is needed; capture creates a new one in
the default scope. You need a feature branch with at least one commit beyond its
base and available conversation context. If a project already tracks the
branch, use oat-project-reconcile instead. With no branch commits to capture,
this skill reports that there is nothing to capture yet.
Example scenario: A small retry fix grew into middleware and tests during an untracked session. The commits explain the changes, but not why one retry policy was rejected. Capture uses that conversation to preserve the reasoning and groups related commits into implementation records for review.
Expected output: A quick-mode project with oat_workflow_origin: captured,
populated discovery.md, and implementation.md entries tied to commit SHAs.
You confirm the proposed project name and the discovery summary, and choose
whether the work is ready for review or still in progress. The scaffold's
plan.md template is acceptable, but capture writes no retroactive plan tasks,
spec, design, or new implementation.
What it does without asking: It runs oat project new --mode quick in the
default scope (commit or push as described under oat-project-new), which makes
the new project active and replaces any active project. It writes state.md,
discovery.md, and implementation.md, commits them (an oat project push in
synced scope), and refreshes .oat/state.md. It asks before: using the proposed
project name, accepting the discovery summary, and setting the work as ready for
review or still in progress.
Next step: For review-ready work, use oat-project-review-provide before
sharing it, or oat-project-pr-final to open a PR directly. For work still in
progress, continue implementation and reconcile new commits into the tracked
project.
oat-project-split
Use split after a discovery or brainstorm has confirmed several coordinated projects. The parent records their relationship. It does not become another implementation project.
Invocation: Provide a persisted split-plan JSON file, not just child names. The skill passes that file to the split orchestrator.
/oat-project-split --plan-file ./split-plan.jsonThe corresponding terminal command is:
oat project split run --plan-file ./split-plan.jsonPrerequisites: No active project is needed. You need a saved split-plan
file (a SplitPlanDocument) and a confirmed split trigger. An explicit
multi-project declaration, a confirmed discovery recommendation, or the
brainstorm split destination can supply the trigger. Detected recommendations in
non-interactive execution must fail fast, not silently choose a split.
A split confirmed during discovery or brainstorm does not produce this file. Those skills hand split an in-conversation payload, and split currently accepts only a saved file, so the file must be saved before split can run. You (or your agent) write it as JSON with this shape:
{
"origin": "detected-convergence",
"interactive": true,
"plan": {
"parentSlug": "billing-platform",
"children": [
{
"slug": "billing-migration",
"description": "Move invoicing onto the new billing service.",
"inheritedContext": "Discovery decisions that apply to this child.",
"knownDependencies": [],
"order": 1
},
{
"slug": "reporting-redesign",
"inheritedContext": "Discovery decisions that apply to this child.",
"knownDependencies": ["billing-migration"],
"order": 2
}
],
"initialActiveChild": "billing-migration"
}
}origin is one of declared, detected-mid-stream, detected-convergence,
or brainstorm-picker. foundationChild and integrationSketch are optional
fields of plan. Check the file before running split:
oat project split validate-plan --plan-file ./split-plan.jsonExample scenario: Discovery identifies a billing-service migration and an
independent reporting redesign. You confirm that each needs its own project
while keeping their integration context. Discovery's split offer does not save a
plan file, so you (or your agent) write the parent, children, and ordering to
split-plan.json in the shape above. Check it with
oat project split validate-plan --plan-file ./split-plan.json, then invoke
split with that file. Split creates a coordination parent, seeds the children in
order, and activates the initial child.
Expected output: The parent has oat_kind: coordination, ordered child
links, references/split-plan.json, and complete decomposition status. It has
no executable spec, design, plan, or implementation artifacts. Children are
created as quick projects. They retain parent, sibling, and dependency links, but
their discovery remains in progress. Inherited context needs revalidation, and
child plans remain template placeholders rather than implementation-ready plans.
What it does without asking: It runs oat project split run, which creates
the parent and every child in the active project's scope (shared when no
project is active). In synced scope it pushes each project to origin; in
shared and local scope it does not commit. It writes the parent's state.md,
discovery.md, and references/split-plan.json, removes the parent's
executable phase files, seeds each child, makes the initial child active, and
refreshes .oat/state.md. It asks for the plan file path when you give none,
and asks before resuming a partially completed split.
Next step: Revalidate the active child's inherited context through its
discovery path. Children are quick projects, so resume the active child with
oat-project-quick-start, which picks it up at discovery. If generation stopped
partway through, rerun the orchestrator using the persisted split plan rather
than rebuilding seed data from child slugs. See Project splitting
for the full coordination contract.