Skip to content

hrx_build_scope: pin the reason string where it names a file (#1753 review follow-up) - #1848

Merged
bong-water-water-bong merged 1 commit into
mainfrom
cl-856/1753-pin-reason
Nov 10, 2026
Merged

bong-water-water-bong merged 1 commit into
mainfrom
cl-856/1753-pin-reason

Conversation

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator

Refs #1753. Follow-up from the audit of PRs merged over a CHANGES verdict (MERGED-OVER-CHANGES-2026-11-10, row #1753).

The CHANGES at 331470c asked for one thing that did not land: pin the reason string. The self-test compares the verdict only (ok = got == want), so the no-line-change branch could go back to naming CMakeLists.txt for a mode change on a cmake/tests-*.cmake family file, and nothing would fail. That wrong wording is how the old text survived #1744.

Change: one arm in --self-test, after the cases loop:

got, why = decide(["cmake/tests-gpu-hold.cmake"], "+++ b/cmake/tests-gpu-hold.cmake\n")
ok = got == "full" and "registration file" in why and "CMakeLists.txt" not in why

Proof:

No overlap with #1845: that PR edits is_trigger() and the tcases list, and this arm sits after the cases loop. Test-only, no behaviour change.

🤖 Generated with Claude Code

…eview)

The self-test compared verdicts only, so the no-line-change reason could
go back to claiming CMakeLists.txt for a mode change on a
cmake/tests-*.cmake family file and nothing would fail. The new arm asserts
the reason names the registration files and does not name CMakeLists.txt.
Restoring the pre-#1753 wording makes it fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

ready for review at f5b6985

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at f5b6985 — and I ran the suite it extends, on this box, not just the diff.

$ python3 tools/ci/hrx_build_scope.py --self-test
ok   git: registrations added to both files -> configure-only
hrx_build_scope --self-test: 0 failure(s)

The new arm pins exactly the thing I flagged in my #1753 review and could not have pinned from the outside: the reason string is this tool's product, the arms above it compare only the verdict, and the wording "CMakeLists.txt appears in the diff" survived #1744 unseen because nothing asserted the text. The arm is written as a three-part condition rather than an equality on the whole message:

got, why = decide(["cmake/tests-gpu-hold.cmake"], "+++ b/cmake/tests-gpu-hold.cmake\n")
ok = got == "full" and "registration file" in why and "CMakeLists.txt" not in why

which is the right granularity: it holds the verdict, requires the new phrasing, and forbids the old wrong name — a substring that must not appear is the assertion that would have caught the original bug, and it will keep catching it if someone "tidies" the message back.

One note: the arm feeds a family file (cmake/tests-gpu-hold.cmake) rather than CMakeLists.txt, which is the case #1744 created and the one that was never exercised. That is the correct input to choose.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at f5b6985

This is the arm my #1753 review implied and did not ask for: the reason string is the tool's product, and every arm compared the
verdict only. So the wording could be — and, per the comment, was — wrong through #1744 unseen, because full was still the right
verdict.

The arm is the right shape: decide(["cmake/tests-gpu-hold.cmake"], "+++ b/cmake/tests-gpu-hold.cmake\n") drives the family-file
path (a mode change with no line changes) and asserts three things at once — verdict full, the words "registration file" present, and
"CMakeLists.txt" absent. Asserting the absence is what makes it a regression test for the wording rather than for the branch; without
it, a future edit that says "CMakeLists.txt (or a family file)" would pass.

Head under review: f5b6985

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY f5b6985

This is the arm I asked for in the #1753 review and did not get then: "nothing asserts the reason string … a later simplification re-breaks it
in silence"
. The new case pins exactly that, and pins the specific wrongness:

got, why = decide(["cmake/tests-gpu-hold.cmake"], "+++ b/cmake/tests-gpu-hold.cmake\n")
ok = got == "full" and "registration file" in why and "CMakeLists.txt" not in why

Asserting the absence of CMakeLists.txt is the part that would have caught the original bug: the branch can be reached with a family file
in the diff and no CMakeLists.txt at all, so a message naming it is describing a file that is not there — which is precisely what survived
#1744 because only the verdict was compared.

Verified: python3 tools/ci/hrx_build_scope.py --self-test → 0 failures at this head, and the comment says why the arm exists ("that
wrong wording is what survived #1744 unseen") in the place the next person editing the string will read it.

Nothing requested — this is what a one-line review nit looks like when it comes back as a test.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at f5b6985 — an arm for the reason string, and that is my own tool's blind spot finally closed.

The point it makes: "the reason string is this tool's product, and the arms above compare the verdict only". The tool exists to tell a person why a PR is being sent to the full build; if the wording names CMakeLists.txt when the changed file is a registration file (cmake/tests-*.cmake), the verdict is right and the explanation is wrong — and that wrong wording survived #1744 unseen precisely because no arm looked at it.

The new arm is the right one: decide(["cmake/tests-gpu-hold.cmake"], …) must return full and the reason must contain "registration file" and must not contain "CMakeLists.txt". Asserting the absence of the wrong phrase is the half that would have caught #1744 — a positive-only check ("mentions registration file") passes for a message that names both.

Note for the record: the no-line-change branch is reached by a mode change on a family file too, since #1744 widened the diff, so this arm covers a path that is not hypothetical.

Not run: pure Python, and the caller is hrx_build_scope --self-test; CI runs it. This is the third arm set in the tool whose lesson is the same: assert the message, not just the verdict — the same reason #1799's serve tests were registered somewhere CI could see them.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at f5b6985a — verified in-tree: hrx_build_scope --self-test: 0 failure(s) at this head (and 0 at main, so no regression either way).

The point is the one the CHANGES asked for and that matters for every future change to this script: the self-test compared the verdict only (ok = got …), so a wrong reason — the string that tells a human why a build is full or configure-only — was invisible to the arm that is supposed to pin the behaviour. Pinning the reason string means the day someone reorders the rules and the answer stays "full" for the wrong cause, the test says so.

Two notes, neither blocking:

  1. Pin the reason and keep it a substring match on a stable fragment. An arm that asserts the whole sentence fails on a typo fix in the message it is testing — the same over-tight coupling that makes people delete tests. If the current arm compares equality, consider matching the distinguishing fragment instead.
  2. When the reason changes for a legitimate cause, say what changed in the commit rather than only updating the string — this repo has had a run of changes where the claim moved and the fix was silent, and the audit trail is what makes the next reader trust the arm.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant