Spaces:
Runtime error
Runtime error
Team Plan v2 β Contract Obligation & Risk Extractor (Challenge 03)
Supersedes the original TEAM_PLAN.md. Same strategy, four amendments β and a walking skeleton already built in this repo, so hackathon day starts from a running end-to-end system, not a blank page.
What already works (pre-hackathon skeleton)
- β
Full pipeline: PDF β clauses β categories β obligations β key dates β
ranked risks (
backend/app/pipeline.py, CLI + FastAPI). - β
Click-to-source: ingestion records word-level offsetβbbox index; the React
- pdf.js UI highlights the exact clause on click. Verified live.
- β Derived deadlines: "90 days prior to term end" β notice-by 2029-04-01 with countdown + urgency tiers.
- β
Risk engine with baseline library (
baselines.json): uncapped liability, auto-renewal traps, one-sided termination, slow breach notice, exclusivity, sole-remedy SLA, high late interest, assignment asymmetry. - β CUAD eval harness with real numbers: keyword classifier baseline = 0.50 macro-F1 over 8 categories on 50 contracts (audit 0.66, assignment 0.64, insurance 0.59; termination precision is the known weak spot).
- β
Open-source-only LLM layer (
CORE_LLM_BACKEND=ollama|rules), LLM obligations grounded back to source sentences. Entire dependency tree is MIT/BSD/Apache β commercially safe. - β Demo MSA generator seeded with every risk pattern.
- β
Hosted-product layer: single Docker image (backend + built frontend +
Tesseract OCR),
docker compose updeploy, shared-password login (APP_PASSWORD), analyses persist across restarts. - β
Real database backend: normalized SQLAlchemy schema (contracts,
clauses, obligations, key_dates, risks, defined_terms) with PDFs as blobs.
PostgreSQL in compose (pg8000 driver β BSD, not LGPL psycopg), SQLite
zero-config fallback. Portfolio queries are SQL.
pg_dump= full backup. - β Scanned-PDF OCR: no text layer β automatic Tesseract pass; word boxes come from the OCR engine so click-to-source still works on scans. Verified: the rasterized demo MSA yields identical results (26 obligations, 10 risks).
- β Exports: Excel register (Summary/Obligations/Key dates/Risks sheets) and .ics calendar of computed deadlines with 7-day reminders.
- β Portfolio dashboard: all deadlines + worst risks across every uploaded contract, each row deep-linking to the source clause. The roadmap slide's first item, already working.
Amendments to the original plan
- Open-source only β this is a commercial product. No proprietary model
APIs at all. Extraction runs on
rules(always works, zero models) orollamawith Apache-2.0 weights (defaultqwen2.5:7b;mistral:7balso Apache-2.0 β avoid Llama-family weights, the Meta licence has commercial conditions). The PDF stack is pdfplumber (MIT) + reportlab (BSD) β deliberately not PyMuPDF, which is AGPL and would poison a commercial product. Full licence audit in README. The rule engine is the demo safety net: if the local model is slow on venue hardware,CORE_LLM_BACKEND=rulesstill produces the entire register + risk list. Pre-pull Ollama models before the day β venue Wi-Fi will not download 5 GB. - CUAD models are extractive QA, not classifiers. The HF "CUAD model" asks
one question per category and returns spans. Plan the upgrade as either
(a) per-category QA over chunks (spans double as traceability), or
(b) a LEDGAR-trained classifier. Whoever owns classification should
prototype this BEFORE the hackathon. The interface to swap is one function:
classification.classify_clause. - No character offsets in the frontend. Ingestion ships
{page, rects[]}per span; the viewer draws overlay divs. Already built β don't reintroduce offset math in the UI. - Walking skeleton first. Done (this repo). Hackathon-day "integration"
means each owner replacing their module behind
schema.py, which stays frozen after the kickoff huddle.
Hackathon-day work split (on top of the skeleton)
| Owner | Upgrade path |
|---|---|
| Tech Lead / Integrator | repo, model serving, schema.py freeze, end-to-end runs every hour, demo runner |
| Extraction core | LLM extraction quality: prompts, few-shot from CUAD, condition/trigger splitting, confidence calibration |
| Classification | replace keyword classifier with CUAD-QA or LEDGAR model; target macro-F1 β₯ 0.7 on the harness |
| Risk engine | extend baselines.json from CUAD norms; severity calibration; explanation quality |
| Segmentation/defined-terms | harden on 10 real CUAD PDFs (messy numbering, definitions cross-refs) |
| Date logic | more derivation patterns (cure periods, payment cycles, milestone chains) |
| Eval | raise category coverage, tune threshold, produce the accuracy slide (before/after classifier swap) |
| Data/demo/story | pick 5β10 CUAD demo contracts (need: auto-renewal + uncapped liability), broken-input tests, "who built what" slide, rehearse 3+ presenters |
Day-of timeline (revised)
| Time | Phase |
|---|---|
| 0:00β0:45 | Huddle: freeze schema.py, assign modules, pick demo contracts, verify models pulled |
| 0:45β2:30 | Module upgrades in parallel β skeleton keeps running throughout |
| 2:30β3:00 | Checkpoint: full end-to-end on a real CUAD contract; ollama vs rules call |
| 3:00β5:00 | Quality push: classifier swap, risk library, extraction prompts |
| 5:00β6:30 | Eval numbers final; UI polish; multi-contract demo set loaded |
| 6:30β7:30 | Demo hardening, slides, 3+ presenter dry run |
| 7:30β8:00 | Buffer + final rehearsal |
Definition of Done (unchanged, all already β on the skeleton)
- Pipeline runs on a real contract β register + ranked risks + traced spans
- UI: upload β click an item β correct clause highlights in the PDF
- Eval prints precision/recall/F1 against CUAD labels
- Broken input (corrupt/empty/scanned PDF) β graceful error
- Full demo dry-run in the time box, 3+ presenters
Post-hackathon product roadmap (the Deployability slide)
Portfolio view across hundreds of contracts β calendar/email alerts on computed deadlines β confidence-driven human review queue (lawyer corrections feed the baseline library) β amendments/versioning β audit log β SSO/RBAC.