State-Driven Development Framework - Terraform for your codebase
Project description
terra4mice
State-Driven Development Framework
"Software isn't done when it works. It's done when state converges with spec."
terra4mice applies Terraform's mental model to software development. While Terraform manages infrastructure, terra4mice manages living development.
The Problem
In livecoding, this happens:
- You implement A
- B breaks A
- You workaround with C
- D becomes a TODO
- Someone says "it works"
- Weeks later: D never existed
The system doesn't know:
- Which parts of the spec are complete
- Which parts are mocked
- Which parts only exist in your head
The Solution
SPEC (desired state) -> What SHOULD exist (declarative YAML)
STATE (current state) -> What DOES exist (inferred/marked)
PLAN (diff) -> spec - state = work to do
APPLY (execution) -> Cycles until convergence
Quick Start
# Install
pip install terra4mice
# With deep AST analysis (optional, Python >=3.10)
pip install terra4mice[ast]
# With remote state backend (S3 + DynamoDB locking)
pip install terra4mice[remote]
# Initialize in your project
cd my-project
terra4mice init
# See what's missing
terra4mice plan
# Auto-detect codebase state
terra4mice refresh
# List resources in state
terra4mice state list
# Mark something as implemented
terra4mice mark feature.auth_login --files src/auth.py
# CI report (JSON)
terra4mice ci --format json
Commands
terra4mice init
Creates spec and state files:
terra4mice init
# Created: terra4mice.spec.yaml
# Created: terra4mice.state.json
terra4mice plan
Shows what's needed to converge:
$ terra4mice plan
terra4mice will perform the following actions:
+ feature.auth_login
# Resource declared in spec but not in state
+ feature.auth_refresh
# Resource declared in spec but not in state
~ feature.auth_logout
# Resource is partially implemented
Plan: 2 to create, 1 to update.
With --verbose, plan shows function-level symbol tracking:
$ terra4mice plan --verbose
~ module.inference
# Resource is partially implemented
Symbols: 10/12 found
- format_report (missing)
- validate_config (missing)
terra4mice refresh
Auto-detects codebase state using multiple strategies:
$ terra4mice refresh
Scanning /my-project for resources...
Inference Report
============================================================
IMPLEMENTED (5 resources)
module.models
Confidence: [##########] 100%
Files: src/models.py
Evidence: Explicit files found, AST analysis: 100% match
Symbols: 12/12 (100%)
PARTIAL (1 resources)
feature.auth
Confidence: [######----] 60%
Symbols: 5/8 (62%)
Missing: validate_token, refresh_session, logout_handler
MISSING (2 resources)
feature.payments
feature.notifications
Summary
Convergence: 68.8%
Inference strategies (in priority order):
- tree-sitter AST (with
[ast]) - verifies functions, classes, exports against spec attributes - stdlib ast - basic Python analysis
- Regex - Solidity, TypeScript/JavaScript patterns
- Heuristic - config/docs file size
terra4mice state list
Lists all resources in state:
$ terra4mice state list
feature.auth_login
feature.auth_refresh
module.payment_processor
terra4mice state show <address>
Shows resource details including symbol-level tracking:
$ terra4mice state show module.inference
# module.inference
type = "module"
name = "inference"
status = "implemented"
files = ["src/terra4mice/inference.py"]
symbols = 12 (10 implemented, 2 missing)
InferenceEngine class lines 94-686 (src/terra4mice/inference.py)
InferenceEngine.infer_all method lines 154-178 (src/terra4mice/inference.py)
InferenceEngine.infer_resource method lines 180-245 (src/terra4mice/inference.py)
format_inference_report function lines 719-787 (src/terra4mice/inference.py)
validate_config function [MISSING]
terra4mice mark <address>
Marks a resource with a status:
# Mark as implemented
terra4mice mark feature.auth_login --files src/auth.py
# Mark as partial
terra4mice mark feature.auth_refresh --status partial --reason "Missing token rotation"
# Mark as broken
terra4mice mark feature.auth_logout --status broken --reason "Tests failing"
terra4mice apply
Interactive apply loop:
$ terra4mice apply
============================================================
Next: + feature.auth_login
Resource declared in spec but not in state
Attributes: {'endpoints': ['POST /auth/login']}
Action: [i]mplement, [p]artial, [s]kip, [q]uit? i
Files that implement this: src/auth.py, src/routes/login.py
Marked as implemented: feature.auth_login
terra4mice state pull / push
Sync state between local and remote backends:
# Download remote state to a local file
terra4mice state pull -o local_backup.json
# Upload local state to the remote backend
terra4mice state push -i local_backup.json
terra4mice force-unlock <lock-id>
Force-release a stuck state lock (when a process crashes mid-operation):
terra4mice force-unlock a1b2c3d4-5678-9abc-def0-123456789abc
# Lock forcefully released: a1b2c3d4-...
# WARNING: Releasing a lock held by another process may cause state corruption.
terra4mice init --migrate-state
Migrate local state to a remote backend configured in the spec:
# 1. Add backend: section to terra4mice.spec.yaml
# 2. Run migration
terra4mice init --migrate-state
# State migrated to s3 backend.
# Resources: 12
# Serial: 45
terra4mice diff
Compare two state snapshots to see what changed:
$ terra4mice diff --old state.json.bak
terra4mice diff
==================================================
Old: state.json.bak (serial 5)
New: terra4mice.state.json (serial 8)
Upgraded (3):
module.inference: partial -> implemented
module.analyzers: missing -> implemented
feature.ci: partial -> implemented
Convergence: 45.0% -> 78.3% (+33.3%)
terra4mice ci
Output for CI/CD pipelines:
# JSON (machine-readable)
terra4mice ci --format json
# Markdown (PR comments)
terra4mice ci --format markdown --comment pr-comment.md
# Fail if convergence < threshold
terra4mice ci --fail-under 80
Spec File Format
# terra4mice.spec.yaml
version: "1"
resources:
feature:
auth_login:
attributes:
description: "User login"
endpoints: [POST /auth/login]
depends_on: []
auth_refresh:
attributes:
description: "Token refresh"
depends_on:
- feature.auth_login
module:
state_manager:
attributes:
class: StateManager
functions: [load, save, list, mark_created]
files:
- src/state_manager.py
endpoint:
api_users:
attributes:
method: GET
path: /api/users
depends_on:
- feature.auth_login
Spec Attributes for AST Verification
With terra4mice[ast] installed, these attributes are verified against actual code:
attributes:
class: StateManager # verified in classes
functions: [load, save, list] # verified in defined functions
entities: [Resource, State] # verified in classes/interfaces/types/enums
exports: [WorkerRatingModal] # verified in exports (TS/JS)
imports: [useState, useEffect] # verified in imports
commands: [init, plan, refresh] # substring match in functions
strategies: [explicit_files] # substring match in functions+classes
Supported languages: Python, TypeScript/TSX, JavaScript, Solidity.
State File Format
{
"version": "1",
"serial": 3,
"last_updated": "2026-01-27T15:30:00",
"resources": [
{
"type": "module",
"name": "inference",
"status": "implemented",
"files": ["src/terra4mice/inference.py"],
"symbols": {
"InferenceEngine": {
"name": "InferenceEngine",
"kind": "class",
"status": "implemented",
"line_start": 94,
"line_end": 686,
"file": "src/terra4mice/inference.py"
},
"format_report": {
"name": "format_report",
"kind": "function",
"status": "missing"
}
}
}
]
}
Remote State Backend
Store state in S3 with optional DynamoDB locking for team collaboration. Add a backend: section to your spec:
# terra4mice.spec.yaml
version: "1"
backend:
type: s3
config:
bucket: my-terra4mice-state
key: projects/myapp/terra4mice.state.json
region: us-east-1
lock_table: terra4mice-locks # DynamoDB table (optional)
profile: my-aws-profile # AWS profile (optional)
encrypt: true # S3 SSE (optional)
resources:
# ... your spec unchanged ...
Without backend: or with type: local, behavior is unchanged (local file).
DynamoDB Lock Table Setup
aws dynamodb create-table \
--table-name terra4mice-locks \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
How Locking Works
When a backend with lock_table is configured, mutating commands (refresh, mark, lock, unlock, state rm, state push) automatically acquire a DynamoDB lock before writing. If another process holds the lock, the command fails with a descriptive error showing who holds it and when it was acquired.
CI/CD Integration
# .github/workflows/terra4mice.yml
name: Check Convergence
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install terra4mice[ast]
- run: terra4mice plan --detailed-exitcode
# Returns 2 if there are pending changes
Roadmap
| Phase | Status | Description |
|---|---|---|
| 1 - MVP CLI | DONE | init, plan, refresh, state, mark, apply, ci, diff |
| 2 - tree-sitter AST | DONE | Multi-language deep analysis, spec attribute verification, symbol tracking |
| 3 - Multi-AI Contexts | PLANNED | Track which AI (Claude, Codex, Kimi) has context on what |
| 4 - CI/CD Integration | DONE | GitHub Action, PR comments, convergence badges |
| 4.5 - Remote State | DONE | S3 backend, DynamoDB locking, state pull/push, migrate-state |
| 5 - Apply Runner | PLANNED | Interactive apply loop, agent integration |
| 6 - Ecosystem Rollout | PLANNED | Deploy across Ultravioleta DAO projects |
Phase 3: Multi-AI Context Tracking (Next)
When multiple AIs work on the same project, each carries its own isolated context. Phase 3 adds a context registry to know which AI has context on what:
terra4mice contexts list
# AGENT RESOURCE LAST SEEN STATUS
# claude-code module.inference 2min ago active
# codex feature.auth_login 1hr ago stale
# kimi-2.5 feature.frontend 30min ago active
terra4mice mark module.auth implemented --agent=codex
terra4mice contexts sync --from=claude-code --to=codex
Philosophy
- State before intention - What exists, not what we want
- Evidence before perception - Tests, not "I think it works"
- Convergence before speed - Better slow and correct
- Clarity before heroism - Visible plan, not magic
Definition of Done
A project is complete when:
$ terra4mice plan
No changes. State matches spec.
Nothing else.
License
MIT - Public good for the developer community.
Contributing
PRs welcome! See CONTRIBUTING.md for guidelines.
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 terra4mice-0.1.0.dev17.tar.gz.
File metadata
- Download URL: terra4mice-0.1.0.dev17.tar.gz
- Upload date:
- Size: 82.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1ed61acd9be4fa470d04a94de4ee34c8b71e67089f14137f80d6496beebbce0
|
|
| MD5 |
538f659327c9e61fba6704f9c3b9c131
|
|
| BLAKE2b-256 |
e265640c790344ceba0ddfb8f2cb174e713093fe38a53ba01be72e9940c1eb70
|
Provenance
The following attestation bundles were made for terra4mice-0.1.0.dev17.tar.gz:
Publisher:
publish.yml on 0xultravioleta/terra4mice
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
terra4mice-0.1.0.dev17.tar.gz -
Subject digest:
a1ed61acd9be4fa470d04a94de4ee34c8b71e67089f14137f80d6496beebbce0 - Sigstore transparency entry: 926198121
- Sigstore integration time:
-
Permalink:
0xultravioleta/terra4mice@643c1963116ab50e65606a723023c290ffb1aeed -
Branch / Tag:
refs/heads/main - Owner: https://github.com/0xultravioleta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@643c1963116ab50e65606a723023c290ffb1aeed -
Trigger Event:
push
-
Statement type:
File details
Details for the file terra4mice-0.1.0.dev17-py3-none-any.whl.
File metadata
- Download URL: terra4mice-0.1.0.dev17-py3-none-any.whl
- Upload date:
- Size: 56.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9489335690dc1a554c70c6f38c535f926283585b2ce138084d55caba1b82ee37
|
|
| MD5 |
3ab2ce0dc5781ab7c04f6a4d17feccd3
|
|
| BLAKE2b-256 |
42dc18bba7e75dd4050d18b5257d08a5a8fc4bd6afddfb596323e62e382135bc
|
Provenance
The following attestation bundles were made for terra4mice-0.1.0.dev17-py3-none-any.whl:
Publisher:
publish.yml on 0xultravioleta/terra4mice
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
terra4mice-0.1.0.dev17-py3-none-any.whl -
Subject digest:
9489335690dc1a554c70c6f38c535f926283585b2ce138084d55caba1b82ee37 - Sigstore transparency entry: 926198136
- Sigstore integration time:
-
Permalink:
0xultravioleta/terra4mice@643c1963116ab50e65606a723023c290ffb1aeed -
Branch / Tag:
refs/heads/main - Owner: https://github.com/0xultravioleta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@643c1963116ab50e65606a723023c290ffb1aeed -
Trigger Event:
push
-
Statement type: