Production-ready Python scaffolding with a structured AI-agent workflow — from idea to shipped feature.
git clone https://github.com/nullhack/python-project-template
cd python-project-template
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-checkSCOPE → ARCH → TDD LOOP → VERIFY → ACCEPT
| Step | Who | What |
|---|---|---|
| SCOPE | Product Owner | Discovery interviews → Gherkin stories → @id criteria |
| ARCH | Software Engineer | Module design, ADRs, test stubs |
| TDD LOOP | Software Engineer | RED → GREEN → REFACTOR, one @id at a time |
| VERIFY | Reviewer | Adversarial verification — default hypothesis: broken |
| ACCEPT | Product Owner | Demo, validate, ship |
WIP limit of 1. Features are .feature files that move between filesystem folders:
docs/features/backlog/ ← waiting
docs/features/in-progress/ ← building (max 1)
docs/features/completed/ ← shipped
@product-owner — scope, stories, acceptance
@software-engineer — architecture, TDD, git, releases
@reviewer — adversarial verification
@setup-project — one-time project initialisation
| Tool | Role |
|---|---|
uv |
Package & environment management |
ruff |
Lint + format (Google docstrings) |
pyright |
Static type checking — 0 errors |
pytest + hypothesis |
Tests + property-based testing |
pytest-cov |
Coverage — 100% required |
pdoc |
API docs → GitHub Pages |
taskipy |
Task runner |
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| Coverage | 100% |
| Type errors | 0 |
| Function length | ≤ 20 lines |
| Class length | ≤ 50 lines |
| Max nesting | 2 levels |
| Principles | YAGNI › KISS › DRY › SOLID › Object Calisthenics |
@pytest.mark.skip(reason="not yet implemented")
def test_feature_a3f2b1c4() -> None:
"""
Given: ...
When: ...
Then: ...
"""Each test is traced to exactly one @id acceptance criterion.
v{major}.{minor}.{YYYYMMDD} — each release gets a unique adjective-animal name.
MIT — see LICENSE.
Author: @nullhack · Documentation