Skip to main content

Spec-Driven Development engine for AI-assisted solo development

Project description

Roundhouse Logo

Roundhouse

Spec-Driven Development engine for AI-assisted solo development.

[![CI](https://github.com/pierregrothe/roundhouse/actions/workflows/ci.yml/badge.svg)](https://github.com/pierregrothe/roundhouse/actions/workflows/ci.yml) [![PyPI](https://img.shields.io/pypi/v/roundhouse-sdd)](https://pypi.org/project/roundhouse-sdd/) Python 3.14+ MIT License

Roundhouse is a standalone governance tool that replaces a full software team's coordination layer -- PM, architect, QA, tech writer -- for developers working with AI coding assistants. It solves the "two-week vacation" problem: persistent project memory, clear next actions, and enforced architectural coherence across sessions.

$ roundhouse status

Project: MyProject
Active Phase: Core Services [====>        ] 33%
Next Module:  auth-service (Phase: Core Services)
Progress:     2/6 modules complete
Blockers:     none

$ roundhouse next

Next: auth-service
Phase: Core Services (active)
Feature: User Authentication (P1)
Action: Create spec with 'roundhouse spec new --feature 2'

Table of Contents


Why Roundhouse

Without governance, AI coding assistants generate plausible but incoherent systems across conversations. Every new session starts from zero context. Architectural decisions get re-debated. Features drift from specs. The codebase grows but nobody tracks what was built, why, or what comes next.

Roundhouse provides the memory and the rules. The AI provides the intelligence.

What it tracks:

  • Features (what to build) and their specs (how to build it)
  • Modules (code units), phases (sequencing), milestones (delivery checkpoints)
  • Architecture Decision Records (why it's built this way)
  • Policies (enforcement rules derived from ADRs)
  • Research briefs (what we investigated)
  • Sessions (where we left off)

What it computes:

  • "What's next?" -- topological sort over phase dependencies
  • "Where was I?" -- last session context with time-since and diff
  • "What rules apply?" -- three-tier policy resolution (constitutional > scoped > global)
  • Quality gates for the spec pipeline (specify > clarify > plan > tasks > implement)
  • Completion percentages across milestones, phases, and modules

Installation

Requirements

  • Python 3.14+
  • pip

Install from PyPI

pip install roundhouse-sdd
roundhouse status            # Works after pip install

Install from source (development)

git clone https://github.com/pierregrothe/roundhouse.git
cd roundhouse
pip install -e ".[dev]"
roundhouse status              # CLI dashboard
python -m roundhouse status    # Alternative (debugger-friendly)

Note: Activate the virtual environment before running commands. After pip install, the bare roundhouse command is available.


Quick Start

1. Initialize a project

cd /path/to/your/project
roundhouse init --scope myproject

This creates a .roundhouse/ directory with:

  • config.toml -- project configuration
  • roundhouse.db -- SQLite database (commit this to git)

2. Add features

roundhouse feature add "User Authentication" -d "Login, registration, password reset" -p P1
roundhouse feature add "REST API Layer" -d "Public API endpoints for all services" -p P0
roundhouse feature add "Analytics Dashboard" -d "Usage metrics and reporting" -p P2

3. Create architecture decisions

roundhouse adr add "Use Protocol-based design" \
  --context "Need flexible service interfaces" \
  --decision "All services expose Protocol classes (PEP 544)"

4. Set up your roadmap

roundhouse milestone add "MVP"
roundhouse phase add "Foundation" --milestone 1
roundhouse phase add "Core Services" --milestone 1
roundhouse module add "data-models" --phase 1 --scope myproject
roundhouse module add "auth-service" --phase 2 --scope myproject

5. Check status

roundhouse status          # Full dashboard
roundhouse next            # Next actionable module
roundhouse resume          # Context from last session

6. Create a spec and start building

roundhouse spec new --feature 1 --tier T2
roundhouse spec advance 1              # Move through pipeline phases
roundhouse spec advance 1 --force      # Bypass quality gate if needed

7. Save your session

roundhouse session save --summary "Implemented auth module, 3 tests passing"

Core Concepts

Entities

Roundhouse tracks 10 entity types organized in three layers:

Governance Layer (can be global or scoped to specific projects):

  • ADR -- Architecture Decision Record. The rationale behind a decision.
  • Policy -- Enforcement rule derived from an ADR. Machine-checkable.
  • Research -- Investigation brief documenting technical exploration.

Planning Layer (always scoped to one project):

  • Feature -- What to build. Has priority (P0-P3) and lifecycle status.
  • Module -- Code organizational unit. Maps to a package or directory.
  • Phase -- Sequenced container of work. Modules belong to phases.
  • Milestone -- Delivery checkpoint. Groups phases into releases.

Execution Layer (inherited scope):

  • Spec -- Formal requirements for a feature. 1:1 with feature.
  • Task -- Discrete implementation unit within a spec.
  • Session -- Work context snapshot for continuity.

Spec Pipeline

Every feature goes through a five-phase pipeline:

specify --> clarify --> plan --> tasks --> implement

Each transition has a quality gate:

Transition Gate
specify -> clarify Minimum number of user stories (tier-dependent)
clarify -> plan Spec maturity >= S3 (Reviewed)
plan -> tasks Plan content exists
tasks -> implement At least 1 task defined

Use --force to bypass gates when AI is unavailable or for rapid prototyping. Bypassed specs are tagged quality:bypassed for audit.

Complexity Tiers

Specs are classified by complexity, which determines quality gate thresholds:

Tier Scope Example
T1 Data models Pydantic models, schemas
T2 Single service One service with protocol + implementation
T3 Multi-component Multiple services coordinating
T4 Full system End-to-end feature across all layers

Scopes (Monorepo Support)

Scopes partition entities for monorepo or multi-project use. Each scope maps to filesystem paths.

  • Scoped entities (module, phase, milestone, session) belong to one scope.
  • Multi-scope entities (ADR, policy, research, feature) can be global (apply to all scopes) or assigned to specific scopes.
  • Global = no scope entries. A constitutional ADR like "ASCII-only" applies everywhere.

Policy Resolution

When checking which policies apply to a scope, Roundhouse resolves conflicts:

  1. Constitutional policies always win (regardless of scope)
  2. Scope-specific policies take precedence over global
  3. Global policies are the fallback
  4. Within the same tier, lower priority number wins
  5. Duplicate slugs are deduplicated (first seen wins)

CLI Reference

All examples below use the bare roundhouse command. Activate the virtual environment first, or install via pip install roundhouse-sdd.

Global Options

--db TEXT         Path to roundhouse.db (overrides auto-discovery)
-s, --scope TEXT  Active scope slug (overrides config default)
--help            Show help for any command

Project Setup

roundhouse init                     # Initialize new project
roundhouse init --scope myproject   # Initialize with named scope

Status and Navigation

roundhouse status                   # Full project dashboard
roundhouse next                     # Next actionable module
roundhouse resume                   # Last session context

Features

roundhouse feature list                          # List all features
roundhouse feature list --status accepted        # Filter by status
roundhouse feature list -f json                  # JSON output
roundhouse feature add "Title" -d "Desc" -p P1   # Add feature
roundhouse feature show 1                        # Show details

Specs and Pipeline

roundhouse spec new --feature 1 --tier T2   # Create spec for feature
roundhouse spec show 1                      # Show spec with pipeline status
roundhouse spec advance 1                   # Advance to next phase
roundhouse spec advance 1 --force           # Bypass quality gate

Tasks

roundhouse task list --spec 1    # List tasks for a spec
roundhouse task start 1          # Mark task in-progress
roundhouse task done 1           # Mark task complete

Architecture Decision Records

roundhouse adr list                          # List ADRs
roundhouse adr list --status accepted        # Filter by status
roundhouse adr add "Title" --context "Why" --decision "What"
roundhouse adr show 1                        # Show with policies + research

Policies

roundhouse policy list                       # List active policies
roundhouse policy list --enforcement hook    # Filter by enforcement type
roundhouse policy show protocol-design       # Show by slug or ID

Research

roundhouse research list                     # List research briefs
roundhouse research add "Survey topic"       # Create new brief
roundhouse research show 1                   # Show details

Modules, Phases, Milestones

roundhouse module list                       # List modules
roundhouse module list --status planned      # Filter by status
roundhouse module show 1                     # Show details

roundhouse phase list                        # List phases
roundhouse phase show 1                      # Show with completion

roundhouse milestone list                    # List milestones
roundhouse milestone show 1                  # Show with phases

Sessions

roundhouse session save -s "Summary of work"   # Save current session
roundhouse session list                        # List past sessions

Scopes

roundhouse scope list                  # List all scopes
roundhouse scope set myproject         # Set default scope

Search

roundhouse search "authentication"              # Search all entities
roundhouse search "protocol" --type adr         # Filter by entity type

Background Tasks

roundhouse queue status              # Show pending/done/failed counts
roundhouse queue process             # Process deferred tasks
roundhouse queue process --batch 50  # Process in larger batches

Output Formats

All list commands support -f / --format with three options:

roundhouse feature list -f table   # ASCII table (default)
roundhouse feature list -f json    # JSON
roundhouse feature list -f plain   # Pipe-separated values

TUI (Terminal UI)

Launch the interactive terminal UI:

roundhouse tui

Screens

Key Screen Purpose
1 Dashboard Current focus, progress, next module, blockers
2 Roadmap Milestone/phase/module tree with progress bars
3 Pipeline Active spec progression and task checklist
4 Governance ADR list with policies
5 Research Research briefs with maturity levels

Keyboard Navigation

Key Action
Alt+1-6 Switch tab/screen
Ctrl+P Command palette
e Edit selected item
d Delete selected item
s Advance status of selected item
c Create new item
1-N Filter by status
/ Search
? Help
S Switch scope
j/k or arrows Navigate lists
Enter Drill into selected item
Esc Go back
q Quit

Context Panel

The right sidebar shows details of the currently selected entity: fields, status, related entities, and tags. It updates automatically as you navigate.


Using as a Library

Roundhouse is designed to be consumed as a Python library by AI tool plugins (Claude Code, Gemini CLI, etc.) or any Python application.

Basic Usage

from roundhouse.core.db import connect, run_migrations
from roundhouse.core.results import Ok, Err
from roundhouse.repositories.features import FeatureRepository
from roundhouse.repositories.links import LinkRepository
from roundhouse.repositories.milestones import MilestoneRepository
from roundhouse.repositories.modules import ModuleRepository
from roundhouse.repositories.phases import PhaseRepository
from roundhouse.services.roadmap import RoadmapService

# Connect to the project database
conn = connect("/path/to/project/.roundhouse/roundhouse.db")

# Build repositories
repos = {
    "modules": ModuleRepository(conn=conn),
    "phases": PhaseRepository(conn=conn),
    "milestones": MilestoneRepository(conn=conn),
}
links = LinkRepository(conn=conn)

# Use services
roadmap = RoadmapService(conn=conn, repos=repos, links=links)

result = roadmap.compute_next(scope_id=1)
match result:
    case Ok(data):
        if data is not None:
            print(f"Next: {data['module']['name']}")
            print(f"Phase: {data['phase']['title']}")
        else:
            print("Nothing actionable -- all caught up.")
    case Err(msg):
        print(f"Error: {msg}")

conn.close()

Service Layer

All business logic lives in the service layer. Services accept repositories via constructor injection and return ServiceResult[T] (which is Ok[T] | Err[str]).

Service Purpose
DashboardService Composite "where am I?" view
RoadmapService Phase sequencing, "what's next?", completion
PipelineService Spec state machine with quality gates
GovernanceService ADR lifecycle, policy resolution
SessionService Session lifecycle, resume context
ResearchService Research brief management
SearchService Full-text search (FTS5)
TaskQueueService Deferred background task processing
InsightsService Project metrics (time-in-status, throughput)
EnforcementService Policy enforcement orchestration (pluggy dispatch)
EmbeddingService Staleness detection for vector embeddings

Result Type

All service methods return ServiceResult[T], a Rust-inspired Result type:

from roundhouse.core.results import Ok, Err, ServiceResult

# Construction
success: ServiceResult[dict] = Ok({"id": 1, "title": "Done"})
failure: ServiceResult[dict] = Err("Feature not found")

# Pattern matching
match result:
    case Ok(value):
        process(value)
    case Err(message):
        handle_error(message)

# Chaining
result = (
    service.get_feature(1)
    .and_then(lambda f: service.create_spec(f["id"], "T2"))
    .map(lambda s: s["id"])
)

# Safe access
value = result.unwrap()          # Raises if Err
value = result.unwrap_or(None)   # Returns default if Err

AI Integration

Roundhouse has zero AI SDK dependencies. AI features use CLI subprocess calls to whatever tool the user already has installed.

Three Modes

Mode How When
Plugin AI tool imports roundhouse as library Primary use. Claude Code or Gemini CLI provides the intelligence.
CLI subprocess TUI shells out to claude/gemini Secondary. For AI features in standalone TUI.
Manual No AI, user writes all content Always works. CRUD, status, navigation, pipeline -- all functional.

Configuration

Set the AI tool in .roundhouse/config.toml:

[ai]
tool = "claude"   # or "gemini" or "none"

LLM Protocol

For plugin developers, Roundhouse defines an LLMProtocol that any AI adapter can satisfy:

from roundhouse.ai.protocols import LLMProtocol
from roundhouse.ai.cli_adapter import CLIAdapter
from roundhouse.ai.null_adapter import NullAdapter

# CLI adapter (shells out to claude/gemini)
adapter = CLIAdapter(tool="claude")

# Null adapter (manual mode)
adapter = NullAdapter()

# Custom adapter (for plugins)
class MyAdapter:
    def generate(self, prompt, context=None):
        return Ok("generated content")
    def embed(self, text):
        return Ok([0.1, 0.2, ...])

What Needs AI vs. What Doesn't

Category Features AI Needed?
Pure logic CRUD, status, navigation, progress, search, pipeline state machine No
Enhanced ADR drafting, spec generation, research synthesis, quality judgment Optional
Dependent Codebase-aware specs, code review against spec, multi-agent orchestration Plugin only

Architecture

Layer Diagram

Consumers:      TUI  |  CLI  |  Plugin (Phase 2)
                 |       |          |
                 v       v          v
API Surface:  +--------------------------------------------+
              |           Service Layer                    |
              | dashboard / roadmap / pipeline / governance |
              +--------------------------------------------+
                        |                    ^
                        v                    |
Data Layer:    Repositories + SQLite    AI Protocol
                                     (CLI subprocess)

Design Patterns

Pattern Application
Protocol-based design (PEP 544) All inter-layer contracts
Dependency injection Constructor injection, Protocol types
ServiceResult[T] Business errors as values, never exceptions
Repository pattern One per entity, thin SQL + Pydantic
Event bus (sync + deferred) Critical path (inline) + side effects (queued)
Table-per-entity-type Typed SQLite tables with CHECK constraints

Database

SQLite with WAL mode. 18 tables (19 with optional sqlite-vec):

  • 10 entity tables (features, specs, tasks, modules, phases, milestones, adrs, policies, research, sessions)
  • 1 infrastructure (scopes)
  • 3 relationship tables (entity_links, entity_scopes, entity_tags)
  • 1 audit (entity_history)
  • 2 background (embedding_metadata, task_queue)
  • 1 search (search_index -- FTS5 virtual table)
  • 1 optional (entity_embeddings -- vec0, requires sqlite-vec extension)

The database lives at .roundhouse/roundhouse.db and should be committed to git (it IS the project governance state).

Event Engine

The EventBus supports two execution paths:

  • Critical (sync): Data integrity handlers (cascade deletes, audit logging, quality gate recomputation). Must finish before the service method returns.
  • Deferred (async): Enhancement handlers (FTS5 indexing, embedding generation, policy compliance checks). Enqueued to task_queue for background processing.

Python 3.14 Features Used

Feature Use
Template strings (PEP 750) SQL injection prevention via t-strings
Deferred annotations (PEP 649) No forward-ref pain in Protocol-heavy code
StrEnum Type-safe entity statuses throughout
match/case Result matching, command dispatch, event handling
TypeIs Type narrowing for ServiceResult.is_ok()
graphlib.TopologicalSorter Phase dependency resolution

Policy Enforcement

Roundhouse enforces architectural decisions via a database-driven policy engine. Policies are stored in SQLite (not config files), resolved per-scope, and dispatched via pluggy.

How It Works

ADR (why) -> Policy (what to enforce) -> Check class (how to check)
                    |
                    v
         roundhouse enforce file1.py file2.py
                    |
                    v
         GovernanceService.resolve_policies(scope)
                    |
                    v
         pluggy CheckEngine dispatches to registered checks
                    |
                    v
         Violations grouped: hook (block) | soft (warn) | agent (AI-only)

Enforcement Tiers

Tier Behavior Example
hook Blocks commit (exit 1) ASCII-only, no type:ignore
soft Warns but allows (exit 0) Missing docstrings, test naming
ratchet Blocks if count increased Complexity, legacy patterns
agent AI-enforced only (CLAUDE.md) Protocol design, Result pattern
manual Human review Architecture decisions

Default Policies (seeded on roundhouse init)

8 ADRs and 20 derived policies are seeded automatically:

  • Constitutional (hook, priority 10): ASCII-only, UTC timezone, file headers
  • Code quality (hook, priority 50): McCabe <= 10, params <= 5, no magic numbers, absolute imports, no mocks, no type:ignore
  • Soft checks (soft, priority 100): Google docstrings, test naming
  • Agent-only (agent): Protocol design, Ok/Err pattern, constructor injection

Adding a New Enforced Rule

# 1. Create the ADR
roundhouse adr add "No Print Statements" \
  --context "Print pollutes stdout" \
  --decision "Use logging module instead"

# 2. Create a policy linked to the ADR
#    (via roundhouse policy add or direct DB insert)

# 3. Create the check class
cat > src/roundhouse/core/checks/no_print_check.py << 'EOF'
from roundhouse.core.enforcement import CheckContext, Violation, hookimpl

class NoPrintCheck:
    RULE_ID = "no-print"

    @hookimpl
    def check_file(self, ctx: CheckContext) -> list[Violation]:
        try:
            return self._check(ctx)
        except Exception as exc:
            return [Violation(self.RULE_ID, ctx.filepath, 0, str(exc), "warning")]

    def _check(self, ctx):
        violations = []
        for lineno, line in enumerate(ctx.content.splitlines(), 1):
            if "print(" in line and not line.strip().startswith("#"):
                violations.append(Violation(
                    self.RULE_ID, ctx.filepath, lineno,
                    "Use logging instead of print()", "error",
                ))
        return violations
EOF

# 4. Register in core/checks/__init__.py BUILTIN_CHECKS dict

# 5. Done. roundhouse enforce picks it up from the DB.

Pre-commit Integration

A single hook runs all policy checks:

# .pre-commit-config.yaml
- repo: local
  hooks:
    - id: roundhouse-enforce
      name: Roundhouse policy enforcement
      language: script
      entry: .hooks/enforce.sh
      types: [python]

The .hooks/enforce.sh shim resolves the .venv/ Python 3.14 to avoid system Python (3.12) incompatibility with GUI git clients.

Export Rules for AI Agents

roundhouse enforce --export claude-md

Generates markdown from the live DB for embedding in .claude/rules/:

## Policy Rules (auto-generated from Roundhouse DB)

### HOOK (blocks commit)
- **ascii-only** (P10, constitutional): No unicode/emoji -- ASCII only
- **no-type-ignore** (P50): No type: ignore except import-not-found
...

Configuration

Project Config

.roundhouse/config.toml:

[project]
name = "My Project"
default_scope = "default"

[ai]
tool = "none"    # "claude", "gemini", or "none"

[tui]
theme = "default"

Project Root Discovery

Roundhouse automatically finds the project root by climbing the directory tree looking for .roundhouse/config.toml (like git finds .git/). You can run roundhouse from any subdirectory.

Override order:

  1. --db CLI flag
  2. ROUNDHOUSE_DB environment variable
  3. Auto-discovery via find_project_root()

Database Location

.roundhouse/roundhouse.db -- add to git. Add to .gitattributes:

*.db binary

Development

Setup

git clone https://github.com/pierregrothe/roundhouse.git
cd roundhouse
poetry install
pre-commit install
pytest tests/

Running

roundhouse status                                    # CLI dashboard
roundhouse next                                      # Next actionable module
roundhouse tui                                       # TUI
python -m roundhouse status                          # Alternative (debugger-friendly)
textual run --dev roundhouse.tui.app:RoundhouseApp   # TUI with live CSS reload

Testing

pytest tests/              # All tests (573 tests, ~40s)
pytest tests/unit/         # Unit tests only (fast)
pytest tests/integration/  # Integration tests (CLI + TUI)
pytest -m slow             # Wheel install test (~30s)

Code Quality

ruff check src/ tests/     # Lint
black src/ tests/          # Format
mypy src/                  # Type check

Project Structure

src/roundhouse/
  core/             # Foundation: DB, models, results, events, constants
  repositories/     # SQL + Pydantic, one per entity type
  services/         # Business logic and computed views
  ai/               # Optional AI integration (CLI subprocess)
  cli/              # Click CLI commands
  tui/              # Textual TUI screens and widgets

Test Structure

tests/
  unit/
    core/           # Models, results, events, decorators
    repositories/   # SQL operations (in-memory SQLite)
    services/       # Business logic (real DB, no mocks)
    ai/             # Adapter tests (subprocess mocked)
  integration/
    cli/            # Click CliRunner tests
    tui/            # Textual pilot tests (async)
    db/             # Schema migration tests

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Write tests first (TDD)
  4. Implement the feature
  5. Run the full test suite (pytest)
  6. Submit a pull request

License

MIT License. Copyright (c) 2026 Pierre Grothe.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

roundhouse_sdd-2026.4.0.tar.gz (209.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

roundhouse_sdd-2026.4.0-py3-none-any.whl (279.9 kB view details)

Uploaded Python 3

File details

Details for the file roundhouse_sdd-2026.4.0.tar.gz.

File metadata

  • Download URL: roundhouse_sdd-2026.4.0.tar.gz
  • Upload date:
  • Size: 209.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for roundhouse_sdd-2026.4.0.tar.gz
Algorithm Hash digest
SHA256 dd37e32bd44604146979220da650ca16464336185c9180f16a1d3ee4c0f3b1a8
MD5 41865489f95b42ffd6b6501b0ef8afb0
BLAKE2b-256 a0c5d14a4721aad0996a7cb00fdb871baee6c3a77d6ed9efa8899bacaf97b05a

See more details on using hashes here.

File details

Details for the file roundhouse_sdd-2026.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for roundhouse_sdd-2026.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 19ce93a4a65ecf417edf1b02028b9fdf3a3339a0dbd50706e94fbc6574706794
MD5 2b41fa1081d258ef8cf1bfe3724c94fe
BLAKE2b-256 bb3811df78ea5f014fe78c94f60658d4fbb432170f32923b92b115837e69847c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page