From 57ed2757831e0a6e6b69d1bdd40b155514c02fe3 Mon Sep 17 00:00:00 2001 From: "Joshua D. Drake" Date: Sun, 13 Sep 2026 12:19:41 -0600 Subject: [PATCH 1/3] test: the grader reads every check helper lib.sh defines (#432, #1040) The other half of #1040. #1041 fixed the two hilbert_locality names this was hiding; this makes the grader able to see that class at all. THE DEFECT. The bash side matched `check(?:_num|_ratio|_text|_timing)?`, so three of the eight helpers lib.sh defines were invisible: check check_num check_text check_ratio check_timing READ check_unrunnable check_skip check_ratio_needs_quiet_machine INVISIBLE A property asserted through one of the three was never reported MISSING and could not move rc, so A PAIR COULD GRADE ONE-FOR-ONE ON THE STRENGTH OF THE GRADER'S BLIND SPOT. It never drifted out of date either: 0cbf574 introduced that pattern and check_unrunnable already had 21 call sites that day. Same shape as #1036 and #1038 on the python side -- a rule true of MOST of a class taken for a property of the class -- sitting on the other side of the same tool for five days, unexamined because fixing one end thoroughly did not prompt anyone to look at the other. THREE ARMS, and two of them state what the tool does NOT cover: test_the_extractor_reads_every_check_helper_lib_sh_defines re-derives the list from lib.sh's DEFINITIONS and fails with the helper named. The list is hand-written so the tool stays standalone; pinned the way _NAME_ARG is. test_a_longer_helper_name_is_not_shadowed_by_a_shorter_one the pattern SHAPE, not the ordering -- see below. test_the_suite_local_helpers_are_known_and_excluded the four helpers one suite each defines (check_structure, check_reconstruct, check_split_happened, check_float), and that none of their suites has a pytest twin, so none is graded today. THE ORDERING CLAIM WAS OVERSTATED AND THE CODE SAID IT UNTIL IT WAS MEASURED. The entries are longest-first and I wrote that a shorter prefix would shadow a longer helper. Python's `re` BACKTRACKS across alternatives, so a pure reorder reads both names identically -- measured, arm stays green. What the OLD pattern could not do was read check_ratio_needs_quiet_machine at all: it matches check_ratio, wants whitespace, finds `_needs`, backtracks to the empty option, wants whitespace after `check`, fails. On a fixture holding both: pre-#1040 optional-suffix form ['short'] this form, either order ['short', 'long'] So the arm pins the SHAPE and the ordering is readability. Corrected in the code comment, the docstring and TESTS.md rather than left to read as load- bearing. POPULATION: `check` or `check_`, not `check[a-z_]*`. The loose form also matches `checks_in` in decode_interrupts.sh, a counting utility returning a number that records nothing. It was in the suite-local list until the arm printed it and the definition was read. Removal proof, each mutation asserted applied by md5, tree restored after each: drop check_unrunnable from the list the drift guard, naming it drop check_skip from the list the drift guard, naming it add a duplicate entry the drift guard (size reconciliation) pure reorder, longest no longer first NOTHING -- which is the finding above Verified against main 0d17a87, not carried from the head it was written on: all seven pairs rc=0 missing=0, guard job 316 collected, 784 checks, 784 pass + 0 fail + 0 unrun, docs_style.sh 14 PASSED. guard_tests 313 -> 316 re-derived by collection. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01NhwXKAgSmYDUjteWkfajHK --- CHANGELOG.md | 36 ++++++++++ test/pytest/TESTS.md | 45 +++++++++++++ test/pytest/compare_to_bash.py | 48 ++++++++++++- test/pytest/expected_tests.txt | 7 +- test/pytest/test_compare_to_bash.py | 101 ++++++++++++++++++++++++++++ 5 files changed, 234 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfc30042..51513131 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1297,6 +1297,42 @@ true until the next version shipped. ### Fixed +- `compare_to_bash.py` read five of the eight check helpers `lib.sh` defines + (#432, #1040). + + The bash side of the parity tool matched + `check(?:_num|_ratio|_text|_timing)?`, so `check_unrunnable`, `check_skip` and + `check_ratio_needs_quiet_machine` were invisible. A property asserted through one of + the three was never reported MISSING and could not move `rc`, which means **a pair + could grade one-for-one on the strength of the grader's blind spot.** + `hilbert_locality` was exactly that, and #1041 closed the two properties it was + hiding. + + It never drifted out of date: `0cbf574` introduced that pattern, and + `check_unrunnable` already had 21 call sites that day. Same defect shape as the + python side in #1036 and #1038 -- a rule true of most of a class taken for a + property of the class -- sitting on the other side of the same tool for five days. + + The helper list is hand-written, so it is pinned the way `_NAME_ARG` is: an arm + re-derives it from `lib.sh`'s DEFINITIONS and fails with the helper named. Two more + arms state what the tool does not cover -- the four suite-local helpers + (`check_structure`, `check_reconstruct`, `check_split_happened`, `check_float`), + none of whose suites has a pytest twin, and the pattern shape that used to make a + prefix unreadable. + + **The longest-first ordering is NOT what makes that work, and the code said + otherwise until it was measured.** Python's `re` backtracks across alternatives, so + a pure reorder reads both names identically. What the old pattern could not do was + read `check_ratio_needs_quiet_machine` at all: it matches `check_ratio`, wants + whitespace, finds `_needs`, backtracks to the empty option, wants whitespace after + `check`, and fails. Measured on a fixture holding both, the old form reads + `['short']` and this one reads `['short', 'long']`. The arm pins the pattern shape; + the ordering is readability. + + The population is `check` or `check_`, not `check[a-z_]*`: the loose form + also matches `checks_in` in `decode_interrupts.sh`, a counting utility that returns a + number and records nothing. + - `compare_to_bash.py` read the wrong argument for the four helpers whose name is not last (#432, #1036). diff --git a/test/pytest/TESTS.md b/test/pytest/TESTS.md index bd565109..ef8d47db 100644 --- a/test/pytest/TESTS.md +++ b/test/pytest/TESTS.md @@ -3657,6 +3657,48 @@ standalone (`ast`, `re`, `sys`) and cannot import `Expect` to ask where each nam out of `pgc_vacuity.py`, recomputes every entry, and fails with the helper named when the two disagree. +### The BASH side had the same blind spot, and it shipped that way (#1040) + +Everything above is about the python side. The bash side read five of the eight check +helpers `lib.sh` defines: + + check check_num check_text check_ratio check_timing READ + check_unrunnable check_skip check_ratio_needs_quiet_machine INVISIBLE + +A property asserted through one of the three was never reported MISSING and could not +move `rc`, so **a pair could grade one-for-one on the strength of the grader's blind +spot.** `hilbert_locality` was exactly that: two of the four properties its unrunnable +branch records had no counterpart in the port, and #1041 closed them. + +It never drifted out of date. `0cbf574` introduced the pattern, and `check_unrunnable` +already had 21 call sites that day. + +All eight take the check NAME as `$1`, so one pattern serves them all. That is a +property of these helpers rather than of bash, which is why the drift guard re-reads it +from `lib.sh` instead of trusting it. + +`check_ratio` is a prefix of `check_ratio_needs_quiet_machine`, and **the old pattern +shape could not read the longer one at all**: `check(?:_num|_ratio|_text|_timing)?\s+"` +matches `check_ratio`, wants whitespace, finds `_needs...`, backtracks to the empty +option, wants whitespace after `check`, and fails. Measured on a fixture holding both, +the old form reads `['short']` and the current one reads `['short', 'long']`. + +**The entries are listed longest-first for readability, and that ordering is NOT what +makes it work.** Python's `re` backtracks across alternatives, so a pure reorder reads +both names identically -- measured, and the arm stays green under it. Said explicitly +because the list LOOKS as though its order is load-bearing, and the arm pins the pattern +shape rather than the order. + +**Suite-local helpers are out of scope, asserted rather than assumed.** Four suites +define one of their own (`check_structure`, `check_reconstruct`, `check_split_happened` +in `parallel_copy.sh`, `check_float` in `parquet_export_stats.sh`) and none has a pytest +twin, so none is graded. An arm holds both halves, so the day one is ported the grader's +limit is stated rather than discovered. + +The population is `check` or `check_`, **not** `check[a-z_]*`: the loose form +also matches `checks_in` in `decode_interrupts.sh`, a counting utility that returns a +number and records nothing. + ### Removal proof | mutation | red | @@ -3694,4 +3736,7 @@ the tool grades THIS tree. | `test_a_helper_whose_name_is_optional_takes_it_only_from_the_keyword` | `plan_marker` and `plan_node` carry no name positionally; absent beats a key | | `test_the_tools_table_agrees_with_the_signatures_it_describes` | the drift guard: every entry re-derived from the real signatures | | `test_no_later_argument_can_overtake_the_name` | nothing after the name may be passed positionally, so `-1` is true of every CALL and not just every signature | +| `test_the_extractor_reads_every_check_helper_lib_sh_defines` | the BASH-side drift guard: the helper list re-derived from `lib.sh`'s definitions | +| `test_a_longer_helper_name_is_not_shadowed_by_a_shorter_one` | `check_ratio` must not eat `check_ratio_needs_quiet_machine` | +| `test_the_suite_local_helpers_are_known_and_excluded` | the four suite-local helpers, and that none of their suites is graded | | `test_the_ported_suites_in_this_tree_are_graded_one_for_one` | the standing arm: every pair in the tree, graded | diff --git a/test/pytest/compare_to_bash.py b/test/pytest/compare_to_bash.py index 69683c56..6dde85c3 100755 --- a/test/pytest/compare_to_bash.py +++ b/test/pytest/compare_to_bash.py @@ -207,6 +207,51 @@ def _as_names(node): r'\$\{[^}]*\}|\$\([^)]*\)|\$[A-Za-z_][A-Za-z0-9_]*|\$[0-9]+|\$[@*#?]') +# EVERY CHECK HELPER `lib.sh` DEFINES, and the pattern built from it (#1040). +# +# This read five of the eight. `check_unrunnable`, `check_skip` and +# `check_ratio_needs_quiet_machine` matched no branch, so a bash property asserted +# through any of them was INVISIBLE: never reported MISSING, never able to move `rc`, +# and therefore a pair could grade one-for-one because the grader could not see the +# gap. `hilbert_locality` was exactly that -- two of the four properties its +# unrunnable branch records had no counterpart in the port. +# +# All eight take the check NAME as `$1`, so one pattern serves them all; that is a +# property of these helpers rather than of bash, and the drift guard re-reads it. +# +# `check_ratio` is a prefix of `check_ratio_needs_quiet_machine`, and the OLD pattern +# shape could not read the longer one at all: `check(?:_num|_ratio|_text|_timing)?\s+"` +# matches `check_ratio`, needs whitespace, finds `_needs...`, backtracks to the empty +# option, needs whitespace after `check`, and fails. Measured on a fixture holding both: +# the old form reads ['short'], this one reads ['short', 'long']. +# +# The entries are written longest-first for readability. **That ordering is NOT what +# makes it work** -- Python's `re` backtracks across alternatives, so a pure reorder +# reads both names identically (measured). An arm pins the BEHAVIOUR rather than the +# order, because the order is the thing that looks load-bearing and is not. +# +# Hand-written so the tool stays standalone, and pinned like `_NAME_ARG`: +# `test_compare_to_bash.py` reads the DEFINITIONS out of `lib.sh` and fails with the +# helper named when the two part company. +# +# SUITE-LOCAL HELPERS ARE OUT OF SCOPE, deliberately. Four suites define one of their +# own (`check_structure`, `check_reconstruct`, `check_split_happened` in +# `parallel_copy.sh`, `check_float` in `parquet_export_stats.sh`) and none of the four +# has a pytest twin, so none is graded. An arm asserts both halves of that. +_BASH_HELPERS = ( + "check_ratio_needs_quiet_machine", + "check_unrunnable", + "check_timing", + "check_ratio", + "check_text", + "check_skip", + "check_num", + "check", +) + +_BASH_PATTERN = (r'\b(?:' + "|".join(_BASH_HELPERS) + r')\s+"([^"]+)"') + + def _template(name): """-> the name with every interpolation reduced to `{}`. @@ -218,8 +263,7 @@ def _template(name): def main(bash_file, py_file): """-> the exit status: 1 when a bash property has no counterpart.""" - bash_names = re.findall( - r'\bcheck(?:_num|_ratio|_text|_timing)?\s+"([^"]+)"', open(bash_file).read()) + bash_names = re.findall(_BASH_PATTERN, open(bash_file).read()) py_names = _py_names(open(py_file).read()) bset, pset = set(bash_names), set(py_names) diff --git a/test/pytest/expected_tests.txt b/test/pytest/expected_tests.txt index 9d4b63a7..cd0599fd 100644 --- a/test/pytest/expected_tests.txt +++ b/test/pytest/expected_tests.txt @@ -75,7 +75,12 @@ # and this branch's REASON check are complementary, and pgc_vacuity.py kept both. # Re-derived by collection on the merged tree: the two 307s and the 310 that # preceded this are each right for a DIFFERENT tree and none of them is this one. -guard_tests 313 +# 313 -> 316 when the bash-side extractor was widened to every check helper lib.sh +# defines (#1040): a drift guard re-deriving that list from lib.sh's DEFINITIONS, a +# shadowing arm (check_ratio is a prefix of check_ratio_needs_quiet_machine), and one +# pinning the four suite-local helpers as knowingly out of scope. +# Re-derived by collection against main 0d17a87: `316 tests collected`. +guard_tests 316 # The complement: tests that need the driver and a throwaway cluster. Until #1016 these ran # in no CI job at all -- a quarter of the corpus, green when somebody ran them by hand and diff --git a/test/pytest/test_compare_to_bash.py b/test/pytest/test_compare_to_bash.py index dd8fd653..56d8d74c 100644 --- a/test/pytest/test_compare_to_bash.py +++ b/test/pytest/test_compare_to_bash.py @@ -35,6 +35,7 @@ import ast import pathlib +import re import sys HERE = pathlib.Path(__file__).resolve().parent @@ -294,6 +295,7 @@ def test_the_tools_table_agrees_with_the_signatures_it_describes(expect): # The one hand-written semantic claim above, pinned against the body it describes: # read cannot_run's own `_record(...)` call and check which parameter it names. + # fn = [f for f in helpers if f.name == "cannot_run"] expect.num(len(fn), 1, "premise: cannot_run is among the helpers read") recorded = [kw.value.id for call in ast.walk(fn[0]) @@ -364,6 +366,105 @@ def test_no_later_argument_can_overtake_the_name(expect): "no positional argument can be written after the name and be read as it") +def test_the_extractor_reads_every_check_helper_lib_sh_defines(expect): + """THE BASH-SIDE DRIFT GUARD (#1040), and the mirror of the table guard above. + + The extractor read five of the eight check helpers `lib.sh` defines. The other + three -- `check_unrunnable`, `check_skip`, `check_ratio_needs_quiet_machine` -- + matched no branch of its pattern, so a bash property asserted through any of + them was invisible, was never reported MISSING, and could not move `rc`. + + **A pair could therefore be declared one-for-one on the strength of the grader's + blind spot**, which is what `hilbert_locality` was: two of the four properties + its unrunnable branch records had no counterpart in the port at all. + + The helper list is hand-written, for the same reason `_NAME_ARG` is: the tool + stays standalone. So it is pinned the same way -- this reads the DEFINITIONS out + of `lib.sh` and fails with the helper named when the two part company. Add a + `check_whatever()` to `lib.sh` and this goes red before a suite using it is + silently ungraded. + + Suite-LOCAL helpers are deliberately not in scope here; that is asserted, with + its reason, in the arm below. + """ + from compare_to_bash import _BASH_HELPERS + + lib = (HERE.parent / "lib.sh").read_text() + # `check` or `check_`. NOT `check[a-z_]*`, which also matches + # `checks_in` -- a COUNTING utility in decode_interrupts.sh that returns a + # number and records nothing. Define the population before counting it. + defined = set(re.findall(r'^(check(?:_[a-z_]+)?)\(\)\s*\{', lib, re.M)) + expect.at_least(len(defined), 8, + "premise: lib.sh's check helpers were found, not an empty set") + + missing = sorted(defined - set(_BASH_HELPERS)) + extra = sorted(set(_BASH_HELPERS) - defined) + expect.text(", ".join(missing) or "none", "none", + "every check helper lib.sh defines is one the extractor reads") + expect.text(", ".join(extra) or "none", "none", + "and the extractor claims no helper lib.sh does not define") + expect.num(len(_BASH_HELPERS), len(defined), + "inputs == sum(buckets): the two lists are the same size") + + +def test_a_longer_helper_name_is_not_shadowed_by_a_shorter_one(expect): + r"""`check_ratio` is a PREFIX of `check_ratio_needs_quiet_machine`. + + THE PRE-#1040 PATTERN COULD NOT READ THE LONGER ONE AT ALL, and that is what this + holds. `check(?:_num|_ratio|_text|_timing)?\s+"` matches `check_ratio`, wants + whitespace, finds `_needs...`, backtracks to the empty option, wants whitespace + after `check`, and fails. Measured on the fixture below: the old form reads + `['short']`, the current one reads `['short', 'long']`. + + WHAT THIS ARM DOES NOT HOLD, said out loud because the code reads as though it + does: the entries are listed longest-first, and that ordering is NOT load-bearing. + Python's `re` backtracks across alternatives, so a PURE REORDER putting + `check_ratio` first reads both names identically -- measured, and this arm stays + green under it. The order is the thing that looks decisive and is not; the pattern + SHAPE is the thing that is. + """ + import re as _re + from compare_to_bash import _BASH_PATTERN + src = ('\tcheck_ratio "the short one" "$a" "$b" 2\n' + '\tcheck_ratio_needs_quiet_machine "the long one" "$a" "$b" 2\n') + got = _re.findall(_BASH_PATTERN, src) + expect.text(", ".join(sorted(got)), "the long one, the short one", + "both are read; the longer name is not eaten by the shorter") + + +def test_the_suite_local_helpers_are_known_and_excluded(expect): + """Four helpers are defined by ONE suite each, and the extractor does not read + them. That is a scope decision and it is asserted rather than left implicit. + + `compare_to_bash.py` grades a `test/.sh` against a + `test/pytest/test_.py`. None of the four suites defining its own helper + has a pytest twin, so none is graded and the exclusion costs nothing TODAY. + The day one of them is ported, this arm is what says the grader cannot see it. + + The population is `check_`, which is not the same as "starts with + check": `checks_in` in `decode_interrupts.sh` is a COUNTING utility returning a + number of interrupt checks in a function body, and records nothing. It was in + this list until the arm printed it and the definition was read. + """ + root = HERE.parent + local = {} + for sh in sorted(root.glob("*.sh")): + if sh.name == "lib.sh": + continue + for h in re.findall(r'^(check_[a-z_]+)\(\)\s*\{', sh.read_text(), re.M): + local.setdefault(h, sh.name) + expect.text(", ".join(f"{h} ({f})" for h, f in sorted(local.items())), + "check_float (parquet_export_stats.sh), " + "check_reconstruct (parallel_copy.sh), " + "check_split_happened (parallel_copy.sh), " + "check_structure (parallel_copy.sh)", + "the suite-local helpers are exactly these four") + twinned = [f for h, f in local.items() + if (HERE / f"test_{f[:-3]}.py").exists()] + expect.num(len(twinned), 0, + "and none of their suites has a pytest twin, so none is graded today") + + def test_the_ported_suites_in_this_tree_are_graded_one_for_one(expect): """THE STANDING ARM, and the reason this file is not only about fixtures. From a834fe85c8eebd955368a06ef220985636cfda8f Mon Sep 17 00:00:00 2001 From: "Joshua D. Drake" Date: Sun, 13 Sep 2026 12:29:50 -0600 Subject: [PATCH 2/3] test: declare the grader's guard in the harness-independence inventory (#432, #1040) CI's cluster leg failed on 57ed275 and the failure was MINE, not the environment. The drift guard reads the shell harness's helper library by a hard-coded path: lib = (HERE.parent / "lib.sh").read_text() which is a python file naming a shell path, so test_the_harness_independence_inventory_is_exactly_what_the_corpus_does reddened: four declared crossings in the tree, five found. Reproduced locally against a clean main as a control. On main only test_a_cluster_test_still_needs_the_driver fails here, which is this host having no driver; with the branch, that plus the inventory arm. So the inventory arm is the branch's and the driver arm is the box's. DECLARED RATHER THAN REDESIGNED, and this is a judgement about the owner's standing rule rather than a mechanical fix. The inventory is the designed mechanism for a crossing that earns itself: it is asserted in BOTH directions, so a declaration that stops being true reddens too, and each entry must carry the mechanism a reader can check by hand. The justification here is the same shape as pgc_cluster.py's -- crossing exists so there is one implementation rather than two. The alternative is a hand-written copy of the helper list inside pytest, which is exactly the value #1040 is about: five of eight helpers had been unreadable since the pattern shipped, and nothing said so. THE ALTERNATIVE READING, which I am not taking but a reviewer may prefer. The assertion "the grader's helper list matches the definitions" is arguably owned by the side that OWNS those definitions, and the shell selftest already reads repo files including python tools. Moving it there would avoid the python-to-shell crossing entirely rather than declaring it. That is a larger change and a different PR; @OffgridwithJD has offered to argue it and I would rather the decision were visible than quietly made. The entry names no file, deliberately: the comment above the declaration records that spelling the helper library's path in a description made the detector flag its own file, reporting four crossings where the tree had three. Guard half unchanged at 316 collected, 784 checks, 784 pass + 0 fail + 0 unrun. docs_style.sh 14 PASSED. No test added, so no count moves. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01NhwXKAgSmYDUjteWkfajHK --- test/pytest/test_harness_deps.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/pytest/test_harness_deps.py b/test/pytest/test_harness_deps.py index 4ef25dd3..9baf86f8 100644 --- a/test/pytest/test_harness_deps.py +++ b/test/pytest/test_harness_deps.py @@ -1144,6 +1144,12 @@ def test_the_job_installs_no_database_driver(expect): "test_mutation_ledger.py": "executes the matrix runner with its list flag to get the registered suite " "list, which is the same mechanism the entry above uses", + "test_compare_to_bash.py": + "reads the shell harness's helper library to re-derive the parity tool's " + "check-helper list from the definitions themselves, so the list the grader " + "matches on cannot become a hand-maintained copy that rots apart from it " + "(#1040, where five of eight helpers had been unreadable since the pattern " + "shipped)", } _SHELL_NAMES = re.compile( From ea5a6cb532c7e18dba90d3efdd2f324ca8a23de0 Mon Sep 17 00:00:00 2001 From: "Joshua D. Drake" Date: Sun, 13 Sep 2026 14:30:05 -0600 Subject: [PATCH 3/3] docs: record that the independence scan's scope is deliberate (#432, #1040) The harness-independence inventory scans `test/pytest/*.py`. That population is a LOCATION, and nothing said whether the location was the point. @OffgridwithJD inferred from it that `.github/scripts/` is exempt by design -- two tools there read `test/*.sh` and appear in no inventory -- and concluded that MOVING compare_to_bash.py there would delete its crossing rather than declare it. The conclusion may be right; the inference was not available from the evidence. Absent-from-the-report and outside-the-scan produce identical output. jd ruled today: the scope IS deliberate. The inventory is the pytest corpus's self-guard, and tooling under `.github/scripts/` belongs to neither harness -- it is CI's, and a tool there reading both sides is what it is for. So those two tools are OUT OF SCOPE rather than exempt, and the ruling is now in the file instead of inferable from a glob. The comment also records the consequence, because it is the part a reader acts on: under this reading a move to `.github/scripts/` is defensible on design grounds, since that is where cross-harness tooling lives -- but never because it makes this arm stop reporting the file. "The guard stops mentioning it" is the worst available reason to move anything. Same defect shape as #1040 itself, one level up: a population named by where things live rather than by what they do. There it was `check*` against "calls pgc_record"; here it is `test/pytest/*.py` against "python that reaches into shell". The difference is that this one is now intentional and says so. Comment only. Guard half unchanged at 316 collected, 784 checks, 784 pass + 0 fail + 0 unrun. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01NhwXKAgSmYDUjteWkfajHK --- test/pytest/test_harness_deps.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/pytest/test_harness_deps.py b/test/pytest/test_harness_deps.py index 9baf86f8..bee165dc 100644 --- a/test/pytest/test_harness_deps.py +++ b/test/pytest/test_harness_deps.py @@ -1127,6 +1127,18 @@ def test_the_job_installs_no_database_driver(expect): # rather than by pattern, which is the only way to tell the first from a string the # code actually passes to bash. +# THE SCAN IS THIS DIRECTORY, AND THAT IS DELIBERATE (jd, 2026-09-13). The inventory is +# the PYTEST CORPUS'S SELF-GUARD. Tooling under `.github/scripts/` belongs to neither +# harness -- it is CI's, and a tool there reading both sides is what it is for -- so it +# is out of scope rather than exempt, and two such tools do read `test/*.sh` today. +# +# Recorded because the distinction is invisible from the output and was inferred wrongly +# once: absent-from-the-report and outside-the-scan produce identical evidence, and a +# reader who meets the second and concludes the first will also conclude that MOVING a +# file to `.github/scripts/` deletes its crossing. Under this reading a move there is +# defensible on design grounds -- that is where cross-harness tooling lives -- but never +# because it makes this arm stop reporting the file. +# # THE DESCRIPTIONS NAME NO FILE, and that is not squeamishness: the first version # spelled the helper library's path in them, and the detector flagged THIS file for its # own inventory -- four files where the tree has three. The mechanism is what the entry