Inspiration

SME owners sign dozens of contracts a year and rarely reread them — until an auto-renewal slips past, or an uncapped liability clause bites. Most "AI contract review" tools paper over uncertainty with confident-sounding prose. We wanted the opposite: a tool that shows its work down to the exact quote and page, and cleanly says "I don't know, ask a lawyer" the moment a question stops being a readable fact and starts being a judgment call.

What it does

Upload a folder of signed contracts (PDFs, Word docs, even scans) and get: extracted key terms — parties, renewal/notice dates, liability caps with carve-outs, exclusivity clauses, payment terms — each traced to a verbatim quote and page; a forward 90-day calendar with anything already missed shown loudest; cross-contract conflict detection (overlapping exclusivity grants, contradicting confidentiality obligations); and a RED/YELLOW/GREY risk flag per issue, assigned by deterministic rules (never the LLM), with a lawyer-ready handoff brief for anything that needs one. Every fact is viewable in plain English or full legal register from the same underlying data — never regenerated twice.

How we built it

FastAPI + Neo4j + React, with an LLM (gemma4:31b via Ollama Cloud via LangChain) doing extraction only. Every extracted value is a small provenance object (value, verbatim_quote, page, basis, confidence) that can only be marked "explicit" once a verification step independently re-locates the quote in the actual source text. A separate, pure-Python rule engine — zero LLM calls — reads only verified facts and decides risk tiers; the LLM's only remaining job is phrasing the explanation of a decision already made. OCR runs through an OpenRouter-first, Tesseract-fallback pipeline that propagates page quality into fact confidence. Ask/Q&A uses hybrid retrieval: a real Cypher query for structured questions, semantic search as fallback.

Challenges we ran into

Keeping judgment strictly separate from generation broke in a subtle way we had to catch and fix with a regression test: a "grounding gap" override was initially using the wrong precedence logic, which could have let a low-confidence rule present as confidently RED. Separately, a single silent schema gap — a Cypher filter evaluating to NULL instead of false for nodes missing one property — invisibly broke our entire Q&A feature; it only surfaced by actually using the app end-to-end, which reshaped how we spent our remaining testing time.

Accomplishments that we're proud of

A real, live, end-to-end pipeline (not a scripted demo path) that we ran against six hand-crafted contracts including an amendment chain, catching and fixing roughly twenty real bugs along the way. GREY (the "I can't confidently evaluate this" tier) is a designed, tested, standalone output — we even built a small script whose job is to flag it as suspicious if refusals ever stop happening across a corpus.

What we learned

The most dangerous bugs in a trust-critical system are silent ones — nothing here threw an error, yet a traversal filter quietly excluded a whole node type, and an idempotency bug quietly duplicated findings. Only end-to-end use, not unit tests alone, caught them — which changed how we prioritized the rest of our build time.

What's next

Anchor "which party is my business" explicitly across documents (currently re-guessed per-document, and can invert on non-standard contract framing); curate a real, human-verified legal authority pack; live-verify the OCR path against a real scanned document; and calibrate our confidence threshold against a labelled sample instead of a documented default.

Built With

Share this project:

Updates