Skip to content

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.

Next steps