Skip to content

Match action inputs on a word boundary, not as substrings - #4

Merged
barnumbirr merged 1 commit into
masterfrom
tech/close-vacuous-green-guards
Sep 17, 2026
Merged

barnumbirr merged 1 commit into
masterfrom
tech/close-vacuous-green-guards

Conversation

@barnumbirr

Copy link
Copy Markdown
Contributor

The input-coverage check in tests/lint-action.sh tested f"inputs.{name}" not in piped, a plain substring match. An input whose name is a prefix of another's therefore reported as covered while never reaching the step: path is a substring of a piped pathspec. Today's five names happen not to collide, so nothing is dead surface right now — the guard was. Its own comment calls an unpiped input dead surface, and this is the check that exists to find one. Verified both directions: an injected unpiped path input now fails the lint and passed it before.

git diff --cached --quiet returns 128 on error, not only 0 and 1, and 2>/dev/null discarded the reason. On an unborn HEAD the suppressed message is fatal: ambiguous argument 'HEAD' and the script proceeded as though there were changes, failing one step later at rev-parse.

The staging branch on PATHSPEC guarded nothing. Both diffs below it already pass the same possibly-empty array through -- "${PATHSPEC[@]}" with no guard, and an empty expansion after -- is what passing no pathspec means. The diff computation the GraphQL mutation depends on is untouched, so deletions stay complete.

The suite cleaned up its scratch directories in three of six groups and left them in the other three, leaking three per run. One scratch root exported as TMPDIR puts all six under the trap that already existed; /tmp delta is now 0. Removed a fixture loop whose only case arm is empty, over a --data@ spelling the caller never produces, and two || true under a harness that sets -u without -e and ends each group with its own explicit exit.

dependabot.yml claimed actions here are pinned to commit SHAs. The one action is actions/checkout@v7, first-party on a major tag deliberately. The same sentence appears in seven other repos' configs and is wrong in all of them; only infrastructure SHA-pins anything.

Not applied, deliberately: tests/lint-action.sh lints the extracted run: body with whatever shellcheck is on PATH while ci.yml uses a digest-pinned image for the .sh files — a real inconsistency, since the inline body is the code no other linter sees. The fix needs the body file reachable from inside a container, and I could not verify that path without a test push. Flagging rather than shipping it unverified.

Verified: 13 assertions, lint-action.sh clean, shellcheck clean, actionlint clean.

The input-coverage check tested `f"inputs.{name}" not in piped`, so an
input whose name is a prefix of another's reported as covered while
never reaching the step: "path" is a substring of a piped "pathspec".
Today's five names happen not to collide, so nothing is dead -- the
guard was. Its own comment calls an unpiped input dead surface, and this
is the check that was supposed to find one.

Verified both directions: an injected unpiped `path` input now fails the
lint, and passed it before.

Also here:

git diff --cached --quiet returns 128 on error, not just 0 and 1, and
2>/dev/null threw away the reason. On an unborn HEAD the suppressed
message is "fatal: ambiguous argument 'HEAD'" and the script proceeded
as though there were changes, failing one step later at rev-parse.

The staging branch on PATHSPEC guarded nothing: both diffs below it pass
the same possibly-empty array through `-- "${PATHSPEC[@]}"` with no
guard, and an empty expansion after -- is what passing no pathspec
means. Three usage strings that disagreed about [pathspec ...] are now
one.

The suite kept its scratch directories in three of six groups and left
them in the other three, so every run leaked three; one scratch root
exported as TMPDIR puts all six under the trap that already existed.
Removed a fixture loop whose only case arm is empty, over a --data@
spelling the caller never produces, and two `|| true` under a harness
that sets -u without -e and ends each group with its own exit.

dependabot.yml claimed actions here are pinned to commit SHAs. The one
action is actions/checkout@v7, first-party on a major tag deliberately.

Verified: 13 assertions, lint-action.sh clean, shellcheck clean,
actionlint clean, /tmp delta 0 (was 3).
@barnumbirr
barnumbirr merged commit b5086e9 into master Sep 17, 2026
1 check passed
@barnumbirr
barnumbirr deleted the tech/close-vacuous-green-guards branch September 17, 2026 13:32
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