SpecOps CLI
Read this in: English | Português (BR)
SpecOps turns GitHub Spec Kit's spec-driven workflow into an enforced, auditable process. It layers an agent-guided atomic development methodology on top of any Speckit repository — a physical state ledger, typed evidence with machine collection, and token-optimized review — without replacing or forking a single Speckit file.
Speckit gives your agents great artifacts (spec → plan → tasks → implement). SpecOps makes sure they actually follow them: state is on disk and Git-verifiable, evidence is collected by tooling instead of claimed by the agent, and review rejects as cheaply as possible.
Why SpecOps?
Spec-driven development with AI agents has three recurring failure modes. SpecOps addresses each one:
| Problem | Without SpecOps | With SpecOps |
|---|---|---|
| Agents hallucinate progress | "Done ✅" with no proof | Every task closes with typed evidence; --auto attaches commit hashes and diffs at the commit boundary, and the review gate verifies the tests |
| State lives in the chat | Lost on context reset; not auditable | State is a physical status.yaml ledger, Git-verifiable and recovery-safe |
| Reviews are slow and expensive | Agent reads the whole repo | /specops-review rejects cheapest-first (reconcile → gate profiles (lint/test by default) → working tree/effective diff → drift) before reading any code |
What it adds to Speckit
- 📒 Physical state ledger (Repo-as-State). A versioned, structured
status.yamltracks phase, tasks, evidence, and review cycles. Mutated only throughspecopscommands — never hand-edited, never held in agent memory. State changes are atomic and interruption-safe, guarded by optimistic concurrency (a monotonicrevision) and a workspace-identity check (feature / branch / baseline); older ledgers migrate losslessly with a backup. - 🔬 Automated evidence collection.
complete-task --autoharvests commits and diffs and records them as typed evidence — mechanically, never agent-narrated. Test verification runs once at the review gate (specops preflight), not per task, so the implement loop stays cheap. A task cannot reachDONE, and no change is approved, without proof. - 🔁 A phase state machine wired into the prompts.
specops initinjects directives into the specify, plan, tasks, and implement prompts so the ledger is created and phases advance automatically — the human never runs the bookkeeping by hand. - ✂️ Token-optimized surgical review. The installed
/specops-reviewcommand reviews only effective-diff files and stops at the first cheap rejection. - 📐 Empirical verification & gates.
specops consistencyandspecops reconcileare exit-code gates you can drop into CI or agent prompts. - ➕ Additive and reversible. Everything is delivered through marker-delimited blocks. Removing those blocks restores the affected Speckit files byte-for-byte.
Install
pip install speckit-specops
Installs the specops command. Requires Python ≥ 3.10 and Git ≥ 2.30. No
network I/O after install.
Quick Start
# In a Speckit-initialized repository:
specops init # inject directives, install /specops-review, create specops.json
That's it. From here you drive Speckit as usual (/speckit.specify,
/speckit.plan, /speckit.tasks, /speckit.implement) and the injected
directives take care of the ledger and phase transitions. Check state anytime:
specops status show
How it works
SpecOps rides the Speckit lifecycle. Once specops init has run, the injected
directives drive the ledger at each stage seam:
| Speckit stage | What SpecOps does |
|---|---|
| specify | Marks the repo as SpecOps-managed (informational; no ledger yet) |
| clarify / checklist / analyze | Records the run decision; a skip is derived — never forced — at the next stage (record-step, buffered before the ledger exists) |
| plan | Enforces empirical path verification and the consistency gate |
| tasks | Creates the ledger (status init-spec, draining buffered decisions), advances the phase to TASKS, and requires [SC-xxx] coverage tags on every task |
| implement | Opens IMPLEMENT, resolves the context map's minimal read set and seeds reads with it (guidance, never a gate nor a ceiling on discovery; no-op without a map), runs the evidence-backed ledger loop, then opens REVIEW |
| converge | Fails closed before an unrecordable task-list mutation (sync-tasks --check), then records appended tasks with coverage tags (sync-tasks) |
| taskstoissues | Nothing — verified read-only for ledger state, protected by a regression test |
| review | /specops-review validates the diff and records APPROVED / REJECTED |
The phase machine is SPECIFY → PLAN → TASKS → IMPLEMENT → REVIEW → DONE.
If SpecOps is not installed, the Speckit prompts still work standalone — the
directives degrade to no-ops.
Commands at a glance
| Command | What it does |
|---|---|
specops init |
Prepare a Speckit repo: inject directives, install /specops-review, create specops.json |
specops extension … |
Native Spec Kit extension lifecycle, plus the specops and specops-lite workflows |
specops status … |
Drive the ledger: show, init-spec, start-task, complete-task, amend-task, transition-phase, record-step, sync-tasks, migrate, rebaseline |
specops feature … |
Recovery operations on the feature itself: use (repoint the active feature), rename (renumber without losing the ledger) |
specops preflight |
Deterministic review gate, cheapest-first — CI-safe (formerly specops review) |
specops reconcile |
Read-only gate: every recorded commit reachable, every DONE task evidenced |
specops consistency |
Read-only gate: SC coverage tags + plan path action suffixes |
specops doctor |
Read-only health diagnostic across every SpecOps surface |
specops report |
Compact, stable machine surface for the active feature's status |
specops context … |
Context map: ownership, phase read sets, impact, staleness |
specops trace … |
End-to-end traceability; classify and acknowledge effective-diff drift |
specops gate … |
Gate-profile suite and structured-evidence inspection |
specops handoff … |
Structured corrective handoffs; record each review round's reviewed scope; import external findings (JSON/SARIF) |
specops lane … |
Lightweight lane for small, reversible changes |
The full reference — flags, exit codes, JSON contracts, examples, and the review workflow — lives in docs/commands.md.
Stability & contract freeze
Building automation on SpecOps? docs/stability.md is the contract
freeze for 1.0: it classifies every adopter-facing surface — specops.json, status.yaml,
lane.yaml, gate-profile files, the --json output envelope, exit codes, the findings-input
contract, the context-map file, and SARIF output — as frozen, and states the
additive-vs-breaking rule and the post-1.0 versioning/migration obligations for each. Every
--json output carries an output_version so you can detect envelope changes.
Recovery operations
Two states an interrupted session leaves behind used to have no legal move, so the only way forward was to hand-edit the very files the ledger exists to make trustworthy. Both are now commands that record the correction rather than hiding it:
- A task closed with wrong evidence.
specops status amend-task <id> --evidence … --reason …appends the correction: it becomes the task's current evidence, the prior record is retained as superseded history, and the task is not reopened. An amended task is more informative than a silently-correct one — which is what stops amendment from being a way to launder a bad close. - The active feature pointer.
specops feature use <dir>repoints it explicitly (andstatus init-specrecords the feature it initializes), whilespecops feature rename <old> <new>carries a renumbering across directory, ledger identity, branch reference and pointer with every recorded fact intact.
SpecOps resolves the active feature with the same precedence Spec Kit uses —
SPECIFY_FEATURE_DIRECTORY before .specify/feature.json — so the two tools can
never answer about different features from the same repository state.
How SpecOps behaves: a paved road you can leave — on the record
SpecOps is neither a rigid gate that blocks you nor a suggestion you can ignore. It presents a correct path and lets you deviate — as long as the deviation is recorded. What it blocks is silent deviation, not deviation itself:
- A path you changed that the plan didn't predict isn't rejected — you
acknowledge it with a reason (
specops trace acknowledge). - A review finding that turns out to be a false positive isn't a dead-end — you
dismiss it with a reason (
specops handoff finding dismiss). - A gate that was skipped is recorded as a finding, never silently passed.
SpecOps records the deviation and its reason; it does not judge whether the reason is good — that is the team's call, not the tool's. (A small core of safety-critical gates — persisted-schema changes, secrets, public-contract breaks, destructive actions — is not pierceable; there SpecOps halts and asks a human.)
Configuration — specops.json
| Key | Purpose | Default |
|---|---|---|
test_command |
Command run by the review gate (specops preflight) |
pytest |
lint_command |
Lint gate run by specops preflight (empty = skipped) |
"" |
skills_dir |
Directory the review prompt loads skills from | .specify/skills |
review_round_cap |
Max semantic review rounds before SpecOps halts and asks a human | 10 |
Unknown keys are preserved on re-init.
Review round integrity
Each review round records the code scope it covered — an anchor round the full
baseline..HEAD, a corrective round the change since the last review — derived from
git, never hand-picked (specops handoff record-scope). Approval fails closed unless the
recorded scopes together cover the whole feature, so no APPROVED can rest on a partial
hunt. If the review keeps cycling past review_round_cap, SpecOps halts and asks a human
rather than looping unbounded (raise the cap, approve, or rebaseline to resume). Ledgers
that predate this behavior degrade to the prior approval path.
Rounds accumulate coverage; they do not narrow it. A corrective round's delta is
where the defects are most likely to be, but it is a priority, not a boundary:
record-scope also prints the full baseline..HEAD set with the remainder marked
not yet re-verified this round, so a defect an earlier round missed cannot be
hidden from later rounds by the tool. If your context budget will not stretch to the
whole set, that is a legitimate call — the directive asks you to record it rather than
letting the tool make it silently. The command also names any product path that no
recorded round has ever reached, and approval fails closed while that set is non-empty.
Coverage is derived from commit ranges only, so a round is credited only with what can
still be verified: if a rebase or squash orphaned a recorded review HEAD, one
specops handoff record-scope on the open round re-anchors over baseline..HEAD — a
rewrite costs a re-scope, never a re-review.
Language policy
All SpecOps operational output (CLI messages, injected assets) is in English.
Your prose (spec.md, plan.md, task descriptions) may be in any language —
SpecOps parses only structural tokens (SC-\d+, T\d+, action suffixes), never
content.
Supported Speckit layouts
SpecOps resolves prompt targets at runtime from
.specify/integrations/<agent>.manifest.json. Any Speckit integration with a
recorded manifest is supported; unknown layouts fail closed. Tested with
Speckit ≥ 0.12 (Claude skills mode, separator -).
Uninstall
Remove the appended block from each prompt file, then delete specops.json and
the installed review command. No other files are written; the restore is
byte-identical.
Contributing
Contributions are welcome — see CONTRIBUTING.md for dev setup,
the quality gates, and project principles. SpecOps is at 0.x; the CLI surface
and ledger format may still change before 1.0 (see CHANGELOG.md).
License
MIT © Paulo Segundo
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file speckit_specops-0.13.0.tar.gz.
File metadata
- Download URL: speckit_specops-0.13.0.tar.gz
- Upload date:
- Size: 179.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
567b4ef9f6d8c8ba053826819e5ee7bf998465b44f998727eefd966c33e3e293
|
|
| MD5 |
0085e395424facff896b3a9306a5396c
|
|
| BLAKE2b-256 |
9eeea401c9511b7fe4ff8136c72e55b5d2d0702df285fe278cfec1d7ad8b0271
|
Provenance
The following attestation bundles were made for speckit_specops-0.13.0.tar.gz:
Publisher:
release.yml on paulo2nd/specops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
speckit_specops-0.13.0.tar.gz -
Subject digest:
567b4ef9f6d8c8ba053826819e5ee7bf998465b44f998727eefd966c33e3e293 - Sigstore transparency entry: 2689920742
- Sigstore integration time:
-
Permalink:
paulo2nd/specops@c4f0cc1b6612ec7f5d026bd213baefe07302fbec -
Branch / Tag:
refs/tags/v0.13.0 - Owner: https://github.com/paulo2nd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c4f0cc1b6612ec7f5d026bd213baefe07302fbec -
Trigger Event:
release
-
Statement type:
File details
Details for the file speckit_specops-0.13.0-py3-none-any.whl.
File metadata
- Download URL: speckit_specops-0.13.0-py3-none-any.whl
- Upload date:
- Size: 209.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26d49f4cb72b2ed5e788ffba3659390f45f5e75edd5ea9065135dd09c81a073a
|
|
| MD5 |
b33bb0e5300620650d64bda22ba2113d
|
|
| BLAKE2b-256 |
ca4bfeb0693edfb83ca6f8c098df8fd0b223c4b24c49d7552284c4c23762ab6b
|
Provenance
The following attestation bundles were made for speckit_specops-0.13.0-py3-none-any.whl:
Publisher:
release.yml on paulo2nd/specops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
speckit_specops-0.13.0-py3-none-any.whl -
Subject digest:
26d49f4cb72b2ed5e788ffba3659390f45f5e75edd5ea9065135dd09c81a073a - Sigstore transparency entry: 2689920897
- Sigstore integration time:
-
Permalink:
paulo2nd/specops@c4f0cc1b6612ec7f5d026bd213baefe07302fbec -
Branch / Tag:
refs/tags/v0.13.0 - Owner: https://github.com/paulo2nd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c4f0cc1b6612ec7f5d026bd213baefe07302fbec -
Trigger Event:
release
-
Statement type: