Contract intelligence that stays inside your walls
Clause extraction, risk analysis, plain-English rewrites, a planner-driven agent pipeline with faithfulness verification, a portfolio knowledge graph, and negotiation drafting — with every model call routed by sensitivity tier.
No account needed in local development. Runs with zero model credentials.
How it works
Upload to verified result, in five stages
Each stage is a live endpoint with an honest degradation path when a dependency isn't reachable — the knowledge graph no-ops, the NLI head falls back to lexical overlap, generation raises a clear error.
- 1
Upload
PDF, DOCX, TXT, or a scanned image. Extraction is fully local — PyMuPDF, python-docx, and Tesseract OCR fallback. No cloud Document AI.
- 2
Classify
A rule-based classifier assigns one of four sensitivity tiers. The tier is what the Model Router's Class-C gate keys on for the rest of the document's life.
- 3
Extract
Segmentation → typed ClauseObjects: deontic modality, defined terms, cross-references, entities, temporal expressions, ambiguity flags. Rule-first, GLiNER where enabled.
- 4
Analyse
A planner decides which agents to run. Risk radar, timeline, knowledge-graph conflict checks, negotiation redlines, cross-document consistency — only what the document needs.
- 5
Verify
Every generated summary and answer is entailment-checked against its sources by an NLI head. Contradicted or unsupported claims are surfaced, and can route the run to a human.
8
delivery phases, each deployable
40+
API endpoints, all typed
400+
backend tests, green
4
sensitivity tiers, enforced end-to-end
0
model credentials required to run
Everything runs against the real document
Not a demo. Every capability below is a live endpoint with an honest “knowledge graph offline” state when a service isn’t reachable.
Structured clause extraction
Every clause typed and tagged — deontic modality, defined terms, cross-references, entities, temporal expressions, ambiguity flags. Rule-based first, neural where it earns it.
Risk radar
Keyword + contextual detection across eight categories, aggregated into a spider chart with clause-level drill-down. Uncapped liability, unilateral termination, one-sided arbitration.
Grounded answers
Ask anything about a contract and get an answer checked against the actual text by an NLI entailment head — unsupported claims are surfaced, not hidden.
Planner-driven agents
A pipeline that decides which agents to run, researches flagged clauses, checks the knowledge graph for conflicts, and verifies its own summary before you see it.
Portfolio knowledge graph
Defined terms linked across documents, candidate cross-document conflicts, bitemporal version history — explore it as an interactive graph.
Negotiation drafting
Clauses compared against your organisation's preferred language, with a redline diff and rationale. Every suggestion is pending review — nothing is auto-applied.
Architecture overview
Seven layers, each replaceable without touching the others
Self-hosting is the spine, not a top-up. The domain quality comes from retrieval, the knowledge graph, fine-tuned heads, and the verifier — not from model scale.
Client
A client-rendered Next.js SPA against a separate FastAPI origin. Auth optional.
API
Thin route → service modules, every route behind one guard: auth, rate limit, audit.
Model Router
Every AI call names a task, never a model. Class A/B/C providers, self-hosted-first chains, an import-linter contract.
Pipelines
Rule-first NLP + CV turn flat text into a structured ClauseObject graph.
Agents
A planner-driven LangGraph: extraction → planner → dispatch → verifier. DBOS durable execution optional.
Knowledge & retrieval
Memgraph or embedded KùzuDB, plus hybrid RAG — dense + sparse + graph fused by RRF.
Data
Postgres or SQLite, Redis, content-addressed blobs. Documents, audit log, traces, eval runs.
Privileged text never leaves the perimeter
Every document is classified public, internal, confidential, or privileged on upload. The Model Router fails closed: confidential and privileged documents are structurally unable to reach an external provider, and a PII redaction gate masks identifiers before any Class C call.
- Regex + NER redaction gate before every external dispatch
- SHA-256 egress audit trail — what left, never the payload
- Air-gapped build excludes the commercial provider package entirely
- Per-key and per-user RBAC with a full audit log
# routing decision
task clause_rewrite
sensitivity privileged
candidates [local-llm, local-llm-large]
class_c_candidates dropped: gemini (tier not permitted)
→ resolved: local-llm-large (self-hosted)
AI pipeline
A pipeline that decides what to do, then checks its own work
A document with no risk or ambiguity signal runs just extraction → planner → verifier. The verifier can fail the run: a fabricated citation, a KG conflict, or an unsupported claim sets needs_human_review and drops it into the review queue.
extraction
Builds the ClauseObject graph — always runs.
planner
Rule heuristics or an LLM plan pick the node set. Falls back to rules on any error.
risk / compliance
Keyword sweep + KG conflict lookup for every defined term used.
research
Hybrid RAG, but only for clauses already flagged by risk or ambiguity.
summary
The one generating node — asks the model to cite retrieved sources by [N].
verifier
Citation validity + KG conflicts + real NLI faithfulness. The mandatory release gate.
Knowledge graph
Your portfolio as a graph, not a folder of PDFs
Defined terms are extracted per document, then linked across the portfolio only when both the alias text and the defining context match. Candidate cross-document conflicts surface obligation/prohibition pairs that share a term.
Per-document terms, portfolio links
"the Company" in two unrelated contracts is not auto-merged — linking needs matching context, not just matching text.
Candidate conflicts
Cross-document obligation vs. prohibition on a shared term — flagged for review, never asserted as a confirmed conflict.
Bitemporal versioning
Transaction time and valid time on every Document/Clause node. Ask what a term meant as of a past date.
Two backends
Memgraph over Bolt, or an embedded KùzuDB with no server at all — the single-binary profile.
Risk analysis
Eight categories, keyword and contextual, drill-down to the clause
A rule-based keyword sweep is the always-on floor; an AI pass adds contextual detection. Results aggregate into a spider chart on the Risk Dashboard, and every point drills into the exact clauses that drove it.
Section 10 — indemnification not subject to any limitation of liability
Negotiation agent
Every clause checked against your playbook — nothing auto-applied
The org configures preferred language per clause type. The agent flags any deviation (not a similarity threshold — a governing-law swap from California to Delaware scores 0.90 on difflib yet is maximally different in effect) and produces a redline. Every suggestion is pending_review.
Governing law — deviation
− governed by the laws of the State of Delaware
+ governed by the laws of the State of California
Evaluation framework
A model only becomes the default when a gate proves it earns it
The cutover gate runs a task's graded eval bound to the external baseline vs. the self-hosted candidate. passed = candidate ≥ baseline × ratio. A task routes to the self-hosted default only on a PASS — and the result is written to the eval_runs table for regression attribution.
Fast lane
Pure-stdlib gold-set checks, CI-gated on every push — clause type, deontic tags, faithfulness.
Graded lane
LegalBench (CUAD / ContractNLI) + MNLI loaders, SQuAD-F1 / macro-F1 metrics, no sklearn.
Cutover gate
Per-task meet-or-beat-baseline. "We chose not to ship this model" is a CI-enforced invariant.
Research contributions
Five directions with potential patent value
Each has a validated CPU prototype or a concrete design. What stays open is GPU training and the formal prior-art / patent-counsel work — both are marked as such, not hidden.
Deontic graph attention
A GAT over an Obligation graph for cross-document conflict detection. Architecture designed; GPU training open.
Temporal obligation simulation
Auto-derive downstream dates from "N days after <trigger>" patterns. CPU prototype validated against hand-modelled scenarios.
Legal-semantic fingerprinting
Contrastive clause embeddings with verified hard negatives — modal swap, negation, magnitude shift. 122 triplets built; fine-tune GPU-blocked.
Adaptive negotiation playbook
Procedural memory of negotiation history. Static-preference first step shipped; the full vision needs redline history.
Deontic-structure-aware ablation
Explain a risk prediction by perturbing one legally-meaningful span at a time. Corroborated the risk model learned superficial n-grams.
Screenshots
The workspace, the trace, the router
Previews render from the live design system — they track the current theme and never go stale.
needs_human_review: KG conflict
Technology stack
Everything self-hostable, nothing that phones home by default
Backend
FastAPI · Pydantic · SQLAlchemy · Postgres / SQLite · Redis
AI orchestration
LangGraph · DBOS · a declarative Model Router · import-linter
Models
Qwen3-8B/14B (Ollama / vLLM) · bge-m3 + bge-reranker (TEI) · DeBERTa NLI · GLiNER
Retrieval & graph
Hybrid RAG (RRF) · rank-bm25 · FAISS · Memgraph / KùzuDB
NLP / CV
regex-first pipeline · dateparser · PyMuPDF · OpenCV · Tesseract
Frontend
Next.js · TypeScript · Tailwind · TanStack Query · React Flow · Recharts
Eval & training
Inspect AI · LegalBench · MLflow · DVC · Argilla
Observability
OpenTelemetry · a SHA-256 egress audit trail · per-call routing logs
Roadmap
Eight phases shipped, each one deployable
No phase left the system in a broken state. What isn't done is either the next phase or explicitly blocked on hardware or a human — both are called out.
V1 hardening · FastAPI re-platform · CPU NLP/CV · knowledge graph + hybrid RAG · planner-driven agents with the NLI verifier
shippedProvider-agnostic Model Router · self-hosted embeddings/rerank · Gemini demoted to a Class-C plugin
shippedSelf-hosted generation target (Qwen3-8B/14B) · graded eval harness + cutover gate · GLiNER NER · NLI head
shippedSensitivity tiering enforced end-to-end · PII redaction gate + egress audit · RBAC · air-gapped packaging · KùzuDB · DBOS · memory service · first SPA
shippedBitemporal graph versioning · consistency + simulation baselines · negotiation agent · risk dashboard + KG explorer · five NOVELTY prototypes
shippedMulti-tenant scale · SOC 2 / GDPR workflows · streaming agent trace over WebSocket · Negotiation Studio
nextGPU-dependent
Fine-tuned clause-type + deontic heads, the contrastive embedding model, and the Deontic-GAT training all need a card this project doesn't have. Prototypes and pipelines are verified via dry-run / smoke.
Infrastructure-dependent
A legal expert to adjudicate weak labels in Argilla, and qualified patent counsel for the prior-art searches. Everything up to the human step is built.
Why this platform
Four decisions that shaped it.
It runs disconnected
The air-gapped build excludes the commercial-provider package entirely. Structure, retrieval, the knowledge graph, agents, and sensitivity classification are all CPU-fine; generation runs on a 16 GB card or a small CPU model.
The verifier can fail
Every agent summary and every grounded answer is entailment-checked against its sources. Contradicted or unsupported claims are surfaced — the product tells you when it isn't sure.
Model choices are gated
A task only becomes self-hosted-by-default when a cutover gate proves the local model meets or beats the external baseline. "We chose not to ship this model" is a CI-enforced invariant.
Nothing is auto-applied
Negotiation redlines, sensitivity overrides, and flagged analyses all route through a human. The review queue is a real queue, not a documented intention.
About
A serious engineering project, documented in the open
Built solo across eight phases, with a 60-plus-entry append-only engineering journal recording every decision and every dead end.
About the project
Why it was built, the design philosophy, the architecture decisions, the phase progression, and what’s next.
About the developer
Shourya Tiwari — the skills this project exercised and what it taught along the way.
Documentation
Concepts you’ll meet in the product, and the repository docs that go deeper.
Frequently asked
Open the workspace
Upload a contract, or start with the sample NDA, and see clause extraction, the risk radar, the agent trace, and the knowledge graph run against it.