fix(gate-65, shellcheck): restore the required check — a whole-repo gate fires inside every fixture - #384
Merged
Merged
Conversation
ShellCheck has been red on main since 2026-08-03 on a single finding, and
because the required check runs against the PR MERGE ref it fails every open
PR — including six queued gate fixes that never touched this file.
All 15 probe callers pass their planted defect as ONE quoted shell string
('rm .php-cs-fixer.dist.php', "sed -i 's|...|...|' composer.json"), so the
string form is what the helper always meant; eval "$@" only looked
array-shaped.
Verified both arms of the suite: 23 passed / 0 failed before and after. That
is a real control, not a tautology — had eval stopped executing, the defect
would go unplanted and each probe would report 'did not detect'.
`Package invariants` — a REQUIRED check — has been red on main since 09:38 today, so the six queued gate PRs cannot merge. Both failures trace to gate-65 (coding-standard-adoption), added in #382. gate-65 is deliberately not diff-scoped: it judges the repo's standing configuration. Its only NOT-APPLICABLE path is "no composer.json and no phpcs.xml", and every synthetic fixture in the corpus HAS a composer.json, because the gate under test needs one. So it fires inside other suites' fixtures and fails runs those suites require to be green. A whole-repo gate is a global mutation of every other gate's test environment. test_gate_license_triangle_scope.sh — the fixture now adopts the standard the same way the compliant scaffold in test_check_coding_standard_adoption.sh does (require-dev, cs:check/cs:fix, .php-cs-fixer.dist.php, and an .editorconfig with indent_style = tab). Arm 6 needed the same treatment separately: it rewrites composer.json down to a bare name to drop the licence field, which also un-adopts the standard — that arm is the CONTROL that makes assertion 5 mean anything, so it silently proving nothing was the worse of the two failures. test_gate_acceptance_matrix.sh — gate-65 gets its COVERED-ELSEWHERE.md row. It is not uncovered: test_check_coding_standard_adoption.sh plants 15 single-defect probes, one per rule, plus a negative control and a wiring assertion. That is what the ELSEWHERE list is for. Verified: license-triangle 11 PASS / 0 FAIL, acceptance matrix green (13 gates counted as covered elsewhere, was 12), and the full helper suite on this branch is 76 passed / 2 quarantined / 0 failed.
…heredoc My own previous commit reintroduced a ShellCheck finding while fixing one. The .php-cs-fixer.dist.php body is PHP and contains $config; written as printf with single quotes, ShellCheck reads it as a shell expansion that will not expand. A <<'PHP' heredoc says verbatim to the shell and to the reader at once, and matches how the sibling scaffold already writes the same file. Re-verified: license-triangle 11 PASS / 0 FAIL.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this is urgent
Package invariants— one of the three REQUIRED checks onmain— has been redsince 09:38 today. Six queued gate PRs (#373, #376, #377, #378, #379, #380) cannot
merge, and none of them caused it.
Two independent things were red. Only one was blocking, and it was not the one that
looks scarier in the checks list.
1. gate-65 fires inside every other suite's fixture (the blocker)
gate-65 coding-standard-adoption(#382) is deliberately not diff-scoped — it judgesthe repo's standing configuration, which is right for its purpose. But its only
NOT-APPLICABLE path is "no composer.json and no phpcs.xml", and every synthetic
fixture in the corpus has a composer.json, because the gate under test needs one.
So it fires inside other suites' fixtures and fails runs those suites require to end
green:
test_gate_license_triangle_scope.sh— 2 assertions, one of them the control thatmakes assertion 5 mean anything, died on
status 1test_gate_acceptance_matrix.sh— gate-65 declared with neither fixture nor reasoned rowThe general lesson, worth writing down: a whole-repo gate is a global mutation of every
other gate's test environment. Diff-scoped gates decline inside fixtures they do not
concern; a whole-repo gate cannot, so it quietly becomes a precondition of every "and the
run ends green" assertion in the corpus.
Fixes
Fixture adopts the standard — mirroring the compliant scaffold already in
test_check_coding_standard_adoption.sh:require-dev,cs:check/cs:fix,.php-cs-fixer.dist.php, and an.editorconfigwithindent_style = tab.Arm 6 needed the same fix separately. It rewrites
composer.jsondown to a bare nameto drop the licence field — which also un-adopts the standard. That arm is the control
for assertion 5, so it silently proving nothing was the worse of the two failures.
gate-65 gets its
COVERED-ELSEWHERE.mdrow. It is not uncovered:test_check_coding_standard_adoption.shplants 15 single-defect probes, one per rule,plus a negative control and a wiring assertion. That is precisely what the ELSEWHERE list
exists for — not an exemption.
2. ShellCheck SC2294 (not required, but red for 9 days)
eval "$@"→eval "$*"in theprobe()helper. All 15 callers pass their planteddefect as one quoted shell string, so there was never an array to preserve;
ShellCheck names the string form explicitly. Checked all 15 call sites — none passes more
than one argument, so
$*'s IFS join cannot change any of them.Verification
test_gate_license_triangle_scope.shtest_gate_acceptance_matrix.shtest_check_coding_standard_adoption.shorigin/maintest_gate_45_to_55_acceptance.shrefuses to run without
ajv(exit 2) rather than emit a false verdict, andrequire('ajv')resolves upward — so it runs from an in-tree checkout and refuses from a
/tmpworktree. The main-branch run above was made in a
/tmpworktree and this one hadNODE_PATHset. Real defects fixed: 2, which is exactly what CI reported.