Pipelines
Step kinds, the default lifecycle, custom pipelines, and resume.
A pipeline is the ordered list of steps contractor run executes for a blueprint. Pipelines are defined in YAML — either inside a schema or in contractor/config.yaml — and resolved at run time against a precedence chain. The runtime is process-detached: a contractor pipeline-shim child process owns the run, and the dashboard or CLI tail it through the global SQLite database.
Step kinds
Every step in a pipeline is one of three kinds:
agent
Spawns the configured AI backend (default: Claude) with a slash-command prompt. Phase references in a schema's pipeline: resolve to agent steps automatically. Fields:
id— step id used in logs, the dashboard, and--gate-afterflags.slashCommand— e.g.implement.md. The runner reads the rendered slash command from.claude/commands/blueprint/.prompt— optional override for the agent prompt. Defaults are per-phase (e.g.Implement all remaining tasks for blueprint "<name>".).model,effort— backend-agnostic overrides (today honored by the claude backend only).critical—true(default) means a failure ends the run;falselets the pipeline continue.when— optional guard (e.g.when: scope) that skips the step under a condition.needs_prepared_worktree— whentrue, the runner injects a synthetic prepare step before this one (see Worktrees).
shell
Runs a shell command in the worktree. Useful for typecheck/test gates, deploy hooks, or formatter passes. Fields:
id— defaults to the command string when generated from a schema.command— the shell command. Supports{{scope}}substitution from the blueprint's scope.critical,when,needs_prepared_worktree— as above.
gate
Pauses the pipeline and waits for a user decision. Fields:
id,description— the description appears in the dashboard's gate prompt.when— optional guard.
Gate decisions are stored in the global DB. See Gates.
The default lifecycle
Both shipped schemas resolve to the same three-phase pipeline plus a single gate before close:
implement (agent, needs_prepared_worktree)
│
▼
review (agent — parallel-agents in base, single agent in lite)
│
▼
gate (pause for user)
│
▼
close (agent, non-critical)
If no schema, no project config, and no --pipeline flag specify a pipeline, contractor falls back to a hardcoded default with the same shape (buildStandardLifecycle). That fallback runs without a needs_prepared_worktree flag — schemas opt in.
Custom pipelines
A repo can define alternative pipelines under pipelines: in contractor/config.yaml:
# contractor/config.yaml
pipelines:
fast-iteration:
description: Implement and quick-review without close
steps:
- id: implement
kind: agent
slashCommand: implement.md
critical: true
- id: review
kind: agent
slashCommand: review.md
critical: false
rebase:
description: Pull main, refresh artifacts, no implement
steps:
- id: rebase
kind: agent
slashCommand: rebase.md
critical: trueThe same map is supported in ~/.contractor/config.yaml (user-level) for pipelines you want available across every repo on the machine. Project pipelines win over global pipelines on name collisions.
Select a pipeline at run time:
contractor run --pipeline fast-iterationOr pin one to a blueprint by adding pipeline: fast-iteration to its .contractor.yaml.
Resolution precedence
When contractor run resolves the pipeline for a blueprint, it walks this chain top-to-bottom and stops at the first match:
--pipeline <name>CLI flag.pipeline:field in the blueprint's.contractor.yaml.pipeline:field incontractor/config.yaml.- The schema's
pipeline:section inschema.yaml. - The hardcoded
contractor-lifecycledefault.
When the resolved name is set (cases 1–3), contractor looks up the named definition in the project pipelines map first, then the global pipelines map. An unknown name fails the run with Unknown pipeline "<name>". Available pipelines: ….
--resume
A failed pipeline run can be re-spawned without re-running its successful steps:
contractor run --resume <pipeline-run-id>
contractor run --resume last-failedlast-failed resolves to the most recent failed pipeline run for the current repo. Either form spawns a new shim process whose initial step state is hydrated from the parent run's child rows: completed, skipped, and cancelled steps are preserved as terminal; failed and running (orphaned) steps are reset to pending. findResumeIndex then picks the first non-terminal step and the new shim picks up there.
Two things to know:
- Only failed runs can be resumed. A
cancelledorcompletedrun rejects with an error. - Resume does not snapshot the worktree. If you edited files between failure and resume, the new run sees the current worktree state. That is usually what you want — fixing the failure is the point — but be aware that the resumed step starts against your edits, not the state that existed at failure.
For resuming a single agent session inside a pipeline, the claude --resume <session-id> hint that contractor prints on agent failure remains available as a manual alternative.