A system that models agreements as infrastructure

How the Agreement Graph is built

This contract isn't a document. It's a state transition waiting to be enforced.

Inspired by the harness-engineering framing: the interesting work isn't storing contracts, it's building the machine that keeps every state change honest.

The argument

A contract is not a flat file. It is a web of parties, obligations, and dependencies, and underneath it, a single enforceable event: the moment identity, intent, and authorization line up and a state changes.

Most contract software treats agreements as documents to store and search. That misses the point. The valuable thing isn't the text, it's the transition: who is bound, under what authority, from what state to what state, and whether you can prove it later.

The Agreement Graph models that directly. Every agreement is a node with a lifecycle. Every change of state is a guarded, audited transition. Every relationship between agreements, a master agreement to its SOW, an amendment to its original, a renewal that supersedes the old terms, is a typed edge in a graph the operator owns.

Agreements represent enforceable state transitions:
identity → intent → authorization → auditability → state change.

What it takes

Three things have to hold first

The honest goal is a system you can trust to change a contract's legal state without a human re-reading the whole file each time. That only holds if three things hold first.

01

A guard sharp enough to fail against

If "ready to sign" is a vibe, the only way to check is to read the contract. So every transition carries a guard, a pure rule that must pass before the state moves. No party attached? submit fails. No reviewer? It never reaches review.

deterministic · no LLM in the guard
02

An audit gate that proves it happened

A state change nobody can reconstruct is a liability. Every transition emits an append-only audit event: who acted, from which state, to which state, when, and why. The trail is the proof. It is never edited or deleted.

append-only · reconstructable
03

A graph that compounds

Every agreement leaves the graph richer than it found it: a new supersession chain, a new dependency, a parent-child link. One contract is a row. A thousand linked contracts is an asset you can query: what depends on what, what's expiring, what replaced what.

typed edges · owned, not rented

The spec → ship loop, for contracts

The lifecycle is a state machine

One agreement, one pipeline. Each transition is a pure function: it takes the agreement plus an actor, checks a guard, and returns a new agreement and an audit event. Nothing is written until both succeed. Click a state to see what it can do, or press play and watch one agreement walk from draft to active.

Tip: click any state node

apply_transition( )

agreement.state = "draft"
transition      = "submit"
actor           = "acme-corp"

returns

agreement.state = "proposed"
audit_event = {
  from: "draft", to: "proposed",
  actor: "acme-corp", at: "…"
}

The compounding artifact

Agreements link into a graph

A master agreement parents its statements of work. A renewal supersedes the old terms. Parties connect to everything they're bound to. Hover a node to inspect it; click to light up everything it touches.

The ingestion pipeline

Bronze → Silver → Gold

Raw contracts come in messy. They earn structure in stages, each layer defined by what it delivers semantically, not by how it's stored. Click a layer to open it.

Constraints that don't bend

Owned, standard, and impossible to fake

Ownership first

Operator owns all data in plain, portable form. Git-friendly, no SaaS lock-in. The lesson from closed memory systems: if you can't export it, you don't own it.

No fact without a source

Every extracted contract fact cites the exact span it came from. Low-confidence extractions get flagged, never silently filled. The system never asserts what it can't point back to.

Standards over custom

W3C DCAT for catalog metadata, PROV-O for lineage, RDF + SPARQL at the Gold layer. Interoperable out of the box instead of a bespoke schema nobody else speaks.

Human at the checkpoint

The UNDER_REVIEW state is a built-in human gate. Nothing reaches APPROVED without an identified reviewer acting on it. AI augments the review; it doesn't replace the signature.

Try it yourself

The scaffold runs today

FastAPI + NetworkX + SQLite. 47 tests green. A demo that walks a Master Service Agreement to a Statement of Work and then supersedes it with a renewal.

run the demo
# get the code
git clone https://github.com/amrit930203/agreement-graph.git
cd agreement-graph

# spin up an isolated environment
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# walk MSA → SOW → supersession end-to-end
python examples/demo.py

# 47 tests over models + state machine + graph + store
pytest tests/ -v

# start the API, docs at /docs
uvicorn agreement_graph.api:app --reload
a transition, in code
from agreement_graph.state_machine import apply_transition

# pure function, nothing is written here
new_agreement, event = apply_transition(
    agreement,
    "submit",
    actor_party_id=acme.id,
)

# caller persists both, atomically
store.save_agreement(new_agreement)
store.save_audit_event(event)   # append-only
graph.update_agreement(new_agreement)
9lifecycle states
11guarded transitions
47tests passing
0external services required