fix: a verb that moves a record repoints every link that named it - #703
Merged
Merged
Conversation
… record capture resolve, capture wontfix and intent plan rename a record between status folders and leave every relative link that named its old path dead, the gap spec close has too. Captured before the fix that closes it. Refs: iss-2609250846525896 Refs: iss-2609091732329046 Assisted-by: Claude:claude-opus-5-5
A record's folder is its status, so spec close (open/ -> closed/, and planned/ -> shipped/ on the close that ships), intent plan (drafts/ -> planned/), capture resolve and capture wontfix are all renames, and each left every relative link that named the old path dead. record-lint's links_resolve then refused the tree the next command ran against, and every intent lane of run A repointed links by hand. core/relink is the one link-repoint primitive the four verbs share. It takes the moves a verb made, walks the working tree's markdown and rewrites every inline link and link-reference definition that resolved to an old path, including a moved record's own links written from the folder it left, and reports each rewrite (file, line, from, to). Three link classes, one rule: a spec already closed that names ../open/<the closing spec>, ADRs, plans and drafts naming an intent's planned/ path, and the closing spec's bare links to siblings still in open/. A link that never resolved stays as written. The walk stays out of .git, the local tier, nested checkouts and the two append-only logs whose gates refuse an in-place edit (DECISIONS.md, DA002; reviews/, RD002). spec close derives its moves from where the records are now, so a re-run finishes a repoint an earlier attempt left. A repoint failure is a warning on stderr, not a failed verb: the move stands. The results carry `relinked` in --json and the text renders list each rewrite. The plugin pages and the intent and capture surface chapters say so. Refs: iss-2608311127491949 Refs: iss-2609091732329046 Refs: iss-2609250846525896 Assisted-by: Claude:claude-opus-5-5
The fix makes spec close, intent plan, capture resolve and capture wontfix repoint every link that named the moved record, through core/relink. Resolving iss-2609091732329046 exercised it: the resolve repointed the one ADR line (adr-2609151513118583) that linked the record in open/. Resolves: iss-2608311127491949 Resolves: iss-2609091732329046 Resolves: iss-2609250846525896 Assisted-by: Claude:claude-opus-5-5
A re-run of `spec close` derives its moves from where the records are now, and relink re-read every moved record's own links from the folder it left. A bare link written into the closed spec after its close, such as `[the closed index](README.md)`, therefore resolved against open/ and was rewritten to `../open/README.md`, a different file. relink.Move carries MovedNow: the caller made this rename in the same operation. Only such a move re-relativises the moved file's own links; every move still repoints other files' links to the old path, so a re-run finishes that class of an interrupted repoint. Reconcile sets it from what the call moved (the spec open at entry; res.IntentMoved). Plan and the capture transition always move, so they always set it. The zero value is the conservative reading. The fixtures gain a link to an existing other file with a moved record's basename and a dead one with the same basename; both stay as written, so a basename-only matcher now fails the tests. Refs: iss-2608311127491949 Assisted-by: Claude:claude-opus-5-5
Review 2 of the lane found the spec close warning, the RelinkError comment and the two docs still promising that a re-run finishes the repoint. After the MovedNow change a re-run repoints the links other files hold and leaves the moved records' own links for links_resolve, and that holds for an attempt that failed before the repoint as well as during it. Assisted-by: Claude:claude-opus-5-5
Assisted-by: Claude:claude-opus-5-5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A verb that moves a record now repoints every link that named it. Before this, each
spec close,intent plan,capture resolveandcapture wontfixleft links to the old path.record-lint'slinks_resolvethen refused them, and they were repaired by hand.internal/core/relink:Repointwalks every markdown file in the tree. It rewrites inline links and link-reference definitions that resolved to a moved path, including the moved record's own links written from the folder it left. It leaves alone any link that never resolved, and it is idempotent.intent.Reconcile(spec close),intent.Plan(drafts to planned) and the ledger's resolve and wontfix, the last under the ledger lock. The results list each rewrite (relinkedin--json). A repoint failure is a warning on stderr, and the verb still succeeds.Review: Fable 5.1. The first round asked for the re-run's own-link handling to be fixed, and the fix round was verified. The verification round's three stale sentences were fixed in 320ea7c. Reading-corpus change: the window eval passed.
Resolves: iss-2608311127491949
Resolves: iss-2609091732329046
Resolves: iss-2609250846525896
Assisted-by: Claude:claude-opus-5-5