Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions extensions/pipeline/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
__pycache__/
*.pyc
.pytest_cache/
.DS_Store
21 changes: 21 additions & 0 deletions extensions/pipeline/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

All notable changes to the Pipeline extension are documented here. Format based on
[Keep a Changelog](https://keepachangelog.com/); this project adheres to Semantic Versioning.

## [1.0.0] - 2026-07-05

### Added

- Initial release.
- `speckit.pipeline.run` — chains `specify → clarify → plan → tasks → analyze → implement`
into one guided invocation with a single interactive clarify gate and an
analyze → fix → re-analyze loop (≤3 cycles) before implement.
- `speckit.pipeline.preview` — dry-run printer for the resolved phase plan.
- `--skip` / `--add` flags with a deterministic phase resolver (`scripts/resolve_phases.py`),
strict validation, and dedicated exit codes (10–14).
- Insertable phases: `constitution` (before specify), `checklist` (after tasks).
- `--yes` unattended mode: answers the clarify gate in-place, halting before `plan`
on a question too consequential to answer without a human.
- Bash + PowerShell wrappers over the Python resolver.
- Stdlib `unittest` suite covering default order, permutation invariance, and every exit code.
21 changes: 21 additions & 0 deletions extensions/pipeline/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Dominik Mattioli

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
98 changes: 98 additions & 0 deletions extensions/pipeline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Pipeline — a Spec Kit extension

Chain the [Spec Kit](https://github.com/github/spec-kit) phases into **one guided, single-invocation pipeline** instead of hand-running seven commands.

```
specify → clarify → plan → tasks → analyze → implement
```

`/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.

## Why

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).

## Commands

| Command | What it does |
|---|---|
| `speckit.pipeline.run` | Run the full pipeline from one feature description, with a single clarify checkpoint. |
| `speckit.pipeline.preview` | Print the resolved phase plan for the given flags without running anything (dry run). |

### Flags

- `--skip <csv>` — drop default phases (e.g. `--skip clarify,analyze`). `specify` and `implement` cannot be skipped.
- `--add <csv>` — insert optional phases: `constitution` (before specify), `checklist` (after tasks).
- `--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.

## Examples

```
# Full default run
/speckit.pipeline.run Add rate limiting to the public API

# See the plan first, then run a tailored pipeline
/speckit.pipeline.preview --add checklist --skip clarify
/speckit.pipeline.run --add checklist Add a healthcheck endpoint

# Unattended (CI / routine), clarify answered in-place, halts on a consequential question
/speckit.pipeline.run --yes Migrate config loading to env vars
```

## How the resolver works

`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:

| Exit | Meaning |
|---|---|
| 0 | resolved OK |
| 10 | unknown phase name |
| 11 | a phase is in both `--skip` and `--add` |
| 12 | `--add` names a non-insertable phase |
| 13 | `--skip` targets a required phase (`specify`/`implement`) |
| 14 | dependency break — a retained phase's dependency was skipped |

`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.

## Agent-neutral

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.

## Layout

```
pipeline/
├── extension.yml # manifest
├── commands/
│ ├── run.md # the orchestrator command
│ └── preview.md # dry-run phase-plan printer
├── scripts/
│ ├── phase_registry.py # deterministic resolver core (pure, no I/O)
│ ├── resolve_phases.py # CLI over the resolver (exit codes 10–14)
│ ├── bash/resolve-phases.sh
│ └── powershell/resolve-phases.ps1
├── config-template.yml # optional per-project defaults
├── tests/test_phase_registry.py # stdlib unittest — determinism + exit codes
├── README.md
├── CHANGELOG.md
└── LICENSE
```

## Install

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.

## Tests

```
cd pipeline
python3 -m unittest discover -s tests -p 'test_*.py'
```

## License

MIT — see [LICENSE](LICENSE).

## Provenance

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.
29 changes: 29 additions & 0 deletions extensions/pipeline/commands/preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
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."
scripts:
sh: scripts/bash/resolve-phases.sh
ps: scripts/powershell/resolve-phases.ps1
---

# Pipeline: preview

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.

## Input

`$ARGUMENTS` — optional flags only (no feature description needed):

- `--skip <csv>` — default phases to drop.
- `--add <csv>` — insertable phases to add (`constitution`, `checklist`).

## Behavior

Run the resolver and print its output:

```
{SCRIPT} --skip "<skip csv>" --add "<add csv>"
```

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.

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.
87 changes: 87 additions & 0 deletions extensions/pipeline/commands/run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
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."
scripts:
sh: scripts/bash/resolve-phases.sh
ps: scripts/powershell/resolve-phases.ps1
---

# Pipeline: run

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.

## Input

`$ARGUMENTS` — the feature description, optionally followed by flags:

- `--skip <csv>` — drop default phases (e.g. `--skip clarify,analyze`). Cannot drop `specify` or `implement`.
- `--add <csv>` — insert optional phases: `constitution` (before specify), `checklist` (after tasks).
- `--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.

If the feature description is empty, report the missing input and stop — do not start.

## Step 1 — Resolve the phase plan (deterministic)

Run the resolver once and branch on its exit code:

```
{SCRIPT} --skip "<skip csv>" --add "<add csv>" --json
```

(`{SCRIPT}` is this command's configured `scripts.sh` / `scripts.ps`.)

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.

## Step 2 — Preflight

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.

## Step 3 — Execute each phase in order

For each phase in the resolved plan, invoke its `/speckit.*` command (the `command` field from the resolver output). After each phase:

- **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.
- **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.

Keep a short running ledger (which phases ran, which were skipped, outcome of each) so the run survives a context reset.

## Step 4 — The clarify gate

`clarify` is the single interactive checkpoint; everything after it runs unattended.

**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.

**`--yes` set** — no human is present, so `--yes` does not mean "skip clarification", it means "answer it responsibly yourself":

1. Run `/speckit.clarify`'s question generation as normal, but don't present the questions to a human.
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.
3. Emit one line noting that clarify was answered unattended, not by a human, so the audit trail is honest.
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.

## Step 5 — The analyze → resolve loop

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.

## Step 6 — Unattended discipline (clarify-satisfied → implement)

From the moment clarify is satisfied through `implement`, run without acknowledgment chatter between phases, but:

- **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.
- **Halt on destructive or irreversible actions** during `implement` (deleting data, force-pushing, rewriting shared history) and ask, rather than proceeding blindly.
- Any phase failure that isn't auto-resolvable, or is unsafe to continue past, halts **before** `implement`, naming the phase and reason.

## Hard stops

| Condition | Behavior |
|---|---|
| Empty feature description | Report missing input; do not start. |
| Resolver returns non-zero | Report its message; run no phase. |
| `.specify/` or a required `/speckit.*` command missing at preflight | Report; do not start. |
| Expected artifact absent after a phase | Halt, name the phase; do not proceed. |
| Analyze findings unresolved after 3 cycles | Halt; report the unresolved findings. |
| A clarify question too consequential to answer unattended (`--yes`) | Halt before `plan`, name the question and why; never guess. |
| Destructive/irreversible action during implement | Halt and ask. |

## Notes

- **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.
- **Preview first.** Run `/speckit.pipeline.preview` with the same flags to see the resolved plan before committing to a full run.
21 changes: 21 additions & 0 deletions extensions/pipeline/config-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Pipeline extension configuration.
# Copy to `pipeline-config.yml` in your project's Spec Kit config location and edit.
# Every key is optional; the values below are the built-in defaults.

pipeline:
# Default phases to skip on every `/speckit.pipeline.run` unless overridden by --skip.
# Cannot include the required phases `specify` or `implement`.
default_skip: []

# Default insertable phases to add on every run unless overridden by --add.
# Valid values: constitution, checklist.
default_add: []

# Maximum analyze → fix → re-analyze cycles before the run halts and reports
# remaining findings instead of implementing against an inconsistent spec.
analyze_max_cycles: 3

# When true, `--yes` runs answer the clarify gate unattended (grounded in the
# spec/repo) instead of pausing for a human. A question too consequential to
# answer without a human still halts the run before `plan`.
answer_clarify_unattended: false
37 changes: 37 additions & 0 deletions extensions/pipeline/extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
schema_version: "1.0"

extension:
id: "pipeline"
name: "Pipeline"
version: "1.0.0"
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."
author: "Dominik Mattioli"
repository: "https://github.com/domattioli/spec-kit-pipeline"
license: "MIT"
homepage: "https://github.com/domattioli/spec-kit-pipeline"

requires:
speckit_version: ">=0.2.0"

provides:
commands:
- name: "speckit.pipeline.run"
file: "commands/run.md"
description: "Run the full spec → implement pipeline from one feature description, with a single interactive clarify checkpoint."
- name: "speckit.pipeline.preview"
file: "commands/preview.md"
description: "Print the resolved phase plan for the given --skip/--add flags without running anything (dry run)."

config:
- name: "pipeline-config.yml"
template: "config-template.yml"
description: "Pipeline defaults — auto-resolve cap for analyze findings, default skip/add sets."
required: false

tags:
- "workflow"
- "orchestration"
- "pipeline"
- "automation"
- "sdd"
- "spec-driven-development"
7 changes: 7 additions & 0 deletions extensions/pipeline/scripts/bash/resolve-phases.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Thin POSIX wrapper: resolve the Spec Kit pipeline phase plan.
# Delegates to the pure-Python resolver so there is one source of truth.
# Usage: resolve-phases.sh [--skip a,b] [--add x,y] [--json|--list]
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
exec python3 "${HERE}/../resolve_phases.py" "$@"
Loading