Metadata-Version: 2.5
Name: speckit-specops
Version: 0.14.1
Summary: A Spec-Driven Development (SDD) process enforcement CLI extending Speckit
Project-URL: Homepage, https://github.com/paulo2nd/specops
Project-URL: Changelog, https://github.com/paulo2nd/specops/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/paulo2nd/specops/issues
Author-email: Paulo Segundo <paulosegundo@gmail.com>
License: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Requires-Dist: packaging>=21.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: typer>=0.9.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest-xdist>=3.5; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
Description-Content-Type: text/markdown

# SpecOps CLI

[![CI](https://github.com/paulo2nd/specops/actions/workflows/ci.yml/badge.svg)](https://github.com/paulo2nd/specops/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/speckit-specops.svg)](https://pypi.org/project/speckit-specops/)
[![Python](https://img.shields.io/pypi/pyversions/speckit-specops.svg)](https://pypi.org/project/speckit-specops/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

Read this in: **English** | [Português (BR)](README.pt-br.md)

**SpecOps turns [GitHub Spec Kit](https://github.com/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.yaml` tracks phase, tasks, evidence, and review cycles. Mutated only
  through `specops` commands — never hand-edited, never held in agent memory.
  State changes are atomic and interruption-safe, guarded by optimistic
  concurrency (a monotonic `revision`) and a workspace-identity check
  (feature / branch / baseline); older ledgers migrate losslessly with a backup.
- **🔬 Automated evidence collection.** `complete-task --auto` harvests 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 reach `DONE`, and no change is approved, without proof.
- **🔁 A phase state machine wired into the prompts.** `specops init` injects
  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-review`
  command reviews only effective-diff files and stops at the first cheap rejection.
- **📐 Empirical verification & gates.** `specops consistency` and
  `specops reconcile` are 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

```bash
pip install speckit-specops
```

Installs the `specops` command. Requires Python ≥ 3.10 and Git ≥ 2.30. No
network I/O after install.

## Quick Start

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

```bash
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](docs/commands.md)**.

### Stability & contract freeze

Building automation on SpecOps? **[docs/stability.md](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
  (and `status init-spec` records the feature it initializes), while `specops 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` |
| `native_review` | Optional, per integration: `{"<integration>": {"command": "…" \| null, "effort": "…"}}` — overrides the native code reviewer `/specops-review` invokes. Applied on `specops extension update` | *(absent — built-in map)* |

Unknown keys are preserved on re-init.

### Native code review

`/specops-review` invokes the agent's **native code reviewer** where the integration
has one the agent can run itself against the round's diff — today Claude Code's
`/code-review`, through the Skill tool, at effort `high`. The review command is
rendered per installed integration, so each copy names its own reviewer, or states
plainly that there is none and the review is manual. When the native reviewer does not
run, the reviewer records an advisory `native-review-not-run` finding instead of
falling back silently, and the next corrective round runs it over that round's range
too. Use `native_review` in `specops.json` to change the effort, name a
project-specific reviewer, or turn it off for an integration.

> **Run `/specops-review` from the main session.** The native reviewer is only
> reliable there. A delegated subagent may lack the Skill tool, and even with it
> `/code-review` runs in the background and reports after the subagent has returned,
> so its findings miss the verdict. A subagent records `native-review-not-run` instead
> of invoking it. The native reviewer complements the agent's own pass and does not
> replace it: it follows its own recipe and may skip tests and Markdown (spec, plan,
> tasks).

### 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](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](CHANGELOG.md)).

## License

[MIT](LICENSE) © Paulo Segundo
