Skip to main content

speckit-gate

Harness-agnostic workflow gates for spec-kit projects.

Prevents out-of-order spec-kit command invocations by evaluating prerequisite artefacts at hook time. Supports hard-deny enforcement on Claude Code and Codex; advisory-only enforcement on all other spec-kit harnesses.

Install

Option 1 — uvx (one-shot, no install required)

# Scan and initialise gates in the current project
uvx speckit-gate init --defaults
uvx speckit-gate compile

# Install Claude Code hooks
uvx speckit-gate install --harness claude
# From within Claude Code, or via the CLI:
claude plugin install srobroek/speckit-gate

The .claude-plugin/plugin.json in adapters/claude/ wires UserPromptExpansion, PreToolUse:Skill, and PreToolUse:Agent hooks.

Option 3 — spec-kit bundle (all harnesses, advisory enforcement)

# Add the community bundle catalog and install
specify bundle catalog add https://github.com/srobroek/speckit-gate/releases/latest/download/bundles.json --id speckit-gate
specify bundle install speckit-gate

See Bundle adapter rationale below.

Option 4 — APM external source

# In apm.yml:
dependencies:
  apm:
    - repo: srobroek/speckit-gate
      ref: ">=0.1.0"
apm install

Quick start

# gates.yaml — 10-line example
config:
  prefix: speckit.
  feature_root: specs
  resolve: [git-branch, newest-dir]

gates:
  plan:
    requires: [specify]
    produces: [specs/<feat>/plan.md]
    context: Decomposes spec into implementation plan.
  tasks:
    requires: [plan]
    produces: [specs/<feat>/tasks.md]
    context: Decomposes plan into discrete tasks.

Compile to nodes.json:

speckit-gate compile
# → Compiled 2 gates → .specify/gates/nodes.json

Agent-driven interview

Use the speckit-gate skill (in skills/speckit-gate/SKILL.md) with Claude Code or any skill-capable harness. The skill:

  1. Scans the project for spec-kit commands.
  2. Shows a full proposal table (known prerequisites pre-filled).
  3. Asks ONE question per unknown command.
  4. Writes gates.yaml via init --answers and runs compile.

For no-agent setup run speckit-gate init --interactive or speckit-gate init --defaults.

Harness enforcement matrix

A gate is only as strong as its blindest channel, and every harness differs by invocation channel: what happens when the user types a command vs. when the model (a workflow engine, a subagent) evokes one mid-run. A gate that covers only the user channel is silently bypassed by agent-driven runs — so the matrix is per-channel. All deny rows below are verified against harness source (mid-2026); adapters currently ship for Claude Code and Codex.

Harness User invocation Model/agent evocation Adapter
Claude Code deny — UserPromptExpansion, sees command name deny — PreToolUse: Skill|Agent shipped
Qwen Code deny — UserPromptExpansion, sees command_name (+ UserPromptSubmit post-expansion) deny — PreToolUse on skill/agent tools (full prompt); model-invoked commands re-fire UserPromptExpansion. SubagentStart cannot block planned
Codex CLI deny — UserPromptSubmit (raw human text; text-match, no command structure; requires [features] hooks = true) none — skills inject as context with no event; SubagentStart is metadata-only (continue:false at best). Artifact gates are the backstop shipped
Gemini CLI deny — BeforeAgent (expanded template text only — no command name, no slash-origin marker; content-match required) n/a — model cannot invoke .toml commands by design planned
Mistral Vibe none — slash/skill input expands in the UI layer, invisible to hooks deny — before_tool on the skill tool (sees skill name; flag: enable_experimental_hooks). Note: skill loads bypass Vibe's user-approval prompt, so this hook is the only programmatic gate planned
GitHub Copilot hooks exist; deny semantics unverified unverified —
Cursor, Zed, Cline, Goose, Devin, Trae, Lingma, Kimi, ZCode, Firebender, Junie, Auggie, + ~14 more static context only — no hook system static context only spec-kit bundle (advisory text)

Where a channel shows none/static, enforcement falls back to artifact gates: a downstream gated command hard-requires the report file the skipped step should have produced, so out-of-order runs still fail at the next enforceable point.

deny = the hook emits permissionDecision: deny or decision: block, preventing the tool from running.

advisory = the gate injects prerequisite context into the model's context window (via spec-kit's before_* hook infrastructure) but does not block execution.

Bundle adapter rationale

spec-kit supports 36+ harnesses. Of these, only Claude Code and Codex expose a real hook system (PreToolUse / UserPromptExpansion / UserPromptSubmit) that can deny tool calls before they run. All other harnesses receive spec-kit's advisory prompt injection as their only integration path — there is no hook event to intercept.

