Skip to content

Nothing runs orphan-scan, so the deleted-check half of the ledger comparison cannot fire -- and the blocker its docstring names was removed by #994/#998 #1015

Description

@OffgridwithJD

pgc_ledger.py orphan-scan reports a ledger row that no record in its own part matches. It
is the half of the comparison that answers "has this check been deleted", and the gate
answers only the other half.

Nothing in the tree runs it. Not run_all_versions.sh, not ci.yml, not
nightly.yml. Its only callers are the selftest arms that test the tool itself. So the
guard exists, is tested, and cannot fire on anybody's change.

The reason it was not armed is gone

Its docstring names one measured blocker, and names it as present tense:

Measured, not assumed: part 340 records ONE skip under a DIFFERENT name ("the
unreadable-source refusal") when the box has no non-root user to read as, rather than
skipping its two named arms. On such a box two committed rows have no matching record and
are not removed checks, so a gate refusing on absence would redden a correct run. Arming
this needs those branches to record a SKIP under the names they stand in for.

That conversion landed in #994 and #998. On main today, part 340 does:

for _fp_n in "premise: the unprivileged reader can source the staged harness" \
             "premise: the tree fingerprints to something when it is readable" \
             "premise: the unprivileged read agrees while everything is readable"; do
    check_skip "$_fp_n" ...
done

and the unreadable-source refusal survives only in a comment saying what it used to do --
one occurrence in the file, on a comment line.

So the stated precondition is satisfied. I have corrected the docstring in #1010 step 2 to
say so, and deliberately did not arm it there: "the one blocker I measured is gone" is a
different claim from "no blocker remains", and the second needs a run across every part that
skips.

What arming needs, and why it is worth doing

The work is a measurement, not a design:

  1. Run the matrix and collect, for every part that emits a SKIP, whether each skipped arm
    records under its own name. The unprunable classification already protects a part that
    skipped anything, so the question is narrower than it looks: it is only about a part
    that skips under a name no row matches, which is the One skip stands in for 28 named arms across six suites, so a skipped arm and a deleted one are indistinguishable #994 defect at branch granularity.
  2. Decide the exit code the runner acts on. orphan-scan returns 1 for an orphan or a
    skipped part's rows and 2 for an integrity failure or a refused prune, and not checked
    deliberately returns 0 -- a run observes one major, so on a multi-major ledger most rows
    are rows it cannot speak for.
  3. Wire it beside the gate in run_all_versions.sh, where every suite's log is already in
    one place and the build directory has not been removed yet.

The value is concrete and already paid for once: two rows sat in the committed ledger
naming checks that no longer existed
(#983). The census counted both. Every run returned 0
while the note scrolled past, because vanished=N was printed and refused nothing. That is
the defect this subcommand was written for, and it can recur tomorrow with nothing to catch
it.

Related: #1010 step 2 fixes the direction where a row for another major reads as a deleted
check. That fix is latent until this is armed, which is the honest reason to arm it rather
than an argument that it is urgent.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions