Skip to main content

Plumb

Plumb is proof of concept software demonstrating how we can manage the "Spec Driven Development Triange". It is very much alpha software, use cautiously.

A tool to keep things true.

plumb keeps your spec, tests, and code in sync during AI-assisted development.

When you work with Claude Code, decisions get made — a caching strategy is chosen, an API contract changes, a behavior is refined. These decisions live in conversation history and staged diffs, but they never make it back to the spec or tests. Over time, the spec drifts from reality, tests cover the wrong behavior, and the codebase becomes its own undocumented source of truth.

Plumb fixes this by intercepting git commit via a pre-commit hook. It analyzes your staged changes and Claude Code conversation, extracts the decisions that were made, and gates the commit on your review. Approved decisions are automatically synced back to the spec and tests. Rejected decisions trigger code modifications to undo them. The result: every committed state has a spec and test suite that could reconstruct the program.

Install

pip install plumb-dev

or

uv add plumb-dev

Quick Start

cd your-project
plumb init

This will:

  1. Ask for paths to your spec markdown and test directory
  2. Create a .plumb/ directory for state (commit this to version control)
  3. Install a git pre-commit hook
  4. Install a Claude Code skill file at .claude/skills/plumb/SKILL.md
  5. Add a Plumb block to CLAUDE.md
  6. Create a .plumbignore file for excluding irrelevant files from analysis
  7. Parse your spec into requirements

From here, just work normally. Plumb activates when you commit.

How It Works

Committing inside Claude Code

  1. You run git commit (or Claude Code does)
  2. The pre-commit hook fires, analyzes the staged diff and conversation log
  3. It writes pending decisions and exits non-zero, aborting the commit
  4. Claude Code's skill reads the output and presents each decision:

    Question: Should we cache API responses in memory or on disk? Decision made: In-memory cache using a dict. Approve, reject, or edit?

  5. You respond in chat. The skill calls plumb approve, plumb reject, or plumb edit
  6. Rejected decisions trigger plumb modify, which rewrites the staged code
  7. Once all decisions are resolved, git commit runs again and lands

Committing from the terminal

Same flow, but you drive it with plumb review instead of the skill.

Commands

Command What it does
plumb init Initialize Plumb in a git repo
plumb status Show spec files, requirements, pending decisions, coverage
plumb diff Preview what decisions Plumb would extract from staged changes
plumb review Interactively review pending decisions in the terminal
plumb approve <id> Approve a decision and sync it to spec/tests
plumb approve --all Approve all pending decisions at once
plumb reject <id> --reason "..." Reject a decision
plumb edit <id> "new text" Amend a decision's text and approve it
plumb modify <id> Auto-modify staged code to satisfy a rejected decision
plumb sync Sync all unsynced approved/edited decisions to spec and tests
plumb parse-spec Re-parse spec files into requirements
plumb coverage Report code coverage, spec-to-test, and spec-to-code coverage

Coverage

Plumb tracks three dimensions of coverage:

  • Code coverage — pytest line coverage via pytest --cov
  • Spec-to-test — which requirements have corresponding tests
  • Spec-to-code — which requirements have corresponding implementations

Run plumb coverage to see all three.

.plumbignore

Plumb uses a .plumbignore file with gitignore-style patterns to exclude files from analysis. This keeps noise out of the decision extraction process — lock files, generated code, and other irrelevant diffs won't produce spurious decisions.

Project State

All Plumb state lives in .plumb/ at the repo root:

.plumb/
├── config.json          # Spec paths, test paths, settings
├── coverage.json        # Cached coverage data
├── decisions.jsonl      # Append-only log of all decisions
└── requirements.json    # Parsed requirements from the spec

Commit this directory to version control.

Requirements

  • Python 3.10+
  • A git repository
  • An ANTHROPIC_API_KEY environment variable or .env file (for LLM-powered analysis)

Note: plumb init, plumb status, and plumb review work without an API key. The key is only needed when the hook analyzes diffs or when syncing decisions to spec/tests.

License

MIT

Metadata

Release files for plumb-dev 0.2.4

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

Source distribution (sdist)

Source distribution for plumb-dev 0.2.4
File Size Uploaded Provenance Actions
plumb_dev-0.2.4.tar.gz 237.6 kB Without provenance Details for plumb_dev-0.2.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for plumb-dev 0.2.4
File Interpreter ABI Platform Actions
plumb_dev-0.2.4-py3-none-any.whl Python 3 none any Details for plumb_dev-0.2.4-py3-none-any.whl

Total release size: 287.6 kB

Release files / plumb_dev-0.2.4.tar.gz

Download URL plumb_dev-0.2.4.tar.gz
Size 237.6 kB
Tags Source
SHA-256 checksum
How to use checksums
a38a5ebf27aa1ab639a06aed2cd722f5201cccee68da14ab9c2fc25578579eab
BLAKE2b-256 checksum
How to use checksums
d6f034321f5931af685d3391065a51b16dbf5b969297d5e54b10a80c5475a2b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Release files / plumb_dev-0.2.4-py3-none-any.whl

Download URL plumb_dev-0.2.4-py3-none-any.whl
Size 50.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8ae9a6fe8cd42f5784e867d4d2d1d1e6032fdfd5ab9c228bfb84977d81f44fa7
BLAKE2b-256 checksum
How to use checksums
28001ca7532290553f0b75f65ceda4d26aa01021f72145da9d0e424e6a9c0c65
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.8

Security for plumb-dev 0.2.4

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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