
Hardware teams don't fail from bad ideas; they fail from momentum. The business case that cleared the Discovery gate is never re-run — BOM cost creeps, the forecast slips, and a program discovers at PVT that it's ramping a product with no margin, a fact that was checkable, cheaply, at every gate in between. No spreadsheet catches this on its own, because a spreadsheet only tells you what someone remembered to update.
Sixteen fixed questions establish where a program actually stands — build facts, not opinions, drive a deterministic state machine that decides the stage; the model only scores the answers, at temperature 0, against rubric cells it never wrote.
The output is a derived verdict and an evidence checklist naming exactly what's met, what's missing, and what closes the gap. The checklist can pull a proceed down to iterate on real evidence; it can never manufacture a pivot or a stop out of nothing — that's arithmetic, not a model's opinion.
A grounded chat sits beside it, backed by six tools: a diagnostic, an action-plan generator, a build-cost estimator, a template generator, a criteria explainer, and a credits check — each answering from a 25-document knowledge base, never from memory.
The knowledge base — 264 chunks, one per rubric cell and ## section — lives in a local ChromaDB store, filtered by stage, dimension, and maturity level before a query ever reaches the model.
LangChain's agent runtime drives six tools over OpenRouter, and the whole engine has no idea which of two front ends is driving it: Assessment is a plain object with no I/O, which is what lets a FastAPI/Next.js web app and a Streamlit fallback share one Python core with zero divergence between them.
Golden-set retrieval precision@3 lands at 0.93, tool-selection accuracy at 1.00, and RAGAs faithfulness at 0.84 against a 0.80 target.
The faithfulness score didn't clear its bar on the first attempt — it opened at 0.57. The cause was not the model failing; it was a system prompt telling it two things at once: “ground every claim in the excerpts” beside “be concrete — name artifacts, quantities, and who decides.”
When the excerpts named no decider, the model resolved the contradiction by inventing one — a fabricated owner, a fabricated headcount — printed beside genuine citations where a reader couldn't tell them apart. The fix wasn't a bigger model; it was making concreteness conditional on what the excerpts actually said.
Ten real bugs surfaced this way over the build, and eight of them were invisible to a fully green offline test suite — caught only against the real vector store, the real model, or a rendered page. The lesson that survived every one of them: a passing test suite is not evidence the real thing works.
1,342 offline tests, 175 browser tests, zero failing
A meaningful slice of that count exists only to forbid things: that the grading module can never import a Judgment type (so a standalone score can never quietly grow an opinion), that no Streamlit import reaches the logic layer, that a document-grading feature never emits a status it isn't allowed to emit.
The stage is never decided by the model — a deterministic state machine owns it, full stop. The verdict is derived, never generated.
Prompt-injection and bulk-extraction attempts are refused before a cent is spent, and a canary phrase is checked so the knowledge base itself can't be recited back wholesale — a real near-miss during the build recited 4,238 characters of it, caught by a review that had nothing to do with jailbreak testing at all.