A project for people to pair program with AI, the right way.
Project description
Quick Start
git clone https://github.com/nullhack/smith
cd smith
curl -LsSf https://astral.sh/uv/install.sh | sh # skip if uv installed
uv sync --all-extras
opencode && @setup-project # personalise for your project
uv run task test && uv run task lint && uv run task static-check
Why this template?
Most Python templates give you a folder structure and a Makefile. This one gives you a complete delivery system: five AI agents, a structured five-step workflow, and quality gates that cannot be silenced by convention.
The goal is to give every project — from its first commit — the same rigour that mature teams take years to establish.
- No feature starts without written acceptance criteria — Gherkin
Example:blocks traced to tests - No feature ships without adversarial review — the reviewer's default hypothesis is "broken"
- No guesswork on test stubs — generated automatically from
.featurefiles - No manual
@idtags — assigned automatically when you run tests - AI agents for every role — each agent has scoped instructions and cannot exceed its authority
How it works
The delivery cycle
SCOPE → ARCH → TDD LOOP → VERIFY → ACCEPT
| Step | Role | Output |
|---|---|---|
| 1 · SCOPE | Product Owner | Discovery interviews + Gherkin stories + acceptance criteria |
| 2 · ARCH | Software Engineer | Module stubs, ADRs, auto-generated test stubs |
| 3 · TDD LOOP | Software Engineer | RED → GREEN → REFACTOR, one criterion at a time |
| 4 · VERIFY | Reviewer | Adversarial check — lint, types, coverage, semantic review |
| 5 · ACCEPT | Product Owner | Demo, validate, ship |
WIP limit: 1 feature at a time. Features are .feature files that move through folders:
docs/features/backlog/ ← waiting
docs/features/in-progress/ ← building (max 1)
docs/features/completed/ ← shipped
AI agents included
| Agent | Responsibility |
|---|---|
@product-owner |
Scope, stories, acceptance criteria, delivery acceptance |
@software-engineer |
Architecture, TDD loop, git, releases |
@reviewer |
Adversarial verification — default position: broken |
@designer |
Visual identity, colour palette, SVG assets |
@setup-project |
One-time project initialisation |
Quality tooling, pre-configured
| Tool | Role |
|---|---|
uv |
Package & environment management |
ruff |
Lint + format (Google docstrings) |
pyright |
Static type checking — 0 errors |
pytest + hypothesis |
Tests + property-based testing |
pytest-beehave |
Auto-generates test stubs from .feature files |
pytest-cov |
Coverage — 100% required |
pdoc |
API docs → GitHub Pages |
taskipy |
Task runner |
Commands
uv run task test # Full suite + coverage
uv run task test-fast # Fast, no coverage (use during TDD loop)
uv run task lint # ruff check + format
uv run task static-check # pyright
uv run task run # Run the app
Code standards
| Coverage | 100% |
| Type errors | 0 |
| Function length | ≤ 20 lines |
| Class length | ≤ 50 lines |
| Max nesting | 2 levels |
| Principles | YAGNI › KISS › DRY › SOLID › Object Calisthenics |
Test convention
Write acceptance criteria in Gherkin:
@id:a3f2b1c4
Example: User sees version on startup
Given the application starts
When no arguments are passed
Then the version string is printed to stdout
Run tests once — a traced, skipped stub appears automatically:
@pytest.mark.skip(reason="not yet implemented")
def test_display_version_a3f2b1c4() -> None:
"""
Given the application starts
When no arguments are passed
Then the version string is printed to stdout
"""
Each test traces to exactly one acceptance criterion. No orphan tests. No untested criteria.
Branding
When you run @setup-project, the agent collects your project's identity — name, tagline, mission, colour palette, and release naming convention — and writes docs/branding.md. All agents read this file. Release names, C4 diagram colours, and generated copy all reflect your project's identity without you touching .opencode/.
Absent or blank fields fall back to defaults: adjective-animal release names, Mermaid default colours, no wording constraints.
Versioning
v{major}.{minor}.{YYYYMMDD} — each release gets a unique name derived from your branding convention. By default: an adjective paired with an animal (scientific name). Configure your own theme in docs/branding.md.
License
MIT — see LICENSE.
Author: @nullhack · Documentation
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 agents_smith-0.1.20260421.tar.gz.
File metadata
- Download URL: agents_smith-0.1.20260421.tar.gz
- Upload date:
- Size: 6.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7f79dff72eda292f8e6591e3b809eec4fae938d1f3e16032fcfb540819759c5
|
|
| MD5 |
4412180e7e076faefbf4b95919fb9fe3
|
|
| BLAKE2b-256 |
1893a1b8b55a2dfaa1fcae15380fd4fa22156b085c4d5305cbaaf3b221f5a186
|
Provenance
The following attestation bundles were made for agents_smith-0.1.20260421.tar.gz:
Publisher:
pypi-publish.yml on nullhack/agents-smith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agents_smith-0.1.20260421.tar.gz -
Subject digest:
c7f79dff72eda292f8e6591e3b809eec4fae938d1f3e16032fcfb540819759c5 - Sigstore transparency entry: 1346409283
- Sigstore integration time:
-
Permalink:
nullhack/agents-smith@595d378243fe96d2b27749fdab0c25b7408a6cce -
Branch / Tag:
refs/tags/v0.1.20260421 - Owner: https://github.com/nullhack
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@595d378243fe96d2b27749fdab0c25b7408a6cce -
Trigger Event:
push
-
Statement type:
File details
Details for the file agents_smith-0.1.20260421-py3-none-any.whl.
File metadata
- Download URL: agents_smith-0.1.20260421-py3-none-any.whl
- Upload date:
- Size: 6.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ef83a7ec4541ff9d2bad8c41622e4ebc4ad8eed97dd905171dd7b320e43c0e2
|
|
| MD5 |
92705e86b3dc83497e84a2a201d83019
|
|
| BLAKE2b-256 |
e692be261a246102e2fdcba9c01b48081125ab93f3c5501ccddc57a113e7d756
|
Provenance
The following attestation bundles were made for agents_smith-0.1.20260421-py3-none-any.whl:
Publisher:
pypi-publish.yml on nullhack/agents-smith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agents_smith-0.1.20260421-py3-none-any.whl -
Subject digest:
0ef83a7ec4541ff9d2bad8c41622e4ebc4ad8eed97dd905171dd7b320e43c0e2 - Sigstore transparency entry: 1346409378
- Sigstore integration time:
-
Permalink:
nullhack/agents-smith@595d378243fe96d2b27749fdab0c25b7408a6cce -
Branch / Tag:
refs/tags/v0.1.20260421 - Owner: https://github.com/nullhack
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@595d378243fe96d2b27749fdab0c25b7408a6cce -
Trigger Event:
push
-
Statement type: