mech.app

The mech.app newsletter

Agentic AI, minus the noise.

Get practical field notes on AI agents, automation, developer tools and security delivered to your inbox.

No spam. Unsubscribe anytime.

Dev Tools

Spec Kit: Executable Specifications for AI Coding Agents

GitHub's open-source toolkit turns specifications into executable source of truth, coordinating agent-generated code through CLI presets and bundles.

Source: github.com
Spec Kit: Executable Specifications for AI Coding Agents

Spec-driven development inverts the traditional workflow. Instead of treating specifications as throwaway scaffolding, the spec becomes the executable source of truth. AI agents generate working implementations directly from these specs, and the Specify CLI coordinates the handoff between human-written specifications and agent-generated code.

GitHub’s Spec Kit provides the infrastructure layer for this pattern: a CLI, preset system, role-based bundles, and extension hooks. It supports any AI coding agent (Copilot, Cursor, Aider, or custom tooling) and aims to make specifications executable rather than just descriptive.

The project has 129K+ stars and ranks #5 on GitHub’s Python trending list. It’s positioned as organizational infrastructure, not a solo developer tool.

How Spec Kit Coordinates Spec and Code

The Specify CLI acts as the orchestration boundary between human specifications and agent-generated implementations. Here’s the flow:

  1. Spec authoring: Developers write specifications in Markdown or structured formats using presets (templates for common patterns like API endpoints, data models, or UI components).
  2. Agent invocation: The CLI passes the spec to the configured AI coding agent via a standardized interface.
  3. Code generation: The agent produces implementation files, tests, and documentation based on the spec.
  4. State reconciliation: The CLI tracks which specs map to which generated artifacts, storing metadata in a .spec-kit/ directory.
  5. Version control: Both specs and generated code live in the same repository, but the spec is the canonical reference for diffs and reviews.

The key challenge is preventing state drift when specs change. Spec Kit handles this by:

  • Storing a hash of the spec content alongside generated file paths.
  • Flagging mismatches when the spec changes but generated code hasn’t been regenerated.
  • Providing a specify sync command to re-run agents on outdated implementations.

This avoids merge conflicts by treating the spec as the single source of truth. If two developers change the same spec, the conflict surfaces in the spec file (human-readable Markdown), not in generated code.

Extension and Preset Architecture

Spec Kit’s “endlessly extensible” claim rests on three composable layers:

LayerPurposeExample
PresetsReusable spec templates for common patternsAPI endpoint spec, database migration spec, React component spec
ExtensionsCustom CLI commands or agent integrationsspecify validate-schema, specify deploy-preview
BundlesRole-based collections of presets and extensionsFrontend bundle (UI presets + Storybook extension), Backend bundle (API + DB presets)

Presets are Jinja2 templates stored in .spec-kit/presets/. When you run specify new api-endpoint, the CLI renders the template with user-provided variables (endpoint path, HTTP method, response schema).

Extensions are Python modules that register new subcommands via entry points. An extension can:

  • Add validation logic (e.g., check that all API specs include rate limit definitions).
  • Integrate with external tools (e.g., push generated OpenAPI specs to a schema registry).
  • Customize agent behavior (e.g., pass additional context files to the agent based on spec metadata).

Bundles package presets and extensions together. A “backend engineer” bundle might include:

  • Presets for REST APIs, GraphQL resolvers, and database schemas.
  • Extensions for running integration tests and deploying to staging.
  • Configuration defaults (preferred agent, output directory structure).

Bundles are distributed as Python packages or Git repositories. Teams can fork the official bundles and add organization-specific presets (e.g., internal service templates).

Version Control for Specifications

When the spec becomes the source of truth, version control semantics shift:

  • Diffs: Code reviews focus on spec changes. Generated code diffs are informational but not the primary review surface.
  • Blame: git blame on a generated file points to the spec commit, not the agent invocation.
  • Rollback: Reverting a spec automatically invalidates the generated code. The next specify sync regenerates from the reverted spec.

Spec Kit stores metadata in .spec-kit/state.json:

{
  "specs": {
    "specs/api/user-endpoint.md": {
      "hash": "a3f2b1c9...",
      "generated": [
        "src/api/user.py",
        "tests/api/test_user.py"
      ],
      "agent": "copilot",
      "timestamp": "2026-08-15T14:32:10Z"
    }
  }
}

This file is committed alongside code. When a spec changes, the CLI detects the hash mismatch and marks the generated files as stale. Developers can:

  • Run specify sync to regenerate immediately.
  • Commit the spec change and let CI regenerate (useful for batching updates).
  • Manually edit generated code and run specify adopt to update the hash (escape hatch for one-off tweaks).

