Objective
Contractual obligations — a renewal notice, an SLA report, a payment trigger — are buried in prose when they should be a queryable structure. This recipe models obligations as a graph so "what is due before October?" is one query across the whole book instead of a manual read.
Step 1: Model a contract and its obligations
MERGE (c:Contract {id: "MSA-2026-14", counterparty: "Acme"})
MERGE (o1:Obligation {id: "OB1", trigger: "renewal notice", deadline: "2026-09-15"})
MERGE (o2:Obligation {id: "OB2", trigger: "SLA report", deadline: "2026-12-01"})
MERGE (c)-[:HAS_OBLIGATION]->(o1)
MERGE (c)-[:HAS_OBLIGATION]->(o2);
Step 2: What is due before a date?
MATCH (c:Contract {id: "MSA-2026-14"})-[:HAS_OBLIGATION]->(o:Obligation)
WHERE o.deadline < "2026-10-01"
RETURN o.trigger AS due_soon, o.deadline;
Result — the renewal notice surfaces; the December SLA report does not:
| due_soon | deadline |
|---|---|
| renewal notice | 2026-09-15 |
Why it matters
Obligations become structured data you can query, alert on, and roll up across the portfolio — no missed renewal because it was buried on page 40. Feed the obligations from clause-risk review, and keep the review itself on a tamper-evident audit. To extract a contract into a graph automatically, see contract extraction.