Live at fact.gateshub.company. I built it to prepare the FACT IEC accreditation submission at the Gates Biomanufacturing Facility (GBF): our own submission, the one this crosswalk has to survive.
The problem
FACT-JACIE accreditation is how cell therapy programs prove they're safe to run. For immune effector cells (the CAR-T family), the standards run to 1,701 across four chapters: scope and definitions, clinical program, apheresis collection, and product processing. 718 of them carry additional Accreditation Manual expectations that spell out what an inspector actually wants to see.
Your evidence is a pile of SOPs, policies, forms, and training records written over years by different people. The accreditation question is simple and brutal: for each standard, which document proves compliance, and where?
By hand, that crosswalk is a grinding read: every document against every standard, over and over. Doing it with a chatbot would take an afternoon and produce something worse than nothing: the standards spine alone runs about 200K tokens, more than a chat window holds before you add a single document, so the model fills what it can't see with confident-looking coverage claims no document actually supports. An inspector finds those. That's the failure mode FACT-Codex is built against.
The whole point is the refusal
In regulated science, a plausible answer that's subtly wrong is worse than no answer. A gap you know about is a work item. A gap hidden behind an optimistic AI summary is a deficiency you discover during the inspection.
So FACT-Codex is engineered to say "no match" and mean it:
- Four verdicts, and the weak ones are honest. Every coverage claim is one of
fully_addresses,partially_addresses,referenced_only, orno_match. "The SOP mentions this topic" is not coverage. It getsreferenced_only, and the dashboard treats it as a gap. - Confidence is mandatory. Every coverage claim and every finding carries a 0.0–1.0 confidence score. The review contract requires the model to label anything below 0.7
expert_review_requiredrather than assert it, and on findings, that flag is a structured field in the output, not just a line of prose. - No fabrication, by instruction and by structure. The review prompt is explicit: if the SOP doesn't say it, it isn't there. Note it as a gap. Validation protocols, release criteria, equipment names, staff titles: the model may not invent any of them. Missing information becomes a "question for the author," not a guessed answer.
- Evidence must point somewhere. A coverage claim has to cite where in the SOP it's addressed (section and paragraph) and list the specific expectation sub-elements that are still missing. A claim with no location is not a claim.
- Even overclaiming by volume gets flagged. The gap rollup buckets every expectation as untouched, weak, or covered, and separately flags
over_coveredexpectations that accumulate three or more full-coverage claims. Redundant claims are a review smell too.
The result reads differently from most AI output. It says "I don't know" a lot. That's the feature.
How it works
- The standards become a spine. The FACT-JACIE IEC Third Edition standards and Accreditation Manual are parsed into a structured crosswalk (1,701 standards with their manual expectations attached) that every review scores against. The licensed source PDFs stay out of the repo; only the derived structure ships.
- A document goes in. Upload an SOP, policy, plan, or form (.docx, .pdf, or .xlsx) or paste plain text directly. The extraction layer normalizes all of it.
- Two independent reviewers read it. When both are configured, a Gemini model reads original PDFs multimodally (layout, tables, signatures) while a Claude model with a 1M-token context window holds the entire standards spine and the document in one pass. (.docx uploads fall back to extracted text for the multimodal read.) Two models, two failure modes, two independent reads a human reviewer can compare.
- Per-expectation coverage rows come out. Each (standard, expectation) pair the document touches gets a verdict, a confidence score, an in-document citation, and a list of missing elements. Findings are graded deficiency / variance / suggestion, each with a concrete remediation, and the review as a whole carries one inspector-risk rating.
- A human owns the decision. The dashboard shows every standard with its manual expectation inline, the mapped evidence beside it, and a status the responsible person sets: gap, draft, approved, effective (plus superseded for retired documents; untouched rows sit at unmapped). AI review informs the status. It never is the status. AI output is not treated as approved compliance language: that line is in the project's own working rules.
What the dashboard shows
The main view is the whole crosswalk: every standard, its manual expectation, its mapped evidence, and its status, filterable by chapter and state. KPI cards total the mapped and gap counts (gaps counted as loudly as wins). Click any row and a drawer opens with the full standard text, the expectation, the evidence checklist, and the owner/notes fields where the human decision gets recorded.
When the AI has reviewed documents against a standard, the mapped-evidence column links straight to the source SOPs. The auto-derived status is deliberately conservative: only a fully_addresses verdict promotes a row past "gap," and a human override beats it either way.
Trust boundaries
Clerk handles per-user authentication, with row-level security in Postgres set up the way an accreditation team actually works: every approved user sees the whole crosswalk, a shared map nobody works blind on. The crosswalk decision rows (status, owner, notes) are team-editable, because accreditation prep is shared work, and every edit is stamped server-side to the user who made it. Mutating or deleting the underlying records (SOPs, reviews, evidence items) is owner-or-admin only. Original document bytes live in private blob storage and are only served through an authenticated proxy: evidence files never get a public URL. Copyrighted FACT source material stays out of the codebase. The working rules bar patient-identifiable information from the workspace.
Stack
Static frontend on Vercel, serverless review endpoints, Neon Postgres with row-level security, Clerk authentication, private Vercel Blob for document storage. Reviewers: Gemini 3 Pro (multimodal) and Claude Sonnet 4.6 with a 1M-token context window. The spine is a JSON derivative generated from the licensed standards by a local tool.
What it demonstrates
The interesting engineering here isn't the AI call. It's the contract around it: a closed verdict vocabulary, mandatory confidence with a refusal threshold, required citations, structured gaps instead of invented answers, and a human status field the model can't touch. That's what it takes to put a language model next to a regulatory process and have it help rather than hurt.