Skip to content

gate-selftests names # NO-SELF-TEST: as the remedy on a branch that returns before reading it #603

Description

@jobordu

The gate tells you to add a declaration that it then ignores on the path that prints the message

scripts/gate-selftests.sh classifies a subject that takes required arguments as
UNESTABLISHED, and prints this remedy:

⚠ check-freshness.py CANNOT BE INVOKED BARE — `--self-test` alone is rejected for MISSING
   REQUIRED ARGUMENTS, so no control is reachable this way. ⛔ That is not
      'has no self-test'; it is a limit of the invocation, and it needs a
      `# NO-SELF-TEST:` line or an invocation this gate can derive.

Adding that line changes nothing. The branch returns at :272; DECLARES_NONE is first
consulted at :340, sixty-eight lines later.

★ Two-pole proof, not inference — same tree, one edit

POLE A   tools/check-freshness.py carries `# NO-SELF-TEST: controlled by …`
         ⚠ check-freshness.py CANNOT BE INVOKED BARE …
         ⚠ UNESTABLISHED: check-freshness.py job-log.py reference-check.py

POLE B   the same file, declaration renamed to `# xx-SELF-TEST:`
         ⚠ check-freshness.py CANNOT BE INVOKED BARE …
         ⚠ UNESTABLISHED: check-freshness.py job-log.py reference-check.py

⇒ IDENTICAL BYTES.

⚠ CONTROL — the declaration is honoured on the other path: gh-complete.py carries the same
line, hits the flag-REJECTED branch at :340, and moved from UNESTABLISHED to
declared NO self-test in the same run. So this is not "declarations don't work" — it is one
branch of two.

grep -n DECLARES_NONE scripts/gate-selftests.sh
  73:DECLARES_NONE="^# NO-SELF-TEST:"
 340:  if grep -q "$DECLARES_NONE" "$f"; then      ← flag-REJECTED path: honoured
 360:  2) if grep -q "$DECLARES_NONE" "$f"; then
                                                   ← :272 bare-args path: returns first

⇒ Why this is a doctrine defect and not a cosmetic one

This repo filed #73 for exactly this shape: an absence report that does not name its remedy
converts a gap into a wall.
The remedy there was that every VOID must state its disposition class.
This is the next failure along: the report names a remedy, and the remedy is inert. That is
worse than naming none, because the reader does the work and gets no signal that it did nothing —
which is how I spent a cycle adding declarations to two files and measuring no change.

⚠ And the branch has a real reason to exist, quoted from its own comment, which is why this is
a question and not a patch:

"A SUBJECT THAT CANNOT BE INVOKED BARE IS ITS OWN STATE, not 'declared none'. … Folding that
into 'has no self-test' would be a claim about the world made from a limit of the invocation."

That reasoning is sound. If a declaration should not satisfy this branch, then the branch is
right and its message is wrong. Both readings are defensible and the choice belongs to whoever
owns the gate.

Two ways to close it — they are not equivalent

  1. Honour the declaration in the bare-args branch. Consult DECLARES_NONE before returning at
    :272. ⚠ Cost: it weakens the distinction the branch's comment is defending — a declared
    subject that also cannot be invoked bare becomes indistinguishable from one that simply has no
    --self-test.
  2. Fix the message instead. Stop naming # NO-SELF-TEST: on this path and name what actually
    works: "an invocation this gate can derive" — i.e. a # SELF-TEST-ARGV: line, or whatever the
    gate can consume. ⚠ Cost: nothing exists to consume yet, so the remedy would be unbuildable
    until it does.

⇒ Option 2 is the honest minimum and needs no semantic decision; option 1 is the one that lets
these two instruments leave UNESTABLISHED at all.

Close condition

  • Adding # NO-SELF-TEST: to a subject that takes required arguments either changes its
    verdict
    , or the message stops naming it as the remedy.
  • A two-sided control asserting the difference: one subject where the declaration changes the
    verdict, one where it provably does not, both named in the output.

Caller: add # NO-SELF-TEST: to tools/check-freshness.py, run SUBJ_DIR=tools ./scripts/gate-selftests.sh, and diff the output against the same run with the line removed. Today
those two runs are byte-identical while the message says they should differ.

⚠ Bounds

  1. ON local only. The gate's own header warns the reading is a property of the tools on that
    machine; nothing here was measured on a runner.
  2. I did not establish whether reference-check.py — the third remaining UNESTABLISHED — reaches
    the same branch. Its cause is separate and recorded on tools/test_reference_check.py fails on main — 3 FAILED, and nothing reports it #280.
  3. Which of the two options is correct is not established here and is deliberately left open.

Measured by TEAMLEAD, session 15b69750, at origin/main. Surfaced by #602,
which adds those declarations and reports honestly that two of the three buy nothing today.

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