Inside `sp2816/contract-intelligence-risk-scoring`: The Open-Source Contract Triage Engine That Scores Risk Clause by Clause

A legal-tech stack that does more than summarize. It extracts clauses, scores exposure, and keeps the evidence trail visible from OCR to dashboard.

8 to 10 min read • View on GitHub • More from sp2816

A legal contract is being broken into smaller clause fragments that feed a dashboard with risk indicators and an evidence trail. The scene explains that the project does not just summarize text. It turns a document into structured review artifacts that can be inspected and scored.
The core move is not summarization. It is decomposition into clauses, entities, and a risk report that can be audited.
Key Takeaways

Contracts Become Evidence, Not Just Text

Most contract AI tools start with a promise of speed. This one starts with a promise of structure. The interesting output is not a single summary sentence, but a chain of artifacts: the contract, its clauses, extracted entities, confidence scores, and an aggregated risk report.

That matters because legal review is not really about reading faster. It is about knowing what changed, what is missing, and why a specific sentence deserves attention. The repo is built around that reality, so the UI can point back to the underlying evidence instead of asking the reader to trust a black box.

The pipeline is not one model doing everything. It is a sequence of small transformations that preserve evidence as the document moves toward a risk score.

The Data Model Is the Product

The architecture makes its intent obvious in the model layer. The repo is not storing files and hoping for magic later. It is storing the things a reviewer would actually need to inspect: contracts, clauses, entities, and a rollup report.

# Simplified shape of the core data model
class Contract:
    id: int
    filename: str
    risk_score: float
    status: str

class Clause:
    contract_id: int
    text: str
    confidence_score: float
    risk_level: str

class Entity:
    clause_id: int
    entity_type: str
    value: str

class RiskReport:
    contract_id: int
    high_risk_count: int
    medium_risk_count: int
    low_risk_count: int

That structure is what makes the deeper review experience possible. A high-risk flag is not just a label. It is attached to a clause, which can be tied back to extracted entities and displayed in context. For a legal reviewer, that is the difference between a demo and a tool.

LayerWhat it storesWhy it matters
ContractFile metadata and overall scoreProvides the top-level object for the dashboard
ClauseSentence or segment, plus confidence and riskMakes the explanation trail specific
EntityNames, terms, jurisdictions, and similar signalsTurns vague language into searchable facts
RiskReportAggregated counts and rollup metricsLets the UI present a decision-ready summary

How a Document Moves Through the Pipeline

The pipeline is deliberately modular. The repo separates ingestion, text normalization, clause segmentation, entity extraction, classification, and aggregation. That is a practical design choice, not a research flourish.

A scanned contract page and a clean digital PDF both feed into the same analysis pipeline. The scanned page first passes through OCR, while the digital PDF bypasses OCR and moves directly into text normalization. The visual explains that the system is designed to handle real-world file quality, not just pristine documents.
Born-digital and scanned documents take different routes at the start, then converge before clause extraction and scoring.

That hybrid path is important. Contract work is full of ugly input files, especially older scans and exhibits. A system that only works on clean text PDFs is fine for a prototype. A system that accepts both formats starts to feel like something an operations team could actually live with.

# Conceptual pipeline shape
contract -> detect_type()
         -> if scanned: ocr()
         -> normalize_text()
         -> extract_clauses()
         -> extract_entities()
         -> classify_clause_risk()
         -> aggregate_risk_report()
         -> render_dashboard()

Why the Mock Chatbot Matters

The chat layer is easy to dismiss because it is currently a mock. That misses the point. The response structure already assumes a future retrieval layer, which means the product is being shaped around structured contract objects rather than free-form prompting.

In practice, that is a better foundation than a chatbot-first design. The system can answer questions later because it has already organized the underlying evidence now. The mock layer is a placeholder, but it is a disciplined one.

The Least Glamorous Feature Is Also the Smartest

`auto_migrate_schema` is the kind of feature that rarely gets a headline and often gets a lot of gratitude. Instead of making contributors manage schema drift by hand, the app inspects the SQLite table definition at startup and adjusts the database to match the models.

def auto_migrate_schema(app):
    # inspect existing SQLite columns
    # compare with SQLAlchemy models
    # apply ALTER TABLE updates when needed
    pass

That choice says a lot about the repo’s priorities. It is trying to be low-friction, demoable, and easy to extend. In other words, it behaves like a product someone wants others to run, not just code someone wants others to admire.

Born-Digital PDFs, Scans, and the Real World

This is where the project becomes less tidy and more credible. Hybrid OCR support is not a nice-to-have in legal work. It is the difference between handling modern contracts and handling the actual archive of business reality.

A lot of document AI tools look impressive when the input is already pristine. The harder test is the one this repo seems to anticipate: faxed amendments, scanned exhibits, mixed-quality PDFs, and files that were never meant to be machine friendly in the first place.

Where It Sits in the Market

The competitive split is clear. Commercial CLM and contract intelligence platforms offer polished workflows, integrations, and enterprise support. Generic legal chatbots offer convenience. Open-source document analyzers often stop at extraction.

ApproachOutputExplainabilityDeploymentBest fit
Generic legal chatbotNatural-language answersLow to mediumUsually SaaSQuick review assistance
Commercial CLM suiteWorkflow automation plus analyticsMediumEnterprise SaaSLarge legal and procurement teams
Open-source document analyzerExtracted text or fieldsMediumOften self-hostedParsing and search
This repoClause-level risk scoring with evidence trailHighLocal-friendly Flask and SQLiteBuilders, internal tools, and explainable triage

The differentiator is not AI in the abstract. It is structured, traceable risk scoring in a stack that is easy to run locally. That combination is rarer than it should be.

What This Repo Is Really Optimized For

This is a builder’s legal-tech stack. It favors modularity over flash, explainability over mystique, and setup simplicity over enterprise ceremony. That makes it valuable as a reference implementation even if it is not yet a household name.

If you want a contract product that can justify its own warnings, this repo points in the right direction. It does not just tell you a clause is risky. It shows you the route the document took to get there.