Skip to content
Conduit

skill

contract-tree

Claude Code plugin: represent a project as a tree of documented modules with boundary contracts, so an agent stays oriented in large codebases and makes boundary changes a deliberate preserve-vs-casca

nicolasapr/contract-treecommunitylistedunreviewed

Set up

Skills are installed by placing their folder where your agent loads skills.

The download comes from github.com/nicolasapr/contract-tree itself, not from our server, so what you get is exactly what its author published.

Install instructions come from the README

Skills do not use an MCP config. Follow the steps in the README below.

README

synced Oct 31, 2026

contract-tree

Stars License: MIT Last commit Issues Author: nicolasapr

A Claude Code plugin that represents a project as a tree of documented modules with boundary contracts, so a coding agent stays oriented in large codebases — reading a few targeted contracts instead of scanning everything, and turning any boundary change into a deliberate preserve-vs-cascade decision.

The problem

As a project grows, agents lose track of how modules fit together. A change to one module ripples into others the agent can't see, so it either breaks downstream consumers or over-reads the whole tree to be safe — both waste context and produce fragile changes.

The idea

Each module (a directory) carries a CONTRACT.md declaring its purpose, I/O, upstream dependencies, invariants, and code entrypoints. A repo-root .contract-tree/tree.md index holds the resolved dependency graph, so the agent can compute what depends on what with a single read.

When the agent is about to change a module, it:

  1. reads the contract to see the module's boundary,
  2. checks whether the change stays inside the boundary or touches it,
  3. if it touches, computes the blast radius (all downstream modules that would break),
  4. and asks you to choose: preserve the boundary or cascade the change.

The agent never cascades on its own.

Grounding

The model is a thin, agent-facing application of established practice: a CONTRACT.md is a Design-by-Contract spec (precondition / postcondition / invariant); a module boundary is where information hiding puts a design decision likely to change; a boundary change is classified by backward compatibility the way SemVer distinguishes major/minor/patch; the blast radius is change impact analysis (candidate vs actual impact set); how strongly a consumer depends on the changing output is read as connascence; and "preserve" is consumer-driven evolution — letting a provider change without every consumer jumping at once. The full mapping, including the compatibility rule and the connascence ladder, is in skills/contract-tree/references/principles.md.

The skills

SkillWhen it fires
contract-treeRouter. Explains the model and points to the right sub-skill. Always loaded, stays light.
map-modulesBootstrap a contract tree — extract contracts from existing code, or design a module tree greenfield before writing code.
change-with-contractsAbout to change code. Locates the module, classifies the change, computes the blast radius, and requires an explicit preserve-vs-cascade decision.
check-driftAudit whether contracts still match the code (e.g. after a large merge). Report-only, never auto-fixes.

On-disk format

Per-module CONTRACT.md (source of truth):

---
id: gps/fix-parser
path: src/gps/fix-parser
entrypoints:
  - src/gps/fix-parser/index.ts:parseFix
upstream: [gps/nmea-reader]
io:
  input: "validated NMEA sentence (NmeaSentence)"
  output: "Fix { lat, lon, alt, hdop, ts }"
---

## Purpose
Convert validated NMEA sentences into a normalized Fix.

## Invariants
- Coordinates always WGS84 decimal degrees.
- `alt` in meters.
- Never returns a partial Fix: either a complete Fix or a thrown error.

Repo-root .contract-tree/tree.md (regenerable index; A → B means B is downstream of A):

# Contract Tree
> Source of truth for I/O = the CONTRACT.md files.

- gps/  — location service
  - gps/nmea-reader        → gps/fix-parser
  - gps/fix-parser         → gps/track-store, gps/geofence
  - gps/track-store        → (leaf)
  - gps/geofence           → (leaf)

Only upstream is authored; downstream is derived by inverting it. If the index and a contract disagree, the contract wins. Full spec: skills/map-modules/references/contract-format.md.

Install

/plugin marketplace add nicolasapr/contract-tree
/plugin install contract-tree@contract-tree

Then, in a project:

  • No tree yet? Ask to map the modules for the area you're working in.
  • Changing code? The change-with-contracts flow computes the blast radius and asks before touching any boundary.

Example (GPS)

The runnable example in fixtures/gps/ is a small GPS pipeline — nmea-reader → fix-parser → {track-store, geofence} — with a CONTRACT.md per module and a .contract-tree/tree.md.

Worked scenario: changing fix-parser's output Fix.alt from meters to feet is a boundary change. The blast radius is {track-store, geofence} — both consume alt — so the agent surfaces those two modules and asks preserve-vs-cascade before editing. See fixtures/gps/VALIDATION.md for the mechanical validation of all three flows.

Run the fixture's own tests:

cd fixtures/gps && npm install && npm test

License

MIT — see LICENSE.

↑↓ navigate openesc close