Skip to content

Commit afaefe5

Browse files
committed
Add pipeline extension
Chains the Spec Kit phases into one guided, single-invocation pipeline with a deterministic phase resolver and one interactive clarify gate.
1 parent bba473c commit afaefe5

13 files changed

Lines changed: 799 additions & 0 deletions

File tree

extensions/pipeline/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
__pycache__/
2+
*.pyc
3+
.pytest_cache/
4+
.DS_Store

extensions/pipeline/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Changelog
2+
3+
All notable changes to the Pipeline extension are documented here. Format based on
4+
[Keep a Changelog](https://keepachangelog.com/); this project adheres to Semantic Versioning.
5+
6+
## [1.0.0] - 2026-07-05
7+
8+
### Added
9+
10+
- Initial release.
11+
- `speckit.pipeline.run` — chains `specify → clarify → plan → tasks → analyze → implement`
12+
into one guided invocation with a single interactive clarify gate and an
13+
analyze → fix → re-analyze loop (≤3 cycles) before implement.
14+
- `speckit.pipeline.preview` — dry-run printer for the resolved phase plan.
15+
- `--skip` / `--add` flags with a deterministic phase resolver (`scripts/resolve_phases.py`),
16+
strict validation, and dedicated exit codes (10–14).
17+
- Insertable phases: `constitution` (before specify), `checklist` (after tasks).
18+
- `--yes` unattended mode: answers the clarify gate in-place, halting before `plan`
19+
on a question too consequential to answer without a human.
20+
- Bash + PowerShell wrappers over the Python resolver.
21+
- Stdlib `unittest` suite covering default order, permutation invariance, and every exit code.

extensions/pipeline/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Dominik Mattioli
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

extensions/pipeline/README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Pipeline — a Spec Kit extension
2+
3+
Chain the [Spec Kit](https://github.com/github/spec-kit) phases into **one guided, single-invocation pipeline** instead of hand-running seven commands.
4+
5+
```
6+
specify → clarify → plan → tasks → analyze → implement
7+
```
8+
9+
`/speckit.pipeline.run` drives each phase in order, pausing exactly once — at an interactive **clarify** gate — then advances unattended through the rest, re-running `analyze` until findings are resolved (up to 3 cycles) before it implements. The phase order is produced by a small, deterministic resolver, so a tailored pipeline (`--skip`, `--add`) always lands in the same canonical order.
10+
11+
## Why
12+
13+
Taking a feature from description to implemented change means issuing `/speckit.specify`, `/speckit.clarify`, `/speckit.plan`, `/speckit.tasks`, `/speckit.analyze`, `/speckit.implement` by hand — and hand-resolving each analyze finding in between. This extension collapses that to a single invocation with one human checkpoint, while keeping every phase's own command as the source of truth (it *drives* the stock commands, it does not reimplement them).
14+
15+
## Commands
16+
17+
| Command | What it does |
18+
|---|---|
19+
| `speckit.pipeline.run` | Run the full pipeline from one feature description, with a single clarify checkpoint. |
20+
| `speckit.pipeline.preview` | Print the resolved phase plan for the given flags without running anything (dry run). |
21+
22+
### Flags
23+
24+
- `--skip <csv>` — drop default phases (e.g. `--skip clarify,analyze`). `specify` and `implement` cannot be skipped.
25+
- `--add <csv>` — insert optional phases: `constitution` (before specify), `checklist` (after tasks).
26+
- `--yes` — unattended run. Answers the clarify gate itself (grounded in the spec/repo) rather than pausing for a human, and **halts before `plan`** if a question is too consequential to answer unattended. `--yes` never means "no clarification" — use `--skip clarify` for that.
27+
28+
## Examples
29+
30+
```
31+
# Full default run
32+
/speckit.pipeline.run Add rate limiting to the public API
33+
34+
# See the plan first, then run a tailored pipeline
35+
/speckit.pipeline.preview --add checklist --skip clarify
36+
/speckit.pipeline.run --add checklist Add a healthcheck endpoint
37+
38+
# Unattended (CI / routine), clarify answered in-place, halts on a consequential question
39+
/speckit.pipeline.run --yes Migrate config loading to env vars
40+
```
41+
42+
## How the resolver works
43+
44+
`scripts/resolve_phases.py` (pure Python, stdlib only) is the deterministic core. It takes the requested skip/add sets, validates them, and returns the phase list in a fixed canonical order. Ordering is a pure function of the *effective set*, so flag ordering never changes the result. Validation is strict, with dedicated exit codes:
45+
46+
| Exit | Meaning |
47+
|---|---|
48+
| 0 | resolved OK |
49+
| 10 | unknown phase name |
50+
| 11 | a phase is in both `--skip` and `--add` |
51+
| 12 | `--add` names a non-insertable phase |
52+
| 13 | `--skip` targets a required phase (`specify`/`implement`) |
53+
| 14 | dependency break — a retained phase's dependency was skipped |
54+
55+
`run` and `preview` both call the resolver, so a bad flag combination is caught before any phase runs. `scripts/bash/resolve-phases.sh` and `scripts/powershell/resolve-phases.ps1` are thin wrappers over the same Python, matching Spec Kit's `scripts.sh` / `scripts.ps` command convention.
56+
57+
## Agent-neutral
58+
59+
The extension ships no dependency on any specific AI agent, model, or vendor tooling — it drives only stock `/speckit.*` commands (or their skills-mode equivalents `speckit-plan`, `speckit-tasks`, …). It works in any Spec Kit-initialized project regardless of which of the 30+ supported agents you use.
60+
61+
## Layout
62+
63+
```
64+
pipeline/
65+
├── extension.yml # manifest
66+
├── commands/
67+
│ ├── run.md # the orchestrator command
68+
│ └── preview.md # dry-run phase-plan printer
69+
├── scripts/
70+
│ ├── phase_registry.py # deterministic resolver core (pure, no I/O)
71+
│ ├── resolve_phases.py # CLI over the resolver (exit codes 10–14)
72+
│ ├── bash/resolve-phases.sh
73+
│ └── powershell/resolve-phases.ps1
74+
├── config-template.yml # optional per-project defaults
75+
├── tests/test_phase_registry.py # stdlib unittest — determinism + exit codes
76+
├── README.md
77+
├── CHANGELOG.md
78+
└── LICENSE
79+
```
80+
81+
## Install
82+
83+
Until it is listed in the community catalog, install by copying `pipeline/` into your project's Spec Kit extensions location (or your fork's `extensions/pipeline/`) so the two commands register on init. See the catalog submission notes in the parent directory's contribution guide.
84+
85+
## Tests
86+
87+
```
88+
cd pipeline
89+
python3 -m unittest discover -s tests -p 'test_*.py'
90+
```
91+
92+
## License
93+
94+
MIT — see [LICENSE](LICENSE).
95+
96+
## Provenance
97+
98+
Ported from the `speckit-pipeline` orchestration skill (formerly `speckit-workflow`), decoupled from its origin repo's internal tooling into a portable, agent-neutral Spec Kit extension.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
description: "Print the resolved Spec Kit pipeline phase plan for the given --skip/--add flags without running anything — a dry run of the deterministic phase resolver."
3+
scripts:
4+
sh: scripts/bash/resolve-phases.sh
5+
ps: scripts/powershell/resolve-phases.ps1
6+
---
7+
8+
# Pipeline: preview
9+
10+
Show the phase plan `/speckit.pipeline.run` *would* execute for a given set of flags, without running any phase. Use it to confirm a tailored pipeline (skips/adds) resolves the way you expect before committing to a full run.
11+
12+
## Input
13+
14+
`$ARGUMENTS` — optional flags only (no feature description needed):
15+
16+
- `--skip <csv>` — default phases to drop.
17+
- `--add <csv>` — insertable phases to add (`constitution`, `checklist`).
18+
19+
## Behavior
20+
21+
Run the resolver and print its output:
22+
23+
```
24+
{SCRIPT} --skip "<skip csv>" --add "<add csv>"
25+
```
26+
27+
Each line is `order phase command gate description`, in the exact order `run` would execute. `--list` (no flags) dumps the full registry of orderable phases.
28+
29+
Report the resolver's exit code and, on any non-zero code (`10``14`), its stderr message verbatim — the same validation `run` performs, so a bad flag combination is caught here first. This command never edits files and never invokes a `/speckit.*` phase.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
description: "Run the full Spec Kit pipeline (specify → clarify → plan → tasks → analyze → implement) from one feature description, with a single interactive clarify checkpoint and a deterministic, tailorable phase order."
3+
scripts:
4+
sh: scripts/bash/resolve-phases.sh
5+
ps: scripts/powershell/resolve-phases.ps1
6+
---
7+
8+
# Pipeline: run
9+
10+
Carry one feature from a plain-language description to an implemented change by chaining the existing Spec Kit phase commands into a single guided run. You (the agent) **are** the orchestrator: you follow this procedure turn by turn, invoking each `/speckit.*` command in order and verifying its artifact landed before moving on. This replaces hand-running `/speckit.specify`, `/speckit.clarify`, `/speckit.plan`, `/speckit.tasks`, `/speckit.analyze`, and `/speckit.implement` one at a time and hand-resolving analyze findings.
11+
12+
## Input
13+
14+
`$ARGUMENTS` — the feature description, optionally followed by flags:
15+
16+
- `--skip <csv>` — drop default phases (e.g. `--skip clarify,analyze`). Cannot drop `specify` or `implement`.
17+
- `--add <csv>` — insert optional phases: `constitution` (before specify), `checklist` (after tasks).
18+
- `--yes` — unattended run. Does **not** skip clarification; instead you answer the clarify questions yourself, grounded in the spec and repo conventions, and halt before `plan` if a question is too consequential to answer without a human (see Step 4). Use `--skip clarify` if you genuinely want zero clarification.
19+
20+
If the feature description is empty, report the missing input and stop — do not start.
21+
22+
## Step 1 — Resolve the phase plan (deterministic)
23+
24+
Run the resolver once and branch on its exit code:
25+
26+
```
27+
{SCRIPT} --skip "<skip csv>" --add "<add csv>" --json
28+
```
29+
30+
(`{SCRIPT}` is this command's configured `scripts.sh` / `scripts.ps`.)
31+
32+
Exit codes: `0` OK · `10` unknown phase name · `11` skip/add name conflict · `12` add-name not insertable · `13` skip targets a required phase · `14` dependency break. On any non-zero code, report the resolver's stderr message verbatim and stop — do not run a partial or incoherent pipeline. The order is deterministic: the resolver consumes skip/add as sets and derives order from one fixed key, so flag ordering never changes the plan.
33+
34+
## Step 2 — Preflight
35+
36+
Confirm the project is Spec Kit-initialized (a `.specify/` directory exists) and that every `/speckit.*` command named in the resolved plan is available in this agent's command set. Report anything missing now — never mid-pipeline. If `--add constitution` or `--add checklist` was requested but that command isn't installed, report and stop.
37+
38+
## Step 3 — Execute each phase in order
39+
40+
For each phase in the resolved plan, invoke its `/speckit.*` command (the `command` field from the resolver output). After each phase:
41+
42+
- **Verify the artifact.** Confirm the expected file was written (`spec.md`, `plan.md`, `tasks.md`, etc.) before proceeding. A phase reporting success is not enough — check the artifact is on disk.
43+
- **Halt on failure.** If a phase fails and the failure is not something you can safely resolve, stop and name the phase and reason. Never proceed past a broken artifact.
44+
45+
Keep a short running ledger (which phases ran, which were skipped, outcome of each) so the run survives a context reset.
46+
47+
## Step 4 — The clarify gate
48+
49+
`clarify` is the single interactive checkpoint; everything after it runs unattended.
50+
51+
**Default (no `--yes`)** — run `/speckit.clarify`, present its questions to the human, and **end your turn to wait** for answers. This is the one human checkpoint.
52+
53+
**`--yes` set** — no human is present, so `--yes` does not mean "skip clarification", it means "answer it responsibly yourself":
54+
55+
1. Run `/speckit.clarify`'s question generation as normal, but don't present the questions to a human.
56+
2. Answer each question as the operator plausibly would, grounded strictly in the spec's own content, the project's constitution/conventions, and established repo patterns. Integrate each answer into the spec exactly as `/speckit.clarify` integrates a human's answer.
57+
3. Emit one line noting that clarify was answered unattended, not by a human, so the audit trail is honest.
58+
4. **If any question is too consequential to answer without a human** — insufficient grounding, security/scope/privacy stakes, or a materially shape-changing decision the spec leaves open — do **not** guess. Halt before `plan`, name the unresolved question and why. This is a correct outcome, not a failure: it means the run recognized it should not proceed unattended past this point.
59+
60+
## Step 5 — The analyze → resolve loop
61+
62+
After `/speckit.analyze` reports findings, fix each finding (edit the spec/plan/tasks as needed), then re-run `/speckit.analyze`. Repeat **up to 3 cycles**. If findings remain unresolved after the third cycle, halt and report them rather than implementing against a known-inconsistent spec.
63+
64+
## Step 6 — Unattended discipline (clarify-satisfied → implement)
65+
66+
From the moment clarify is satisfied through `implement`, run without acknowledgment chatter between phases, but:
67+
68+
- **Log every skip and every fallback.** Silent deviation from the plan is not allowed — if you skip or work around something, say so in the ledger.
69+
- **Halt on destructive or irreversible actions** during `implement` (deleting data, force-pushing, rewriting shared history) and ask, rather than proceeding blindly.
70+
- Any phase failure that isn't auto-resolvable, or is unsafe to continue past, halts **before** `implement`, naming the phase and reason.
71+
72+
## Hard stops
73+
74+
| Condition | Behavior |
75+
|---|---|
76+
| Empty feature description | Report missing input; do not start. |
77+
| Resolver returns non-zero | Report its message; run no phase. |
78+
| `.specify/` or a required `/speckit.*` command missing at preflight | Report; do not start. |
79+
| Expected artifact absent after a phase | Halt, name the phase; do not proceed. |
80+
| Analyze findings unresolved after 3 cycles | Halt; report the unresolved findings. |
81+
| A clarify question too consequential to answer unattended (`--yes`) | Halt before `plan`, name the question and why; never guess. |
82+
| Destructive/irreversible action during implement | Halt and ask. |
83+
84+
## Notes
85+
86+
- **Agent-neutral.** This command drives only stock `/speckit.*` commands and ships no dependency on any specific AI agent, model, or vendor tooling. In an agent that renders Spec Kit commands as skills, the same phases appear as `speckit-plan`, `speckit-tasks`, etc. — invoke whichever form your agent exposes.
87+
- **Preview first.** Run `/speckit.pipeline.preview` with the same flags to see the resolved plan before committing to a full run.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Pipeline extension configuration.
2+
# Copy to `pipeline-config.yml` in your project's Spec Kit config location and edit.
3+
# Every key is optional; the values below are the built-in defaults.
4+
5+
pipeline:
6+
# Default phases to skip on every `/speckit.pipeline.run` unless overridden by --skip.
7+
# Cannot include the required phases `specify` or `implement`.
8+
default_skip: []
9+
10+
# Default insertable phases to add on every run unless overridden by --add.
11+
# Valid values: constitution, checklist.
12+
default_add: []
13+
14+
# Maximum analyze → fix → re-analyze cycles before the run halts and reports
15+
# remaining findings instead of implementing against an inconsistent spec.
16+
analyze_max_cycles: 3
17+
18+
# When true, `--yes` runs answer the clarify gate unattended (grounded in the
19+
# spec/repo) instead of pausing for a human. A question too consequential to
20+
# answer without a human still halts the run before `plan`.
21+
answer_clarify_unattended: false

extensions/pipeline/extension.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
schema_version: "1.0"
2+
3+
extension:
4+
id: "pipeline"
5+
name: "Pipeline"
6+
version: "1.0.0"
7+
description: "Chain the Spec Kit phases (specify → clarify → plan → tasks → analyze → implement) into one guided, single-invocation pipeline with a deterministic phase resolver and one interactive clarify gate."
8+
author: "Dominik Mattioli"
9+
repository: "https://github.com/domattioli/spec-kit-pipeline"
10+
license: "MIT"
11+
homepage: "https://github.com/domattioli/spec-kit-pipeline"
12+
13+
requires:
14+
speckit_version: ">=0.2.0"
15+
16+
provides:
17+
commands:
18+
- name: "speckit.pipeline.run"
19+
file: "commands/run.md"
20+
description: "Run the full spec → implement pipeline from one feature description, with a single interactive clarify checkpoint."
21+
- name: "speckit.pipeline.preview"
22+
file: "commands/preview.md"
23+
description: "Print the resolved phase plan for the given --skip/--add flags without running anything (dry run)."
24+
25+
config:
26+
- name: "pipeline-config.yml"
27+
template: "config-template.yml"
28+
description: "Pipeline defaults — auto-resolve cap for analyze findings, default skip/add sets."
29+
required: false
30+
31+
tags:
32+
- "workflow"
33+
- "orchestration"
34+
- "pipeline"
35+
- "automation"
36+
- "sdd"
37+
- "spec-driven-development"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
# Thin POSIX wrapper: resolve the Spec Kit pipeline phase plan.
3+
# Delegates to the pure-Python resolver so there is one source of truth.
4+
# Usage: resolve-phases.sh [--skip a,b] [--add x,y] [--json|--list]
5+
set -euo pipefail
6+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7+
exec python3 "${HERE}/../resolve_phases.py" "$@"

0 commit comments

Comments
 (0)