Vendor and contract documents into structured, evidenced, risk-scored decisions. Replaces $100K/yr SaaS (Vendr, Ironclad) with a self-hosted policy engine, human-in-the-loop queue, and immutable audit log.
Every B2B company onboarding a vendor hits the same pile of unstructured documents โ W-9s, certificates of insurance, SOC 2 reports, MSAs, NDAs, invoices, POs. Today that work is done manually in spreadsheets or with six-figure SaaS tools. The cost of doing it badly is real: expired COIs slipping into procurement, MSAs auto-renewing with liability caps below the policy floor, invoices paid against the wrong rates, vendor risk discovered only after something has gone wrong. This is the platform pattern underneath.
PDF, DOCX, and plaintext upload. SHA-256 content hash is the dedupe key โ a (tenant_id, content_sha256) unique constraint absorbs re-uploads at the DB layer so business logic never sees them.
Documents are routed to typed extractors (W-9, COI, MSA, Invoice). Every extracted field carries page number, bounding-box, and character offsets pointing back to the actual text โ no synthetic confidence, no "trust me."
Six validation rule types (presence, format, range, expiry with first-class time tokens like `now+30d`, cross-field, list-membership) run as a single pass. A composite confidence score combines completeness, validation pass rate, and per-field extractor confidence.
A small DSL (if liability_cap < $1M and contract_value > $100K then route_to_review with reason=โฆ) evaluates top-to-bottom, first match wins. Auto-approve, route-to-review, and reject are first-class outcomes.
Anything routed to review lands in a steward queue. Every decision (extract, validate, score, route, approve, reject) appends to a hash-chained audit log within the same DB transaction as the action itself.
Every field carries page+bbox+char-offsets from the actual document text. Reviewers can jump to the exact span; downstream systems can verify provenance. No "0.87 confidence" floating in space.
Extractor implementations are heavier โ they must preserve coordinates through the parsing pipeline. Pays back the first time anyone disputes a field.
Parse โ classify โ extract โ validate โ score โ policy โ audit all share one session.commit(). If any stage fails, the entire chain rolls back โ no half-processed documents in the database.
Long-running LLM calls inside the transaction need careful timeout management. Worth it for the all-or-nothing guarantee.
Full demo runs with zero API keys via deterministic fixture-anchored extractors. The LLM extractor is a swappable Phase-3 stub โ the platform shape is locked in before the model dependency is.
Mock extractors lag real LLM accuracy until swapped. Acceptable as a portfolio-and-staging story.
The DSL is purposely small โ domain-readable. Procurement leads can review and propose policies without a PR cycle; engineers approve the merge.