Skip to content

An outranked scan fault is discarded with no trace, at two sites #87

Description

@randomparity

Found by the branch review on #69 (PR pending). #69 briefly fixed one of the two sites and reverted it on the next review pass; see the comment below for why.

Problem

Two functions in .github/scripts/check-records.sh remember a scan fault so that it cannot outrank a positive result, and then discard it when a positive result arrives.

gate_existed_at:

      path_exists_at "$base" "${rel}/${name}" || status=$?
      case $status in
      0) return 0 ;;
      1) ;;
      *)
        fault_status=$path_exists_status
        gate_witness_path="${rel}/${name}"
        ;;
      esac

renumbered_elsewhere has the same shape: a candidate whose index query or base-ref witness could not run is remembered in fault_status, and a later candidate whose content matches returns 0 without mentioning it.

Remembering rather than returning is correct in both — a witness that genuinely found a gate file, or a candidate that genuinely matches, is not made unreliable by an unrelated probe failing. What neither site does is say that the search reached its answer incompletely. The verdict is right; the fact that part of the search never ran is reported nowhere.

The open question

This is not simply "add two warn_full calls". ADR 0005 governs the file and does not settle this case:

  • Decision 3 says the predicate returns a fault value and the caller reports. Both sites would be reporting from inside the predicate, where the caller cannot see it.
  • Decision 1 specifies E-<RULE>-SCAN on the error channel. A warning-severity scan code is a new channel for scan faults, which is a change to that decision rather than an application of it — and ADR 0005 is append-only.
  • ADR 0005 addresses a fault that would otherwise become a verdict. An outranked fault never becomes one, so the record's reasoning does not reach it.

So the work is: decide whether an outranked fault is reportable at all and through which channel, record that decision, then apply it at both sites.

Expected

A decision record settling the above, and both sites following it, in .github/scripts/check-records.sh and its byte-identical mirror under skills/tome-of-lore/assets/.

If the answer is that it should be reported, each site needs a regression test. renumbered_elsewhere already has a fixture that reaches the state — renumber_match_outranks_fault in check-records-test.sh, where one candidate's index query faults and a later one matches. gate_existed_at has none: it needs a git stub that faults ls-tree for one witness path while another resolves for real, in a repo whose protected set is otherwise empty so gate_existed_at is reached at all. Adding an unfalsifiable branch to the gate's own self-protection is what kept this out of #69 — that suite's stated acceptance criterion is that neutralising any single rule turns it red.

Notes

just records compares the two mirrors byte for byte. Related: #25, #55, #64, #66, #69.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:guardrailsGate scripts, test harnesses, Just recipes, hooks, and CI enforcementarea:recordsADR and debt-record conventions, numbering, and record lifecyclebugSomething isn't workingeffort:SSmall; hours, single sittingpriority:P3Low priorityrisk:night-watchRevertible but not test-decided; may be built unattended, merged by a humanstatus:awaiting-mergegreen + mergeable; human just clicks merge

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions