Legal: Contract Logic Conflicts¶
Case study β legal
Contracts are logic systems. Treat them like logic systems.
Long agreements hide conflicts because obligations and exceptions are far apart. Chat summaries can be fluent while structurally wrong.
The question¶
How do we surface contradictions in long contracts where obligations and exceptions are far apart?
Why chat summaries fail¶
Structure is the point
Contracts are not prose; they are conditional rules with scope and precedence.
Conflicts are non-local
Clause A can silently contradict Clause B across sections and appendices.
No trace, no accountability
You need clause references and logic links, not just a summary paragraph.
Graph representation¶
Model clauses as nodes and dependencies/conflicts as edges.
This makes contradictions computable and reviewable.
flowchart TB
%% Styles (brModel Standard)
classDef i fill:#D3D3D3,stroke-width:0px,color:#000;
classDef p fill:#B3D9FF,stroke-width:0px,color:#000;
classDef r fill:#FFFFB3,stroke-width:0px,color:#000;
classDef o fill:#C1F0C1,stroke-width:0px,color:#000;
classDef s fill:#FFB3B3,stroke-width:0px,color:#000;
I_Doc(["π Contract + exhibits"]):::i
I_Def(["π Definitions section"]):::i
I_Jur(["βοΈ Jurisdiction / governing law"]):::i
P_Seg("βοΈ Segment into clauses"):::p
R_Cla(["π Clause objects<br>(id, text, section)"]):::r
P_Ent("π·οΈ Extract entities, terms, modalities"):::p
R_Terms(["π Term graph<br>(definitions + aliases)"]):::r
G_Def{"Definitions resolved?"}:::s
S_AskDef(["π Ask for clarification / missing definitions"]):::i
P_Link("π Link references + cross-refs"):::p
R_CG(["πΈοΈ Clause graph<br>(references, scope)"]):::r
P_Prec("π Build precedence + exception hierarchy"):::p
R_Prec(["π Precedence map<br>(overrides, carve-outs)"]):::r
G_Prec{"Precedence clear?"}:::s
P_Check("π§ͺ Evaluate obligations vs prohibitions"):::p
R_Conf(["β οΈ Conflict candidates<br>(with clause paths)"]):::r
G_Mat{"Material risk?"}:::s
O_Out(["β
Review pack<br>(issues + suggested edits)"]):::o
S_Esc(["π Escalate to counsel review"]):::i
R_Tr(["π§Ύ Trace bundle<br>(clause paths + conditions)"]):::r
I_Doc --> P_Seg --> R_Cla --> P_Ent --> R_Terms --> G_Def
I_Def --> P_Ent
I_Jur --> P_Prec
G_Def -->|"no"| S_AskDef --> R_Tr
G_Def -->|"yes"| P_Link --> R_CG --> P_Prec --> R_Prec --> G_Prec
G_Prec -->|"no"| S_Esc
G_Prec -->|"yes"| P_Check --> R_Conf --> G_Mat
G_Mat -->|"yes"| S_Esc --> R_Tr --> O_Out
G_Mat -->|"no"| R_Tr
βοΈ A contract becomes computable when you turn it into artifacts: clause objects, a term/definition graph, a precedence map, and a trace bundle. Conflicts arenβt guessed β they are detected through explicit gates (definitions resolved? precedence clear?) and escalated when ambiguity is structural.
Diagram: obligation/exception flow¶
flowchart TB
%% Styles (brModel Standard)
classDef i fill:#D3D3D3,stroke-width:0px,color:#000;
classDef p fill:#B3D9FF,stroke-width:0px,color:#000;
classDef r fill:#FFFFB3,stroke-width:0px,color:#000;
classDef o fill:#C1F0C1,stroke-width:0px,color:#000;
classDef s fill:#FFB3B3,stroke-width:0px,color:#000;
I_C(["π Clause text"]):::i
P_T("π·οΈ Classify modality"):::p
G_Type{"Type clear?"}:::s
R_Type(["π Clause type<br>(obligation/prohibition/exception)"]):::r
S_EscType(["π Escalate: ambiguous modality"]):::i
P_S("π§ Extract scope + conditions"):::p
R_Scope(["π§Ύ Scope object<br>(who/what/when)"]):::r
P_Refs("π Resolve defined terms + cross-refs"):::p
G_Refs{"Refs resolved?"}:::s
S_Ask(["π Ask: missing definition / reference"]):::i
P_Rule("π§© Translate to rule"):::p
R_Rule(["π Rule node<br>(condition β constraint)"]):::r
P_Insert("πΈοΈ Insert into clause graph"):::p
R_CG(["πΈοΈ Updated clause graph"]):::r
P_Check("π Check against existing rules"):::p
G_Conf{"Conflict found?"}:::s
P_Diag("π§ͺ Diagnose trigger conditions"):::p
R_Conf(["β οΈ Conflict record<br>(paths + conditions)"]):::r
G_Prec{"Precedence resolves?"}:::s
O_OK(["β
OK (with trace)"]):::o
O_Iss(["β
Review issue<br>(with proposed edits)"]):::o
S_Esc(["π Escalate to counsel"]):::i
R_Tr(["π§Ύ Trace bundle"]):::r
I_C --> P_T --> G_Type
G_Type -->|"no"| S_EscType --> R_Tr
G_Type -->|"yes"| R_Type --> P_S --> R_Scope --> P_Refs --> G_Refs
G_Refs -->|"no"| S_Ask --> R_Tr
G_Refs -->|"yes"| P_Rule --> R_Rule --> P_Insert --> R_CG --> P_Check --> G_Conf
G_Conf -->|"no"| O_OK --> R_Tr
G_Conf -->|"yes"| P_Diag --> R_Conf --> G_Prec
G_Prec -->|"yes"| O_Iss --> R_Tr
G_Prec -->|"no"| S_Esc --> R_Tr
π§ This is where βpointβ happens: every clause is converted into a rule node and inserted into a graph. If terms or references canβt be resolved, the system must stop and ask. If conflicts appear, precedence is tested; if precedence is unclear, it escalates instead of inventing certainty.
Diagram: precedence and exception gates (what overrides what)¶
flowchart TB
%% Styles (brModel Standard)
classDef i fill:#D3D3D3,stroke-width:0px,color:#000;
classDef p fill:#B3D9FF,stroke-width:0px,color:#000;
classDef r fill:#FFFFB3,stroke-width:0px,color:#000;
classDef o fill:#C1F0C1,stroke-width:0px,color:#000;
classDef s fill:#FFB3B3,stroke-width:0px,color:#000;
I_Q(["π― Proposed action<br>(send, disclose, terminate)"]):::i
P_Find("π Retrieve applicable clauses"):::p
R_Set(["π Candidate clause set"]):::r
P_App("π§ Build applicability chain"):::p
R_App(["π§Ύ Applicability record<br>(conditions met?)"]):::r
G_Exc{"Exception applies?"}:::s
P_Prec("π Evaluate precedence"):::p
G_Prec{"Precedence clear?"}:::s
P_Out("βοΈ Determine allowed/required"):::p
G_Risk{"High stakes?"}:::s
O_OK(["β
Allow / require<br>(with clause path)"]):::o
S_Esc(["π Escalate: ambiguity / conflict"]):::i
R_Tr(["π§Ύ Trace bundle<br>(clauses + conditions)"]):::r
R_Neg(["π Negotiation levers<br>(which clause drives risk)"]):::r
I_Q --> P_Find --> R_Set --> P_App --> R_App --> G_Exc
G_Exc -->|"yes"| P_Prec
G_Exc -->|"no"| P_Prec
P_Prec --> G_Prec
G_Prec -->|"no"| S_Esc --> R_Tr
G_Prec -->|"yes"| P_Out --> G_Risk
G_Risk -->|"yes"| S_Esc
G_Risk -->|"no"| O_OK --> R_Tr
R_Tr --> R_Neg
π¦ The decision mechanism is explicit: compute applicability, test exceptions, evaluate precedence, and gate on high-stakes actions. The output isnβt a chat answer β itβs a trace bundle plus negotiation levers that show exactly which clauses create downstream risk.
Outputs¶
Conflict graph
Edges with clause references and conditions under which the conflict triggers.
Risk register
Prioritized issues with remediation suggestions and owner workflows.
Traceable justification
Every flag links back to clauses, sources, and logic edges.
Governance integration
Constraints can block prohibited actions and require legal escalation.
Exception handling
Non-local carve-outs and precedence rules surfaced explicitly, so reviewers donβt miss βonly ifβ¦β conditions.
Negotiation levers
Which clauses drive the most downstream risk, and what edits reduce conflict without breaking the deal intent.