Architecture Decision Log¶
Decisions are recorded here as they are made. Each ADR captures the context, the decision, and the consequences — including trade-offs accepted.
| # | Title | Status |
|---|---|---|
| 001 | Use Anthropic API with claude-sonnet-4-6 | Accepted |
| 002 | Enforce structured output via tool use, not prompt engineering | Accepted |
| 003 | Use synthetic data only — no real news articles | Accepted |
| 004 | Implement eval metrics in plain Python — no ML framework | Accepted |
| 005 | Optimize the classifier prompt with an autonomous, error-driven agent, guarded by a 3-way split | Accepted |
| 006 | Make an autonomy ladder the portfolio spine, with the classifier as the single protagonist | Accepted |
| 007 | Wire the v2 gold-set evals into CI as a two-gate quality gate, split by API cost and fork-PR secret safety | Accepted |
| 008 | Enforce enum validity server-side with strict: true, retire the client-side re-sample |
Accepted |
| 009 | Add a Message Batches API path for non-latency-sensitive bulk classification | Accepted |
| 010 | Pin the RAG-grounded path to claude-sonnet-4-6 after the Sonnet-5 workhorse migration | Superseded by 012 |
| 011 | Re-aim v2.2.0 tiered routing at technology-vs-operations, not industry-vs-procurement | Closed by 013 |
| 012 | Retire BM25 retrieval grounding — it no longer pays under the improved prompt | Accepted |
| 013 | Decline tiered model routing — measured, it buys nothing at ~2x the cost | Accepted |
| 014 | Region field design — six labels with a global catch-all, gold-first scope |
Accepted |
| 015 | All text is public-domain or synthetic — DVIDS + SEC + generated, never scraped or licensed | Accepted |
| 016 | Agentic PR review as an advisory lane, not a gate — comments only, never fails the build; on-demand via @claude only since 2026-07-26 (Amendment 1) |
Accepted |
| 017 | Classical ML baseline bake-off — TF-IDF+logreg measured; the LLM wins by 20+ points, the spend is justified with a number | Accepted |
| 018 | Rung 2: agent-driven ML loop on the bake-off substrate — rung 1's A/B/C + done-signal architecture reused as shared code | Accepted |
| 019 | kNN-exemplar few-shot — measured and declined as a clean null (n=300 paired, p=0.70); completes the three-shape retrieval series | Accepted |
| 020 | L4 built + measured: the backward edge fixed 6/7 of the named cluster, but the over-challenging critic did net harm (scale domain p=0.016) at 4× cost — declined as configured | Accepted |
| 021 | One API error taxonomy (retry 429/5xx/529/timeouts, fail fast on auth/quota/billing) replacing five hand-rolled loops, plus a stop-reason assertion so a truncated response is never scored | Accepted |
| 022 | Scaled region eval measured (n=300): region 88.3% [84.2, 91.5], the CI narrows 18pts → 7pts, and the named global cluster is confirmed systematic (49% of region disagreements) — figures published as frozen dated prose, no CI floor |
Accepted |
| 023 | The global-boundary prompt clause, measured against ADR-022's ruler and reverted: region 88.5% → 92.2% (12/17 named pulls fixed, 7 correct rows broken) at McNemar p=0.0522 against a pre-registered p<0.05 — marginal reverts, because a pre-registration that binds only when convenient is not one. Amended 2026-08-03 with a pointer to ADR-024; body unchanged |
Accepted |
| 024 | The same clause re-registered at adequate power and adopted (v3.2.1): effective n=595 at 0.837 power, region 89.9% → 94.1% at McNemar p=0.0002, guardrails clean, gold 87.0% → 94.4% — the first measure-first adoption after six declines, and the honest lesson is that ADR-023 was underpowered (~49%), not wrong |
Accepted |
| 026 | Ralph outer loop with an honest ruler — the agent reads split A, the acceptance gate is the hidden split B, split C decides nothing; all seven agent-ops ADR-016 rails live in the outer script, and the loop merges nothing | Accepted |
Format¶
Each ADR follows this structure:
- Context — what problem or decision point prompted this
- Decision — what was chosen
- Consequences — what the decision enables, what it costs, what it forecloses
- Alternatives Considered — what was ruled out and why
Statuses: Proposed → Accepted → Superseded / Deprecated