The adopt command is the safety valve. If an agent generates incorrect code and a developer fixes it manually, adopt updates the state file to reflect the manual edit. Future syncs won’t overwrite the fix unless the spec changes again.

Agent Integration Surface

Spec Kit doesn’t implement agents. It provides a standardized interface for invoking them:

# Extension example: custom agent integration
from spec_kit.agents import AgentBase

class CustomAgent(AgentBase):
    def generate(self, spec_path, output_dir, context):
        # Read spec
        spec = self.read_spec(spec_path)
        
        # Call your agent (API, local model, etc.)
        code = your_agent_api.generate(
            prompt=spec.content,
            context_files=context.get("related_specs", []),
            constraints=spec.metadata.get("constraints", {})
        )
        
        # Write output
        self.write_files(output_dir, code.files)
        
        return {
            "generated": code.file_paths,
            "metadata": code.metadata
        }

The CLI calls generate() for each spec. The agent receives:

  • Spec content: Markdown or structured data.
  • Context: Related specs, existing code, configuration.
  • Constraints: Type hints, style rules, security policies.

Agents return file paths and metadata. The CLI updates state and handles version control.

Built-in integrations exist for GitHub Copilot, Cursor, and Aider. Custom agents plug in via the extension system.

Failure Modes and Observability

Spec-driven workflows introduce new failure surfaces:

Failure ModeSymptomMitigation
Spec ambiguityAgent generates incorrect codePreset validation rules, spec linting
State driftGenerated code diverges from specspecify sync in CI, pre-commit hooks
Agent non-determinismSame spec produces different code on re-runPin agent versions, use temperature=0 for LLMs
Circular dependenciesSpec A references spec B, which references spec ADependency graph validation in CLI

Observability hooks:

  • Telemetry: CLI emits events (spec created, agent invoked, sync completed) to stdout in JSON format. Pipe to your logging system.
  • Dry-run mode: specify sync --dry-run shows what would be regenerated without modifying files.
  • Diff preview: specify diff <spec> shows the delta between current generated code and what a fresh agent run would produce.

The CLI also supports a --trace flag that logs the full agent prompt, response, and file writes. Useful for debugging why an agent produced unexpected output.

Deployment Shape

Spec Kit runs in three contexts:

  1. Local development: Developers run specify new and specify sync on their machines.
  2. CI/CD: Pipelines run specify validate to check for stale generated code and specify sync to regenerate on spec changes.
  3. Organizational registry: Teams host a private bundle repository with custom presets and extensions. Developers install bundles via specify bundle install <org-bundle>.

For CI, the recommended pattern is:

# .github/workflows/spec-kit.yml
on:
  pull_request:
    paths:
      - 'specs/**'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: pip install spec-kit
      - run: specify validate
      - run: specify sync --check
      # Fails if generated code is stale

The --check flag makes sync exit non-zero if regeneration would change files. This enforces that developers regenerate locally before pushing.

Security Boundaries

Spec Kit executes agent-generated code during the sync process (e.g., running tests to validate generated implementations). This creates a trust boundary:

  • Spec source: Who can modify specs? If specs live in the same repo as code, existing code review processes apply.
  • Agent output: Do you trust the agent to generate safe code? Sandboxing (Docker, gVisor) is recommended for untrusted agents.
  • Extension code: Extensions run with full CLI privileges. Only install extensions from trusted sources.

For high-security environments, run agents in isolated containers:

specify sync --agent-runtime=docker \
  --agent-image=your-org/secure-agent:v1

The CLI spawns a container, mounts the spec and output directory, and invokes the agent inside the sandbox.

Technical Verdict

Use Spec Kit when:

  • Your team already writes detailed specs (PRDs, API docs, architecture diagrams) and wants to make them executable.
  • You’re integrating multiple AI coding agents and need a unified interface.
  • You want version control semantics where specs are the canonical source of truth.
  • You’re building organizational infrastructure for spec-driven workflows (custom presets, compliance checks).

Avoid Spec Kit when:

  • Your workflow is exploratory and specs emerge from code experiments (spec-first doesn’t fit).
  • You need real-time collaboration on specs (Spec Kit is file-based, not a live editor).
  • Your agents are highly non-deterministic and produce wildly different outputs on re-runs (state management breaks down).
  • You’re working solo and don’t need the organizational scaffolding (bundles, extensions, role-based presets).

The experimental goal of making specifications truly executable (not just agent prompts) is ambitious. Current implementation treats specs as structured prompts. Future versions may compile specs to intermediate representations (IR) that agents execute directly, similar to how compilers work. That would require standardizing spec semantics across agents, which is an open research problem.