Custom Pipeline
The specdacular pipeline is fully configurable. Nothing is hardcoded. This guide covers the three customization mechanisms: hooks, workflow swaps, and full pipeline replacement.
How the pipeline works
Section titled “How the pipeline works”The default pipeline is defined in pipeline.json. The brain reads it on every continue invocation and dispatches accordingly:
{ "schema_version": "1.0", "pipelines": { "main": [ { "name": "discuss", "workflow": "discuss.md" }, { "name": "research", "workflow": "research.md" }, { "name": "plan", "workflow": "plan.md" }, { "name": "phase-execution", "pipeline": "phase-execution" } ], "phase-execution": [ { "name": "plan", "workflow": "phase-plan.md" }, { "name": "execute", "workflow": "execute.md", "pause": true }, { "name": "review", "workflow": "review.md", "pause": true }, { "name": "revise", "workflow": "revise.md", "pause": true } ] }, "hooks": { "pre-step": null, "post-step": null }}To override this, place .specd/pipeline.json in your project. This is a full replace — not a merge. The entire default pipeline is replaced by your file.
Option 1: Hooks
Section titled “Option 1: Hooks”Hooks are markdown workflow files that run before or after pipeline steps. They’re the lightest customization — you don’t change the pipeline structure, just add behavior around existing steps.
Convention-based hooks
Section titled “Convention-based hooks”The easiest way to add a hook: create a file at the right path. The brain automatically checks for:
.specd/hooks/pre-{step-name}.md.specd/hooks/post-{step-name}.mdFor example, to run something before every execution phase:
.specd/hooks/pre-execute.mdThe brain finds it automatically — no configuration needed.
Configured hooks
Section titled “Configured hooks”For explicit control over hook behavior, configure hooks in your .specd/pipeline.json:
{ "name": "execute", "workflow": "execute.md", "hooks": { "pre": { "workflow": ".specd/hooks/pre-execute.md", "mode": "inline", "optional": false }, "post": { "workflow": ".specd/hooks/post-execute.md", "mode": "subagent", "optional": true } }}Hook modes
Section titled “Hook modes”| Mode | Behavior |
|---|---|
inline | Runs in the brain’s context. Can read all state, task files, and pipeline configuration. |
subagent | Spawns a separate agent with fresh context. Isolated — ideal for side effects like notifications or external API calls. |
Hook error handling
Section titled “Hook error handling”| Setting | Behavior on failure |
|---|---|
optional: false | Stops the pipeline. State is saved. |
optional: true | Logs a warning. Pipeline continues. |
Hook execution order
Section titled “Hook execution order”Global pre-step hook (hooks.pre-step in pipeline.json) │Step pre-hook (hooks.pre in step config, or convention fallback) │ ▼Step runs │Step post-hook (hooks.post in step config, or convention fallback) │Global post-step hook (hooks.post-step in pipeline.json)Example: Notify a Slack channel after review
Section titled “Example: Notify a Slack channel after review”Create .specd/hooks/post-review.md:
# Hook: Post-Review Notification
Read the review outcome from config.json.
If the review was approved:- Post to the #deployments Slack channel: "Feature {task-name} phase {N} approved and ready for deploy."
If the review requested changes:- Post to #code-review: "Feature {task-name} phase {N} needs revisions."This runs automatically after every review step. No pipeline configuration needed.
Option 2: Swap a workflow
Section titled “Option 2: Swap a workflow”If you want to change what a specific step does — without altering the pipeline structure — point its workflow field to your own markdown file.
Example: replace the default research step with one that searches your internal knowledge base:
{ "schema_version": "1.0", "pipelines": { "main": [ { "name": "discuss", "workflow": "discuss.md" }, { "name": "research", "workflow": ".specd/workflows/custom-research.md" }, { "name": "plan", "workflow": "plan.md" }, { "name": "phase-execution", "pipeline": "phase-execution" } ], "phase-execution": [ { "name": "plan", "workflow": "phase-plan.md" }, { "name": "execute", "workflow": "execute.md", "pause": true }, { "name": "review", "workflow": "review.md", "pause": true }, { "name": "revise", "workflow": "revise.md", "pause": true } ] }, "hooks": { "pre-step": null, "post-step": null }}Custom workflow files use the same markdown format as the built-in ones. They receive $TASK_NAME as context.
Option 3: Full pipeline replacement
Section titled “Option 3: Full pipeline replacement”For teams with fundamentally different workflows, replace the entire pipeline. Create .specd/pipeline.json with whatever structure makes sense:
{ "schema_version": "1.0", "pipelines": { "main": [ { "name": "spec", "workflow": ".specd/workflows/spec.md" }, { "name": "approve", "workflow": ".specd/workflows/approve.md", "pause": true }, { "name": "implement", "pipeline": "implementation" } ], "implementation": [ { "name": "build", "workflow": ".specd/workflows/build.md", "pause": true }, { "name": "test", "workflow": ".specd/workflows/test.md", "pause": true }, { "name": "ship", "workflow": ".specd/workflows/ship.md", "pause": true } ] }, "hooks": { "pre-step": null, "post-step": null }}The pause field
Section titled “The pause field”Any step can be configured to pause before execution:
{ "name": "execute", "workflow": "execute.md", "pause": true }In default mode, the brain pauses here and asks: “Execute, Review plan, or Stop for now?”
In --auto mode, pause is ignored and execution continues without prompting.
In --interactive mode, the brain prompts at every step regardless of the pause field.
Practical patterns
Section titled “Practical patterns”Pattern: Require tests before review passes
Section titled “Pattern: Require tests before review passes”Add a post-execute hook that runs your test suite and fails if tests don’t pass. Since optional: false, a test failure stops the pipeline before review.
Pattern: Auto-deploy on phase completion
Section titled “Pattern: Auto-deploy on phase completion”Add a post-review hook that deploys to a staging environment when review is approved.
Pattern: Update a project tracker
Section titled “Pattern: Update a project tracker”Add a post-step global hook that updates a Jira/Linear ticket when each stage completes.
Related concepts
Section titled “Related concepts”- Pipeline lifecycle — How the pipeline runs end to end
- The orchestrator — How the brain reads and drives the pipeline