The problem is not generating more code
Coding models have changed the economics of development. Producing code is dramatically faster; understanding, integrating, and maintaining the accumulated result is not.
Without stronger abstraction, model-driven speed increases the amount of software that can become coupled or misplaced before anyone notices. Every new session can search the repository, but that means every session pays to reconstruct the architecture and may draw a different map.
Contract Graph grew from ground-up work across several products. The recurring need was not persuading models to write more. It was giving each session a reliable overview, routing it to the right abstraction, and preserving that understanding after the code changed.
The model
A repository already contains a natural hierarchy, expressed indirectly through imports, constructors, routes, build files, and naming:
project
→ module
→ sub-module
→ component or library
→ implementation
Contract Graph makes that structure explicit as durable nodes:
repository contract
→ module contract
→ sub-module contract
→ component contract
→ relevant implementation
Each contract explains its unit in the parent's context:
- why the unit exists and which responsibility it owns;
- who calls it and through which public entry points;
- what is deliberately outside its boundary;
- which children decompose its responsibility;
- which sibling contracts it consumes;
- which invariants and dependency directions must hold; and
- which command verifies a change inside the boundary.
Viewed together, the contracts give an overview of the software. Traversed one edge at a time, they give the smallest context needed for one task.
Structure is the primary control
Contract Graph is most opinionated about structure because structure decides whether future changes remain understandable and confined. Schema-backed contract.yaml nodes record responsibilities, public surfaces, composition and dependency edges, routes, invariants, and verification.
Its authority has a deliberate order:
- Structural integrity: responsibilities and boundaries form a recursive structure that keeps change comprehensible.
- Structural binding: machine-enforced rules keep the authored graph valid, connected, navigable, and truthful.
- Architecture guidance: security, deployment, data, configuration, and similar choices remain repository judgement unless specifically adopted.
This is a structural layer, not a universal constitution. A specification framework can own product requirements and broader engineering policy while Contract Graph owns routing and structural integrity.
Opinionated at installation, non-possessive afterward. Installed contracts, principles, and guidelines belong to the adopting repository. Later cg init runs preserve those choices rather than silently resetting them. Skills and schemas may be replaced; see upgrade.
Route first; read code second
Contract-owned routes turn a request into one or more starting contracts. The agent follows child links until the responsible unit and its boundary are clear, then reads implementation.
request → contract route → broad-to-narrow contracts
→ bounded source → verification
This does not eliminate code reading. It stops broad code reading from being how every new session reconstructs the system. The honest benefit is bounded, predictable context and less rediscovery—not fewer tokens under every workload.
Abstraction confines change
A folder plus its contract is the smallest workspace that can be handed to a person or agent with the instruction: change anything inside; keep the contract.
- Placement: the contract states how the parent uses the unit.
- Closure: the contract names the child or sibling context needed next.
- Confinement: a change that must escape the unit becomes an explicit contract change rather than silently widening the work area.
The same principle holds at the code boundary. A caller depends on a public promise, not an implementation detail. The implementation can change inside that promise without forcing every caller to change with it.
Why it is a graph
Hierarchy is the primary route, not the only relationship. A module can consume a sibling's public contract, a shared library can serve several parents, and one task can touch two branches. Those lateral relationships form graph edges around a hierarchical spine.
A useful contract therefore does more than describe the files in its directory. It locates the unit in the system and tells the reader where context continues. A contract that cannot say where to go next is prose, not a navigable node.
Keeping the graph true
Once contracts become durable project context, drift is a maintenance defect. Implementation and graph truth must close together: code that violates its contract is wrong, while a changed contract must be explicit and reviewable.
Machine-expressible invariants require blocking detectors and fail-on-demand fixtures. Guidance that cannot be mechanically rejected remains guidance instead of pretending to be enforced.
The causal order matters:
explicit project context
→ precise task routing
→ bounded implementation reading
→ contracts that must stay truthful
→ detectors, rules, and governance
Governance is a consequence of preserving useful context. If enforcement grows while the graph becomes less useful for locating software, the project has optimized the by-product and missed its purpose.
The intended outcome
A fresh session should be able to answer from contracts:
- What does this system contain?
- Where does this request belong?
- How is that unit used by its parent and neighbours?
- Which narrower units are relevant, and which are outside the change?
- What must remain true while the implementation changes?
- What is the smallest verification command that proves the result?
What is built—and what remains
Contract Graph currently scaffolds and verifies schema-backed contracts, routes tasks through contract-owned phrases, discovers brownfield module roots, applies structural rules, generates agent discovery files, supports a contract-driven lifecycle, and verifies authored graph closure.
It machine-proves reciprocity, acyclicity, root reachability, surface paths, and invariant-to-verification links within the authored graph.
It does not yet prove that source code contains no undeclared boundary, that every named symbol is exported, that every import respects the graph, or that arbitrary parallel write sets are safe. Those require ecosystem-specific correspondence checks and write confinement.
Contract Graph provides precise routing and bounded code reading today. It does not claim that an authored subtree is a complete proof of the implementation.