posix_script_gate uses a WHOLE-FILE predicate for a call-scoped hazard: a file that merely quotes a script path beside an unrelated Command::new becomes an offender #244
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#244
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by the #239 lane while adding a test that executes a checked-in script. The gate was right about the code actually written, so this cost nothing real — but the population rule is wrong in a way that will bite a future lane, and its only escape hatch is the thing the same message tells you not to use.
The fact
posix_script_gate::no_test_spawns_a_checked_in_script_as_an_imagedecides membership with a whole-file predicate — roughlycode.contains("Command::new")— for a hazard that is call-scoped: spawning a checked-in.shas a process image.crates/indexer/tests/release_gate.rshas spawnedgitandbashfor unrelated reasons since long before #239. The moment that change put the string.forgejo/scripts/require_fixtures_graded.shinto the file, it became an offender — with no script being spawned anywhere in it.So the gate's population is "files containing a
Command::newanywhere AND a script path anywhere", which is not the same set as "files that spawn a checked-in script", and the two only coincide today by luck.Why it is worth fixing rather than living with
Two properties compound:
gitfor a fixture and mentions a.forgejo/scripts/...path in an assertion message, a doc comment, or a parsed constant joins the population. Neither of those facts is the hazard.#![cfg(unix)]on the whole file — and the gate's own message tells you not to reach for that, because it silently removes the file from Windows coverage. So a lane that trips it falsely is pushed toward the exact remedy the gate exists to discourage.That combination is what makes it worth a number: a gate whose false-positive path leads to a worse tree than not having the gate.
What must NOT be done
.shas a process image is a real portability defect and the gate has earned its place. This is about who is in the population, not about what the rule says.release_gate.rs. An exemption list for a file that is not an offender records a wrong fact and rots.*_gate.rs" or similar. The hazard is not correlated with a filename.Shape of a fix
Scope the predicate to the call, not the file: an offender is a
Command::new(...)whose argument resolves to a checked-in script path, not a file that contains both tokens somewhere. This tree has precedent for exactly that narrowing —#180's fix established that "the defect is the SCOPE, not the spelling", and thedispatch_arm_bodiessplitter inargument_registry_e2eis the worked example of scoping a scan to the unit that can actually contain the fault.A cheap intermediate, if full call-scoping is too much: require the script path and the
Command::newto be within one statement or one function body of each other, the same way #239's own fixture-count predicate ended up requiring the number to sit within three tokens of the word it counts.What a fix must prove
.shas an image is still flagged — the hazard's own arm must survive, and this is the one that matters.git/bashfor unrelated reasons and separately mentions a script path is not flagged. That is the exact shaperelease_gate.rshas today, so it is a real fixture, not a synthetic one.#![cfg(unix)]as part of the fix.Related
#204 (a scan over real inputs is structurally incapable of noticing its own predicate has gone vacuous), #180 (the defect is the scope, not the spelling — its token had 41 legitimate users), #239 (where this surfaced).
Filed 2026-09-09 against
master34b0fd5.Fixed by
8fff4e0("posix_script_gate grades the CALL, not the file") and0a42731("a QUOTED call is not a call"), merged at12dfbcb. Closing late — the fix shipped and the issue was never closed.Verified in the tree, not just in the commit subjects:
crates/indexer/tests/posix_script_gate.rs:817builds the quoted-call fixture and asserts the gate does not grade it —so the call-scoped predicate is graded by a fixture that a whole-file predicate would have failed.