KEEL · YARD v0.10.0

Amendments & blast radius

Changing a canon beat is not an edit — it is a migration with a computed impact set. Prose fights its beat; that is normal and expected. When it happens, you amend the beat, and Keel tells you exactly what the change breaks: which leaves realize it, which neighbouring contracts stop holding, which references and promises are stranded. The whole change then lands atomically — or not at all.

A worked amendment, end to end

Say the crossing scene taught you the toll is memory, not coin — the beat's exit condition is wrong. Check the beat out and change it:

$ keel co b-v1.1.1.1 checked out b-v1.1.1.1 r3 → checked-out/b-v1.1.1.1.yaml # edit the card: exits_with: Kael lighter by one memory he cannot name. $ keel amend b-v1.1.1.1 -m "the toll is memory" amendment a-1 opened — b-v1.1.1.1 (exits_with) blast radius (2 impacts): ⛔ b-v1.1.1.2 b-v1.1.1.1 changed exits_with — b-v1.1.1.2's enters_with must be re-satisfied ⚠ s-0001 realizes b-v1.1.1.1 — contract fields changed: exits_with reconcile: `keel co <object>` · edit · `keel ci <object> -m "…" --changeset a-1` — then `keel land a-1`

The beat's own edit became the first member of changeset a-1, landed as pending — visible to everyone, canon to no one. Try to land too early and Keel refuses:

$ keel land a-1 keel: a-1 has unresolved blocking impacts — reconcile them into the changeset or land with --waive "reason" (recorded): ⛔ b-v1.1.1.2 — b-v1.1.1.1 changed exits_with — b-v1.1.1.2's enters_with must be re-satisfied

Reconcile the successor — an ordinary check-out and check-in, tagged to the changeset:

$ keel co b-v1.1.1.2 # edit: enters_with: he arrives lighter by one memory. $ keel ci b-v1.1.1.2 -m "re-satisfy entry" --changeset a-1 checked in b-v1.1.1.2 r2 — pending in a-1 $ keel land a-1 a-1 landed — 2 revisions canon tracked debt — these show ⚠ stale until reconciled: ⚠ s-0001 — realizes b-v1.1.1.1 — contract fields changed: exits_with

The warning you chose not to reconcile did not vanish — it became tracked debt. Until that leaf is revisited, keel status says so:

$ keel status no open checkouts frontier: 1.1.2 "The Gate" — last specified beat ⚠ stale s-0001 — realizes b-v1.1.1.1 — contract fields changed: exits_with (landed a-1, unreconciled)

Why a changeset

canon a-1 LANDS ATOMICALLY a-1 b-v1.1.1.1 r4 · pending b-v1.1.1.2 r2 · pending one review · one transaction · no branches, no merge
Pending revisions accumulate on the changeset; landing flips them all canon in a single transaction. Abandoning discards them all.

A three-word canon change can touch six leaves. If each reconcile were its own review, nobody would use the tool for a week — so an amendment is reviewed once, as one changeset spanning many objects. While an object's head is pending in an open changeset, a plain check-in on it is refused: history cannot interleave.

Where the impacts come from

DIRECTevery leaf realizing the amended beat — the prose that now serves a changed contract
CONTRACTa changed exits_with breaks the successor's entry; a changed enters_with questions the predecessor's exit — ⛔ blocking
REFERENCEleaves whose quote-anchored refs point at changed people or places, via the index
PROMISEan opens removed strands its payoff; a pays removed orphans the setup
⛔ blockingmust be reconciled into the changeset — or waived with the reason on record
⚠ warningmay land as tracked debt; shows stale until revisited
· advisorylisted, never gating

Waiving, and walking away

Sometimes the blocking impact is wrong, or you know better. Landing with --waive "reason" proceeds — and writes your reason into the amendment's record permanently. The other exit is full retreat:

$ keel abandon a-1 a-1 abandoned — 2 objects walked back (revisions retained)

Nothing is ever deleted. Abandoning walks each object's head back to its last revision outside the changeset — but the pending revisions stay in the trail, visible in keel log. The next revision simply lands above them. History only ever grows.