#899·openwiki

Claim evidence keeps stale #Lx-Ly line numbers after a block moves

Author: drmikecroweCreated Sep 17, 2026Updated Sep 17, 2026

When a cited block relocates, openwiki re-finds it correctly and writes a correct digest, but leaves the old line numbers in the evidence resource string. The published page then sends readers to lines that no longer hold the cited code.

resolveLineRangeEvidence (dist/claims/evidence/repository/resolver.js:131) passes input.resource through untouched on both relocation paths:

  • Unchanged but moved (locateUnchangedLineRange, :213) returns { resource: input.resource, version: previousVersion } while the content comes from unchangedSpan, which is somewhere else in the file.
  • Changed and moved (locateChangedLineRange, :250) calls createLineRangeEvidence(input.resource, lines, changedSpan) at :195. That builds a fresh version from the new span at :333 and still carries the old resource string.

The second case also leaves the record internally inconsistent. selectedLineCount describes the new span, #Lx-Ly describes the old one.

A concrete one from my repo, after an update that spanned 75 commits:

resource: repo://src/harnessed/launcher.py#L2801-L2834   (34 lines)
version payload: selectedLineCount = 42

The content actually sits at lines 2928-2969 in the current tree. I scanned the file for a 42-line window whose first and last line hashes match firstSelectedLineHash and lastSelectedLineHash, and exactly one span matches: 2928-2969. So the relocation logic got it right and only the URI is wrong.

24 of 2098 evidence entries came out of that run this way. The previous run, against a tree where nothing cited had moved, had 0.

Two ways this bites:

  1. Published pages cite line numbers that are wrong, and pointing at exact lines is the whole job of the repo://path#Lx-Ly convention.
  2. Anything reading the Claims externally has to know that the resource span is a hint and selectedLineCount is the truth. I had a drift checker that asserted the two agreed. It was green for months and died the first time real code moved.

dist/claims/evidence/repository/resolver.js is byte identical across 0.4.3, 0.5.1 and 0.5.2, so this isn't a recent regression. It just needs a relocation to show up.

What I'd expect as a fix: createLineRangeEvidence already has the new span, so it can rewrite the fragment, and the unchanged-but-moved path can do the same instead of returning the previous evidence verbatim. I can send a PR if that's the direction you want.

One question before I do. Is the current behavior deliberate? If the resource URI is meant to be a stable identity for a piece of evidence rather than a pointer to its current location, that explains it, and the fix is documentation plus possibly a separate current-location field. I don't know which you intended.