The spec-kit bundle is therefore the only distribution path that reaches advisory harnesses. It ships an extension that registers /speckit.gate.init and emits prerequisite context before each spec-kit command via spec-kit's built-in before_* advisory hooks.

The bundle does not duplicate Claude Code or Codex enforcement — those harnesses should use the plugin or install --harness path for real deny gates.

CLI reference

Verb Description
scan Scan project for spec-kit commands
propose Show prerequisite proposal table
init Write gates.yaml (--defaults / --answers / --interactive)
compile Compile gates.yaml → .specify/gates/nodes.json
compile --check Drift check only; exit 1 if stale
install --harness Install hook adapters (claude/codex/speckit/all)
explain <cmd> Show prerequisites for a command
dry-run <cmd> Simulate a hook event
`dispatch pre post`

gates.yaml schema

config:
  prefix: speckit.          # command prefix; default "speckit."
  feature_root: specs       # feature artefact root; default "specs"
  resolve: [git-branch, newest-dir]
  messages:
    no_feature: "..."       # block reason when no feature resolved

gates:
  <command>:
    requires: [cmd-or-artefact, ...]
    produces: [artefact, ...]
    deprecated: true|false
    spawn_agent: true|false  # adds PreToolUse:Agent gate (Claude only)
    context: "..."           # advisory context injected into the model

compile derives edges by matching produces → requires and writes .specify/gates/nodes.json in the flat dispatcher format the hook reads.

Presets

Preset Description
presets/core.gates.yaml Spec-kit built-in commands only (analyze, checklist, clarify, constitution, converge, implement, plan, specify, tasks, taskstoissues). Safe to use on any spec-kit project.
presets/extensions.example.gates.yaml Example file showing how to gate community and custom extensions. Not an installable preset — copy individual entries into your gates.yaml.

Copy the core preset as your starting gates.yaml:

curl -sL https://raw.githubusercontent.com/srobroek/speckit-gate/main/presets/core.gates.yaml \
  > gates.yaml
speckit-gate compile

Extending for custom extensions

If your project uses community extensions (e.g. speckit.verify-tasks, speckit.agent-assign.*, speckit.refine.*), add gates for them on top of the core preset. See presets/extensions.example.gates.yaml for documented patterns covering:

  • requires-chain — sequencing a community command after a built-in artefact
  • spawn_agent — gating commands that spawn sub-agents via PreToolUse:Agent
  • deprecated — emitting an upgrade hint instead of a prerequisite block
  • produces-artefact — requiring a specific artefact path rather than a command name
# Copy entries you need from the example into your gates.yaml:
curl -sL https://raw.githubusercontent.com/srobroek/speckit-gate/main/presets/extensions.example.gates.yaml

Plain-python fallback

For exec-tax-sensitive environments (slow filesystem, EDR overhead) where uvx startup latency matters even with caching, use the installed console script directly:

pip install speckit-gate  # or uv pip install speckit-gate
# then in hooks.json:
# "command": "speckit-gate dispatch pre"

The dispatcher (dispatch.py) is stdlib-only with no import overhead. uvx caches after first run and is the default wiring; switch to the installed path only when profiling shows hook latency is a problem.

Development

uv sync --dev
uv run pytest
uv run speckit-gate --help

License

Apache-2.0

Metadata

Release files for speckit-gate 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for speckit-gate 0.2.2
File Size Uploaded
speckit_gate-0.2.2.tar.gz 55.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for speckit-gate 0.2.2
File Interpreter ABI Platform
speckit_gate-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 87.4 kB

Release files / speckit_gate-0.2.2.tar.gz

Download URL speckit_gate-0.2.2.tar.gz
Size 55.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f7d37b0c40200285fc05dfa520ac133b08ccdfdb269546607c7775bb986f02c5
BLAKE2b-256 checksum
How to use checksums
174cd4cfcde428fbd9db864bd82e71a050dbcb35c14800a642dd87e301bd1a8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.

Transparency log

Release files / speckit_gate-0.2.2-py3-none-any.whl

Download URL speckit_gate-0.2.2-py3-none-any.whl
Size 31.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0a0e55726952e0b53a060fa76dfc07ba372fa3650a0505a20b383e08abe1eeb
BLAKE2b-256 checksum
How to use checksums
b01e3ad4227479035a9f5f0220a349da06b90e41562cd884db96abd0f59f6345
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.2 This release

2 release files

0.2.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page