Skip to content

tracked_in_index collapses a git ls-files fault into 'not tracked' #69

Description

@randomparity

Found during the spec review on #55's branch. Deferred from #55 with an owner
rather than swept there: converting it ripples through three callers, each
needing its own post-fault decision, and #55 already converts nine sites.

Problem

tracked_in_index (.github/scripts/check-records.sh:371) is a two-valued
predicate over a git query:

tracked_in_index() {
  local path=$1
  git ls-files --error-unmatch -- "$path" >/dev/null 2>&1
}

git ls-files --error-unmatch exits 1 when the path is not tracked — the
ordinary negative — and non-zero for a real fault, with stdout and stderr both
discarded so the status is the only signal. The two collapse, which is the defect
class ADR 0005 (landing with #55) records: a scan that could not run is reported
as one that ran and found nothing.

Three callers treat the collapsed result as authoritative:

  • renumbered_elsewhere:415tracked_in_index "$candidate" || continue, a
    literal in-charter cmd || continue. A fault silently drops a candidate from
    the renumber search, so a genuinely renumbered record reports E-GONE.
  • check_no_disappearances:581 — decides whether a record is present as a real
    tracked file, and so whether the anti-erasure rules run against it at all.
  • check_gate_files:739 — decides whether a renamed gate file's successor is
    really tracked, which is what separates an exempted rename from E-GATE-GONE.

Expected

Per ADR 0005: tracked_in_index becomes three-valued — 0 tracked, 1 not
tracked, 2 fault — capturing git ls-files' status rather than discarding it,
and each of the three callers cases on the result and reports the fault instead
of its ordinary negative verdict.

Each caller needs its own decision about what the fault means, which is the work
here and the reason it is not folded into #55:

  • renumbered_elsewhere — a fault on one candidate must not outrank a positive
    match on another; it is remembered and returned only if the loop exhausts.
  • check_no_disappearances — a fault must not let a record skip the
    append-only rules silently.
  • check_gate_files — a fault must not exempt a rename it could not verify.

A regression test per caller, using the PATH-stubbed git shape #55 introduces.
Note the callers are reached through different fixtures, and a stub keyed only on
ls-files will fire for whichever caller runs first — the stub needs to key on
the path argument as well.

Notes

.github/scripts/check-records.sh has a byte-identical mirror under
skills/tome-of-lore/assets/; the fix lands twice. just records compares them.

Best done after #55 lands, which introduces the three-valued predicate
convention and the git stub harness this would reuse.

Related: #25 (PR #54), #55, #63, #64, #66. ADR 0005 states the rule.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingeffort:MMedium; a day or twopriority:P2Normal priorityrisk:night-watchRevertible but not test-decided; may be built unattended, merged by a human

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions