Spec-Driven Development engine for AI-assisted solo development
Project description
Roundhouse
Spec-Driven Development engine for AI-assisted solo development.
[](https://github.com/pierregrothe/roundhouse/actions/workflows/ci.yml)
[](https://pypi.org/project/roundhouse-sdd/)
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
- Installation
- Quick Start
- Core Concepts
- CLI Reference
- TUI (Terminal UI)
- Using as a Library
- AI Integration
- Architecture
- Policy Enforcement
- Configuration
- Development
- License
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 bareroundhousecommand 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 configurationroundhouse.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:
- Constitutional policies always win (regardless of scope)
- Scope-specific policies take precedence over global
- Global policies are the fallback
- Within the same tier, lower
prioritynumber wins - Duplicate slugs are deduplicated (first seen wins)
CLI Reference
All examples below use the bare
roundhousecommand. Activate the virtual environment first, or install viapip 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_queuefor 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:
--dbCLI flagROUNDHOUSE_DBenvironment variable- 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
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Write tests first (TDD)
- Implement the feature
- Run the full test suite (
pytest) - Submit a pull request
License
MIT License. Copyright (c) 2026 Pierre Grothe.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd37e32bd44604146979220da650ca16464336185c9180f16a1d3ee4c0f3b1a8
|
|
| MD5 |
41865489f95b42ffd6b6501b0ef8afb0
|
|
| BLAKE2b-256 |
a0c5d14a4721aad0996a7cb00fdb871baee6c3a77d6ed9efa8899bacaf97b05a
|
File details
Details for the file roundhouse_sdd-2026.4.0-py3-none-any.whl.
File metadata
- Download URL: roundhouse_sdd-2026.4.0-py3-none-any.whl
- Upload date:
- Size: 279.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19ce93a4a65ecf417edf1b02028b9fdf3a3339a0dbd50706e94fbc6574706794
|
|
| MD5 |
2b41fa1081d258ef8cf1bfe3724c94fe
|
|
| BLAKE2b-256 |
bb3811df78ea5f014fe78c94f60658d4fbb432170f32923b92b115837e69847c
|