A production-quality coding harness for Python (FastAPI) + Vite/React/TypeScript projects. Designed for LLM-driven development: every gate — lint, types, architecture, security, eval — is enforced mechanically so code quality stays consistent across many human and AI contributors.
- Backend: Python 3.14, FastAPI, Pydantic v2 (
StrictModelbase),uvdeps, OpenTelemetry SDK + OTLP exporter, structured JSON logs, generic tool-registry pattern. - Frontend: Node 24 LTS, React 19.2, Vite 8, TypeScript strict, ESLint 10 flat config, Prettier, Vitest + jsdom + Testing Library.
- Eval harness: provider-agnostic runner + LLM-judge
Protocol, three tolerance modes (exact / numeric / semantic), one example golden case, nightly workflow (disabled by default). - CI: 21 required status checks across
ci.yml(lint/format, mypy strict, unit tests, coverage, import-linter architecture, pre-commit, frontend build, frontend quality, branch-protection sync, commit-type sync, version/action/tests/docs audits) +security.yml(gitleaks, pip-audit, npm audit, trivy) + PR-title lint. - Release: tag-triggered workflow that builds the image, pushes to
ghcr.io, generates a CycloneDX SBOM, and publishes the GitHub Release. - Agent integration:
.claude/hooks/(forbidden-flag blocker, secret scan, formatter dispatch, SessionStart context) + six auto-activating skills (architect / code-reviewer / devops / frontend / qa-engineer / technical-writer). - Issue execution: GitHub Issues remain the external source of truth; optional Beads guidance adds a local dependency-aware execution queue without changing issue closure authority.
- Docker: multi-stage Dockerfile (non-root, healthcheck),
docker compose upboots app + frontend + Jaeger.
git clone https://github.com/constk/harness-python-react.git
cd harness-python-react
uv sync --extra dev
uv run pre-commit install --hook-type pre-commit --hook-type commit-msg
(cd frontend && npm ci)
docker compose up # backend :8000, frontend :5173, Jaeger :16686The pre-push gate is just check (= ruff + mypy + import-linter + pytest). For frontend changes add just frontend-check.
What every contributor sees before pushing:
$ uv run --frozen ruff check .
All checks passed!
$ uv run --frozen ruff format --check .
37 files already formatted
$ uv run --frozen mypy --strict src/ tests/
Success: no issues found in 31 source files
$ uv run --frozen lint-imports
Analyzed 24 files, 15 dependencies.
src layers flow one-way (api/eval -> agent -> tools -> data -> observability ->
models) KEPT
src.models depends on nothing in src/ KEPT
Contracts: 2 kept, 0 broken.
$ uv run --frozen pytest tests/ --cov=src --cov-report=term
============================= 40 passed in 0.75s ==============================
TOTAL 221 3 99%
Required test coverage of 75.0% reached. Total coverage: 98.64%
Ten jobs across ci.yml (eight backend + two frontend) — all green:
The four security-workflow jobs (gitleaks, pip-audit, npm audit, trivy) gate every PR alongside this set; see the Security workflow runs.
The scaffold's React page hits /api/v1/health on load and renders the version + status badge. The Vite dev server proxies /api/* to the FastAPI backend (target overridable via VITE_API_PROXY_TARGET):
The differentiator isn't the scaffold — it's that every layer of the pipeline catches a different failure class without relying on the human or LLM coder remembering to run anything. The same posture protects code regardless of who wrote it.
See docs/HARNESS.md for the full umbrella. Highlights:
- Pydantic
StrictModeleverywhere a contract crosses a seam (rejects unknown keys at construction). import-linterenforces one-way layer flow (api | eval → agent → tools → data → observability → models).- Three independent secret scans (PreToolUse hook → pre-commit gitleaks → CI gitleaks).
- Two meta-gates that catch drift in the gates themselves:
Branch-protection contexts sync(workflow jobs vs branch-protection JSON) andCommit-type sync(commitizen schema vs PR-title allowlist). - CycloneDX SBOM attached to every release for supply-chain attestation.
| File | Purpose |
|---|---|
docs/HARNESS.md |
Umbrella: every control + where it lives |
docs/INVARIANTS.md |
The numbered load-bearing rules |
docs/BOUNDARIES.md |
Module layering + the import-linter contracts |
docs/DEVELOPMENT.md |
Local setup, branching, justfile, CI |
docs/EVAL_HARNESS.md |
Eval flywheel + opt-in for the nightly workflow |
docs/BEADS.md |
Optional local Beads queue layered under GitHub Issues |
docs/SECURITY.md |
Threat model + defence-in-depth map |
docs/ARCHITECTURE.md |
Scaffold-level component view |
CONTRIBUTING.md |
Branching, commit format, PR flow |
CLAUDE.md |
Agent-facing project instructions |
Verified April 2026 (endoflife.date):
| Layer | Version | Sunset |
|---|---|---|
| Python | 3.14.4 | active feature release |
| Node LTS | 24.15.0 | through 2028-04-30 |
| React | 19.2.5 | current stable |
| Vite | 8.x | current stable |
| TypeScript | 6.x | current stable |
Bump together (Python in pyproject.toml, Node in frontend/package.json, both in Dockerfile + the CI matrix). Document the bump in docs/DEVELOPMENT.md.
MIT.

