A small, deliberately complete example of durable AI-assisted code. It extracts structured fields from the text of an invoice or receipt using Claude, and exists to show what the durable-code practices look like in one repository you can read in an afternoon: a written spec, a fail-fast config, a single model-dependent function, evals that gate model behavior, a hook that enforces a house rule, and CI. It is the worked example for the Durable Code series.
The surface is intentionally tiny: text in, JSON out. No images, no upload handling, no database, no auth, no users. The interesting part is the one place the system depends on a model, and how that part is specified, constrained, tested, and gated.
The repository is durable-code-example; the package inside it is
invoice-extractor, installed as the extract-invoice command.
$ echo "ACME OFFICE SUPPLIES
Invoice #4471 Date: 2024-03-14
Stapler 19.98
Desk lamp 34.00
Total: USD 53.98" | extract-invoice
{
"vendor": "ACME Office Supplies",
"invoice_date": "2024-03-14",
"total": 53.98,
"currency": "USD",
"line_items": [
{"description": "Stapler", "amount": 19.98},
{"description": "Desk lamp", "amount": 34.00}
]
}
The output shape is guaranteed by the model's structured-output format, so the code does not parse-and-repair. See docs/adr/0001-structured-outputs.md.
Requires Python 3.13 and an Anthropic API key.
git clone https://github.com/AgenticBricksRepo/durable-code-example.git
cd durable-code-example
./scripts/setup.sh # creates .venv, installs, runs the offline checks
source .venv/bin/activate
cp .env.example .env # then put your key in .env
extract-invoice path/to/invoice.txtpip install -e ".[dev]"
# Unit tests: offline, mocked, no key needed
pytest tests/
# Evals: gate model behavior; call the real model, so they need a key
ANTHROPIC_API_KEY=sk-ant-... pytest evals/
# Lint and security review
ruff check .
bandit -r src
pip-auditUnit tests gate code changes. Evals gate the things that change the model's behavior: the prompt, the model, or the schema. The offline eval-set check runs without a key, so CI always exercises it. See evals/README.md.
In CI (.github/workflows/ci.yml), every push and pull request is gated by lint,
the unit suite, the offline eval-set check, and the security review. The live
evals need a key, and a live key should not live in a public repo's Actions
secrets, so CI does not run them automatically. A maintainer runs them on demand
via the workflow_dispatch trigger after configuring an ANTHROPIC_API_KEY
secret, or anyone runs them locally with a key. That run uses --require-live, so
a configured run fails rather than passing by skipping.
| Practice | Where it lives |
|---|---|
| Specs | docs/SPEC.md, docs/adr/, docs/CONVENTIONS.md |
| Manage agents (mechanisms) | .github/workflows/ci.yml, .claude/agents/reviewer.md |
| Automated tests + evals | tests/, evals/ (deterministic, judge, calibration) |
| Automated setup | scripts/setup.sh (idempotent clone-to-running) |
| Agent context | small CLAUDE.md, docs/, externalized prompts/, .claude/ |
| Probabilistic to deterministic | config.py fail-fast, structured outputs, the .claude/ hook |
durable-code-example/
├── src/invoice_extractor/ # config, schema, prompt loader, extract, cli
├── prompts/ # the extraction prompt (externalized)
├── tests/ # offline unit tests (mocked)
├── evals/ # deterministic + judge + calibration; authored cases
├── docs/ # SPEC, CONVENTIONS, ADRs
├── .claude/ # the house-style hook and the reviewer subagent
└── .github/workflows/ci.yml
Released under the MIT License.