agentsclimarketplace

Change with contracts

Skill nicolasapr/contract-tree/skills/change-with-contracts

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-cascade decision.

Install
npx -y skills add nicolasapr/contract-tree --skill change-with-contracts

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 21 days oldThe repository was created 21 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when about to change code in a repo that has a contract tree. Locates the affected module via `.contract-tree/tree.md`, classifies whether the change touches the module boundary, computes the downstream blast radius, and requires an explicit preserve-vs-cascade decision from the user before touching boundary-affecting code.

SKILL.md

4.3 KB, 955 tokens by cl100k_base, as published. Nobody here has run it

Change With Contracts

The procedure for changing code in a repo that has a contract tree. It keeps you oriented with cheap reads and turns any boundary change into a deliberate, visible decision.

Hard rule: this skill NEVER cascades on its own. When a change would alter a module's boundary, you present the blast radius and let the user choose preserve-vs-cascade. No boundary-affecting code is touched before that choice.

If the repo has no .contract-tree/ yet, run map-modules first (at least for the area you're touching), then return here.

The six steps

1. Locate

Read .contract-tree/tree.md. Find the module(s) where the task lives. Open only those CONTRACT.md files — read their purpose, io, invariants, and entrypoints. Do not scan the whole tree.

2. Classify the change

Read io.input as the module's precondition, io.output as its postcondition, and each invariant as a boundary guarantee (Design by Contract). Then classify into three — see ../contract-tree/references/principles.md for the compatibility rule and taxonomy:

  • Internal (SemVer PATCH) — internals only; precondition, postcondition, and every invariant stay true. → Implement freely. On finish, re-check invariants; update CONTRACT.md only if something it declares actually changed. No cascade.
  • Additive (SemVer MINOR) — the contract changes but stays backward compatible: it weakens the precondition (accepts more), strengthens the postcondition (guarantees more), or adds a new optional output/entrypoint. Existing consumers still work. → Update the CONTRACT.md; no cascade. This is also the target of a "preserve".
  • Breaking (SemVer MAJOR) — it strengthens the precondition (demands more of callers), weakens the postcondition (guarantees less), removes/renames required I/O, or breaks a declared invariant. → Go to step 3.

When unsure whether a change is additive or breaking, treat it as breaking and compute the radius; a false alarm is cheap, a missed break is not.

3. Compute the blast radius

Follow references/blast-radius.md: from tree.md, follow edges transitively from the changed module to collect all downstream modules, then open each one's CONTRACT.md to see how it consumes the changing output. Note which are genuinely affected and how.

4. Present the radius and let the user decide

Show the user: what boundary changes, which downstream modules are affected, and their concrete use points. Then offer the two paths explicitly:

  • Preserve — find an additive path to the same goal so the provider evolves without consumers jumping in lockstep (consumer-driven evolution): add a new field/overload instead of changing an existing one, introduce an extension point, adapt at the edge, or deprecate-before-removing. The radius collapses to zero downstream work.
  • Cascade — accept the breaking change and propagate it through the affected downstream modules.

When you present the radius, note how each downstream module is coupled to the changing output (its connascence — a renamed field is weak; a relied-on meaning like "meters" or a positional/algorithmic dependency is strong). Stronger coupling means a costlier cascade and a stronger reason to preserve.

Stop and wait for the user's choice. Do not touch boundary-affecting code before it.

5. Execute the chosen path

  • Preserve — implement the boundary-safe alternative in the module. Downstream is untouched.
  • Cascade — change the root module, then each affected downstream module in graph order (upstream before downstream), updating each module's CONTRACT.md as its boundary changes.

6. Close

Update every CONTRACT.md whose boundary changed, and regenerate the affected part of .contract-tree/tree.md if the dependency graph changed. An updated contract is part of "done" — leaving it stale is a bug, because the next task trusts it.

What ships with it: 1 file

3.4 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.