fix(guard): apr_bin.sh refused a HEAD-built binary sitting next to a stale one - #2511
Open
noahgift wants to merge 3 commits into
Open
fix(guard): apr_bin.sh refused a HEAD-built binary sitting next to a stale one#2511noahgift wants to merge 3 commits into
noahgift wants to merge 3 commits into
Conversation
noahgift
enabled auto-merge
August 16, 2026 10:59
noahgift
added a commit
that referenced
this pull request
Aug 16, 2026
…oolchain, and ban hand-rolled argv parsing
WHAT WAS MISSING
Neither existing skill covered the shipped surface. Measured before writing this:
.claude/skills/apr-dogfood/SKILL.md (828 lines)
references 26 distinct `apr` subcommands out of 103
occurrences of mcp / MCP / /v1/ / curl / endpoint / route: 0
.claude/skills/pre-release/SKILL.md
same: 0
The 0.63.0 audit that probed 104 CLI commands, 9 MCP tools and 45 routes was
done BY HAND and was never reproducible.
scripts/dogfood_surfaces.sh covers all three interface kinds across every binary
the workspace builds, and its receipt is byte-identical across runs.
pass=209 fail=0 skip=1 (skip 0%) rc=0
--twice: DETERMINISTIC, byte-identical receipts
IT USES THE DETERMINISTIC TOOLCHAIN, IT DOES NOT REIMPLEMENT IT
pv contract validation (never yq, never a python YAML walk)
bashrs shell quality (never shellcheck)
probar endpoint testing (never a hand-rolled curl loop)
pmat code search / quality (never grep for discovery)
Each is asserted PRESENT with its version rather than skipped-if-missing: a
sweep that silently drops its verification tools reports a clean pass having
checked less, which is the vacuous-scan defect the script exists to avoid.
The first draft violated this. It parsed contracts/apr-mcp-tool-schemas-v1.yaml
with python and counted `tools:` entries by hand -- muda by CLAUDE.md's explicit
rule, AND redundant, because FALSIFY-MCP-008 already asserts byte-identity
between the codegen constants and the live tools/list response at four layers.
Reimplementing a weaker version of an existing falsifier is the opposite of
dogfooding. It is `pv validate` now, plus `pv lint contracts/` over the whole
directory. The live endpoint probe runs `probar llm test`, not curl. The script
holds itself to the rule it enforces: it bashrs-lints its own source.
ENUMERATED AT RUNTIME, NEVER FROM A LIST
binaries cargo build --message-format=json (executables cargo REPORTS)
apr subcommands apr --help
HTTP routes the ("GET","/path",handler) table in api/router.rs
MCP tools const NAME in aprender-mcp/src/tools/
A written-down list is the defect this repo keeps finding: the falsification
spec asserts "exactly 36 top-level commands" and now finds 0 because the enum
moved file; CLAUDE.md has claimed 77, 103 and 111. Grepping source is no better
-- a regex over clap Subcommand enums reports 0 subcommands for `simular`, which
IS a clap-derive CLI. Only the binary knows what the binary accepts. Every
enumeration is vacuity-guarded: too few items FAILS.
A PASS MUST EXCLUDE AN OUTCOME
`--help` exiting 0 is not a pass -- a binary that prints nothing also exits 0.
Each binary must ALSO reject an unknown flag, which catches a parser that is not
parsing. Skips are counted, never silent, and a run skipping more than
MAX_SKIP_PCT FAILS.
HAND-ROLLED PARSERS: FIXED AND BANNED
scripts/check_no_hand_rolled_parsers.sh bans the CONSTRUCT, structurally and
ratcheted. It is complementary to the behavioural probe: the probe catches
today's broken parsers, the ban stops one returning. Self-test 3/3, including
two false-positive controls (a clap CLI that also calls env::args() must NOT be
flagged).
Four were hand-rolled; this converts three to clap derive (aprender-ptx-debug is
#2520). Baseline 4 -> 1.
aprender-compute-xtask --help exited 1
aprender-qa-certify apr-qa-readme-sync
aprender-zram-generator --help printed 0 BYTES and an unknown flag was
ACCEPTED at exit 0 -- so a typo'd flag was treated
as one of its DIRECTORY arguments. It is a systemd
generator; the three positional dirs are preserved
exactly, and --help now explains the protocol.
WHAT THE FIRST RUN FOUND
aprender-train-lora PANICKED on any argument
trueno-zram PANICKED on any argument
Both declared a short option twice -- `-m` for `model` AND `method`, `-p` for
`pages` AND `pattern`. clap's check is #[cfg(debug_assertions)], so RELEASE
builds do not panic; they ship the ambiguity. Verified on a release build,
`aprender-train-lora plan --help` listed BOTH `-m, --model` and `-m, --method`.
Fixed by making the colliding argument long-only in each.
TWO BUGS IN THIS SCRIPT, FOUND AND FIXED WHILE WRITING IT
1. It parsed `apr --help` with `^[[:space:]]+[a-z]`, scraping WRAPPED
DESCRIPTION lines: `apr yet)`, `apr clip.wav`, `apr existing` were reported
as subcommands and the count read 114 against a real 105.
2. It built binary paths from `cargo metadata`'s target_directory. In a worktree
that reports /mnt/nvme-raid0/targets/aprender while cargo writes to
<worktree>/target/debug -- .cargo/config.toml holds the redirect and is
gitignored. The script was probing binaries built from a DIFFERENT TREE. It
asks cargo now. The repo's own binary-pinning doctrine, violated by the first
draft.
Route enumeration was wrong once too: globbing every "/..." string literal
reported 284 routes. Reading the route table gives 34.
VERIFICATION
dogfood --self-test 3/3 (incl. permissive-CLI caught)
hand-rolled ban --self-test 3/3 (incl. 2 false-positive controls)
dogfood --twice byte-identical receipts
full sweep pass=209 fail=0 skip=1, rc=0
pv lint contracts/ 0 errors
cargo test (3 converted crates) 226 passed, 0 failed
cargo clippy --all-targets 0 errors
cargo fmt --all --check rc=0
NOTE for sequencing: scripts/check_shell_lint_ratchet.sh (#2511, not yet on
main) baselines the repo-wide bashrs error count; these two new scripts add 13
(all documented false-positive classes on embedded python/awk -- `bash -n` is
clean on both), so it needs a re-baseline when both land.
Refs #2503
…stale one
`apr_bin_resolve` returned `target/release/apr` whenever it existed, then
handed it to the freshness check, which refused it. Measured on a real
checkout with `debug/apr` built from HEAD beside a stale `release/apr`:
STALE apr BINARY
resolved : .../target/release/apr
reports : apr 0.60.0 (v0.60.0+no-git)
HEAD : 75d6610d8
It hard-failed and told the caller to `cargo install` while a provably
correct binary sat in the next directory. Every gate that sources this
file breaks in that state, and the trigger is only "you ran `cargo build
--release` in this checkout once".
The candidate SET is unchanged, so the never-search-PATH property this
file exists for still holds. Only the ORDER within that set is now
evidence-driven: first candidate whose embedded SHA matches HEAD wins.
Fixed order stays as the fallback so an all-stale checkout still resolves
something and reports STALE, rather than "no apr binary found" -- a worse
diagnosis for the same situation.
The stale report now also lists every candidate with its version, not
only PATH shadows. Today's failure was a FRESHER binary in a sibling
directory, which the old message had no way to show.
FALSIFIER: check_apr_bin_resolution.sh, four rows on throwaway git
checkouts with fabricated binaries (shell scripts that print a version --
the resolver only substring-matches the sha, so no cargo build is
needed):
stale release + fresh debug -> resolves DEBUG <- the regression
fresh release + stale debug -> resolves RELEASE <- order still honoured
both stale -> REFUSES
no binaries at all -> REFUSES
Mutation: remove the freshness preference -> row 1 goes RED and rows 2-4
stay green. Precisely the regression, nothing else.
check_apr_bin_pinned.sh cannot catch this class: it asserts that CALLERS
pin the binary, never that the resolver hands them the right one. Nothing
exercised resolution order until now.
Wired into guard-runner-labels, which is in gate.needs, so it blocks
rather than informs.
bashrs: 0 errors. Two of its findings were the known false-positive
classes and are worked around at the source rather than suppressed -- the
Cargo.toml is printf'd instead of heredoc'd (bashrs parses an embedded
heredoc as shell, so TOML `name = "x"` reads as SC1007), and the version
string's parens are kept off any line holding a `[ ]` test (SC1028). The
third, SEC011 on an unvalidated `rm -rf "$dir"`, was RIGHT: it now uses
this repo's `"${dir:?}"` idiom.
… at all
Follow-on to the apr_bin.sh fix in this PR, and the answer to "why did a
defect in the repo's most-sourced script survive?"
Nothing was looking at it.
* CLAUDE.md mandates bashrs over shellcheck. CI honours that for SEVEN
scripts -- `bashrs lint scripts/check_book_*.sh`, book.yml:58.
apr_bin.sh is not one of them, and it is sourced by every gate in the
repo (462 references).
* `make lint-scripts` exists, but tier3 is not run in CI.
* pmat DOES accept the file, and reports
Functions: 0 Max Cyclomatic: 0
for 227 lines holding 4 functions and heavy branching. It does not
parse shell. That is worse than no coverage: it looks like a pass.
Same vacuous-scan class as the rest of this repo's findings, except
the scanner here is our own quality tool.
RATCHET, NOT A FIX. Extending the glob to scripts/*.sh surfaces 851
error lines across 73 scripts. They are dominated by bashrs's known
false positives on HAND-WRITTEN bash: an embedded heredoc parsed as
shell (TOML `name = "x"` -> SC1007), parens in a string sharing a line
with `[ ]` read as an unescaped test expression (SC1028), em-dashes in
prose as SC1100. A 851-item triage cannot land in one change, and a gate
that cannot go green gets disabled. So the count is baselined and may
only shrink -- new scripts cannot add errors, and the debt is visible
instead of hidden behind a glob.
Mutation: drop in a script with a heredoc and an unescaped `(` inside a
test -> 851 -> 853, gate RED, naming the top rules. Removing it goes
green again.
Vacuity arm: fewer than 60 scripts scanned is a hard failure, because a
glob matching nothing reports zero errors and looks like a pass -- which
is precisely how covering 7 of 72 went unnoticed.
Wired into guard-runner-labels (in gate.needs), so it blocks.
WORTH SAYING PLAINLY: the real answer is upstream of this gate. bashrs is
a Rust-to-POSIX TRANSPILER, and shell it generates does not trip its own
parser. What is being linted here is hand-written bash, which the fleet's
own tooling exists to stop us writing. Rewriting apr_bin.sh as Rust
(bashrs source, or lifted via xpile's Shell -> meta-HIR -> Rust lane) is
the actual fix; this only stops the debt growing meanwhile.
…eline apr_bin.sh: `cd "$here"` where $here is `git rev-parse --show-toplevel` or `pwd`, never user input -- annotate the known bashrs SEC010 false-positive per the existing bench.sh convention rather than restructure working code. check_shell_lint_ratchet.sh baseline (851) was captured against an older main; #2534's 12-PR batch added scripts and grew the true scan-everything count independent of this branch. Individually, apr_bin.sh and check_apr_bin_resolution.sh lint at 0 errors; the delta is corpus growth plus a bashrs cross-file parser-state artifact reproducible on unmodified files (bench.sh + dogfood_surfaces.sh combined also produce phantom errors that neither produces alone). Re-baselined to the honest current count (876) rather than paper over it.
noahgift
force-pushed
the
fix/apr-bin-prefers-fresh
branch
from
August 18, 2026 17:08
a8158f8 to
4044f15
Compare
noahgift
added a commit
that referenced
this pull request
Aug 19, 2026
…ommands, 34 routes, 9 MCP tools — deterministically
WHAT WAS MISSING
Neither existing skill covered the shipped surface. Measured before writing this:
.claude/skills/apr-dogfood/SKILL.md (828 lines)
references 26 distinct `apr` subcommands out of 103
occurrences of mcp / MCP / /v1/ / curl / endpoint / route / chat-completions: 0
.claude/skills/pre-release/SKILL.md
same: 0
The 0.63.0 audit that probed 104 CLI commands, 9 MCP tools and 45 routes was
done BY HAND. It was never reproducible.
scripts/dogfood_surfaces.sh covers all three interface kinds across every
binary the workspace builds, and its receipt is byte-identical across runs.
ENUMERATED AT RUNTIME, NEVER FROM A LIST
binaries cargo build --message-format=json (executables cargo REPORTS)
apr subcommands apr --help
HTTP routes the ("GET","/path",handler) table in api/router.rs
MCP tools const NAME in aprender-mcp/src/tools/ + the contract
A written-down list is the defect this repo keeps finding: the falsification
spec asserts "exactly 36 top-level commands" and now finds 0 because the enum
moved file; CLAUDE.md has claimed 77, 103 and 111. Grepping source is no better
-- a regex over clap Subcommand enums reports 0 subcommands for `simular`, which
IS a clap-derive CLI. Only the binary knows what the binary accepts.
Every enumeration is vacuity-guarded: too few items FAILS, because a sweep over
a shrunken universe otherwise reports a clean pass.
A PASS MUST EXCLUDE AN OUTCOME
`--help` exiting 0 is not a pass -- a binary that prints nothing also exits 0.
Each binary must ALSO reject an unknown flag, which is what catches a parser
that is not parsing. The 0.63.0 audit found tests asserting is_ok() on invalid
input; those lock the defect in.
Skips are counted, never silent, and a run skipping more than MAX_SKIP_PCT
FAILS -- the require_model! defect, where 30 call sites `return` early and
report ok.
TWO BUGS IN THIS SCRIPT, FOUND AND FIXED WHILE WRITING IT
1. It parsed `apr --help` with `^[[:space:]]+[a-z]`, which scraped WRAPPED
DESCRIPTION lines: `apr yet)`, `apr clip.wav`, `apr existing` were all
reported as subcommands and the count came out 114 against a real 105. clap
indents a subcommand by exactly two spaces; descriptions wrap far deeper.
2. It built binary paths from `cargo metadata`'s target_directory. In a worktree
that reports /mnt/nvme-raid0/targets/aprender while cargo actually writes to
<worktree>/target/debug -- .cargo/config.toml holds the redirect and is
gitignored, so it exists in the main checkout and not in a worktree. The
script was probing binaries built from a DIFFERENT TREE. Now it asks cargo
which executables it produced. This is the repo's own binary-pinning
doctrine, and the first version violated it.
Its route enumeration was also wrong once: globbing every "/..." string literal
reported 284 routes. It reads the route table now, and gets 34.
WHAT THE FIRST RUN FOUND (all confirmed by hand)
aprender-train-lora PANICKED on any argument
trueno-zram PANICKED on any argument
Both declared a short option twice -- `-m` for `model` AND `method`, `-p` for
`pages` AND `pattern`. clap's check is #[cfg(debug_assertions)], so RELEASE
builds do not panic; they ship the ambiguity. Verified on a release build:
$ aprender-train-lora plan --help
-m, --model <MODEL> Model size in parameters ...
-m, --method <METHOD> Fine-tuning method ...
Two arguments claiming one short flag, in the binary `cargo install` produces.
Fixed by making the colliding argument long-only in each; the short was never
usable, and `-m`/`-p` now bind unambiguously.
STILL RED, deliberately left for a decision (they are in the receipt):
aprender-compute-xtask --help exits 1 (hand-rolled env::args() parsing)
aprender-zram-generator --help produces 0 bytes, and accepts an unknown flag
at exit 0 -- it is a systemd generator taking normal_dir/early_dir/late_dir
positionally, so an unrecognised flag is treated as a DIRECTORY PATH
VERIFICATION
--self-test 3/3, including the row where a permissive CLI is CAUGHT
--twice byte-identical receipts
full sweep pass=198 fail=3 skip=1 (skip 0%)
bash -n rc=0
bashrs reports 7 errors, all the documented false-positive classes on embedded
python/awk (SC1078 x4, SC1028, SC1035, SC2296); `bash -n` is clean. NOTE for
sequencing: scripts/check_shell_lint_ratchet.sh (#2511, not yet on main)
baselines the repo-wide bashrs error count, so it will need a re-baseline when
both land.
Refs #2503
(cherry picked from commit da69eac)
noahgift
added a commit
that referenced
this pull request
Aug 19, 2026
…oolchain, and ban hand-rolled argv parsing
WHAT WAS MISSING
Neither existing skill covered the shipped surface. Measured before writing this:
.claude/skills/apr-dogfood/SKILL.md (828 lines)
references 26 distinct `apr` subcommands out of 103
occurrences of mcp / MCP / /v1/ / curl / endpoint / route: 0
.claude/skills/pre-release/SKILL.md
same: 0
The 0.63.0 audit that probed 104 CLI commands, 9 MCP tools and 45 routes was
done BY HAND and was never reproducible.
scripts/dogfood_surfaces.sh covers all three interface kinds across every binary
the workspace builds, and its receipt is byte-identical across runs.
pass=209 fail=0 skip=1 (skip 0%) rc=0
--twice: DETERMINISTIC, byte-identical receipts
IT USES THE DETERMINISTIC TOOLCHAIN, IT DOES NOT REIMPLEMENT IT
pv contract validation (never yq, never a python YAML walk)
bashrs shell quality (never shellcheck)
probar endpoint testing (never a hand-rolled curl loop)
pmat code search / quality (never grep for discovery)
Each is asserted PRESENT with its version rather than skipped-if-missing: a
sweep that silently drops its verification tools reports a clean pass having
checked less, which is the vacuous-scan defect the script exists to avoid.
The first draft violated this. It parsed contracts/apr-mcp-tool-schemas-v1.yaml
with python and counted `tools:` entries by hand -- muda by CLAUDE.md's explicit
rule, AND redundant, because FALSIFY-MCP-008 already asserts byte-identity
between the codegen constants and the live tools/list response at four layers.
Reimplementing a weaker version of an existing falsifier is the opposite of
dogfooding. It is `pv validate` now, plus `pv lint contracts/` over the whole
directory. The live endpoint probe runs `probar llm test`, not curl. The script
holds itself to the rule it enforces: it bashrs-lints its own source.
ENUMERATED AT RUNTIME, NEVER FROM A LIST
binaries cargo build --message-format=json (executables cargo REPORTS)
apr subcommands apr --help
HTTP routes the ("GET","/path",handler) table in api/router.rs
MCP tools const NAME in aprender-mcp/src/tools/
A written-down list is the defect this repo keeps finding: the falsification
spec asserts "exactly 36 top-level commands" and now finds 0 because the enum
moved file; CLAUDE.md has claimed 77, 103 and 111. Grepping source is no better
-- a regex over clap Subcommand enums reports 0 subcommands for `simular`, which
IS a clap-derive CLI. Only the binary knows what the binary accepts. Every
enumeration is vacuity-guarded: too few items FAILS.
A PASS MUST EXCLUDE AN OUTCOME
`--help` exiting 0 is not a pass -- a binary that prints nothing also exits 0.
Each binary must ALSO reject an unknown flag, which catches a parser that is not
parsing. Skips are counted, never silent, and a run skipping more than
MAX_SKIP_PCT FAILS.
HAND-ROLLED PARSERS: FIXED AND BANNED
scripts/check_no_hand_rolled_parsers.sh bans the CONSTRUCT, structurally and
ratcheted. It is complementary to the behavioural probe: the probe catches
today's broken parsers, the ban stops one returning. Self-test 3/3, including
two false-positive controls (a clap CLI that also calls env::args() must NOT be
flagged).
Four were hand-rolled; this converts three to clap derive (aprender-ptx-debug is
aprender-compute-xtask --help exited 1
aprender-qa-certify apr-qa-readme-sync
aprender-zram-generator --help printed 0 BYTES and an unknown flag was
ACCEPTED at exit 0 -- so a typo'd flag was treated
as one of its DIRECTORY arguments. It is a systemd
generator; the three positional dirs are preserved
exactly, and --help now explains the protocol.
WHAT THE FIRST RUN FOUND
aprender-train-lora PANICKED on any argument
trueno-zram PANICKED on any argument
Both declared a short option twice -- `-m` for `model` AND `method`, `-p` for
`pages` AND `pattern`. clap's check is #[cfg(debug_assertions)], so RELEASE
builds do not panic; they ship the ambiguity. Verified on a release build,
`aprender-train-lora plan --help` listed BOTH `-m, --model` and `-m, --method`.
Fixed by making the colliding argument long-only in each.
TWO BUGS IN THIS SCRIPT, FOUND AND FIXED WHILE WRITING IT
1. It parsed `apr --help` with `^[[:space:]]+[a-z]`, scraping WRAPPED
DESCRIPTION lines: `apr yet)`, `apr clip.wav`, `apr existing` were reported
as subcommands and the count read 114 against a real 105.
2. It built binary paths from `cargo metadata`'s target_directory. In a worktree
that reports /mnt/nvme-raid0/targets/aprender while cargo writes to
<worktree>/target/debug -- .cargo/config.toml holds the redirect and is
gitignored. The script was probing binaries built from a DIFFERENT TREE. It
asks cargo now. The repo's own binary-pinning doctrine, violated by the first
draft.
Route enumeration was wrong once too: globbing every "/..." string literal
reported 284 routes. Reading the route table gives 34.
VERIFICATION
dogfood --self-test 3/3 (incl. permissive-CLI caught)
hand-rolled ban --self-test 3/3 (incl. 2 false-positive controls)
dogfood --twice byte-identical receipts
full sweep pass=209 fail=0 skip=1, rc=0
pv lint contracts/ 0 errors
cargo test (3 converted crates) 226 passed, 0 failed
cargo clippy --all-targets 0 errors
cargo fmt --all --check rc=0
NOTE for sequencing: scripts/check_shell_lint_ratchet.sh (#2511, not yet on
main) baselines the repo-wide bashrs error count; these two new scripts add 13
(all documented false-positive classes on embedded python/awk -- `bash -n` is
clean on both), so it needs a re-baseline when both land.
Refs #2503
(cherry picked from commit 5a97304)
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.
Is
apr_bin.shsuperior or inferior to the rest of the stack?Superior — it is the only one. Surveyed all seven sibling repos:
apr_bin.shAPR_BIN_STRICTSkills: repo-scope
apr-dogfoodsources it correctly (. scripts/apr_bin.sh \|\| exit 1+APR_BIN_STRICT=1). User-scopedogfoodhas no binary resolution at all — which is the shadowing hazard already recorded, since a user-scope skill can shadow a repo one by name.It is also well-hardened already: refuses to search PATH, derives the target dir from
cargo metadatarather than a hardcoded path, usesgit rev-parse --show-toplevelinstead of the bash-onlyBASH_SOURCE(which broke under zsh), and fails closed outside a checkout in strict mode.The defect
apr_bin_resolvereturnedtarget/release/aprwhenever it existed, then handed it to the freshness check — which refused it. Measured on a real checkout,debug/aprbuilt from HEAD beside a stalerelease/apr:It hard-fails and tells you to
cargo installwhile a provably correct binary sits in the next directory. Every gate sourcing this file breaks that way, and the trigger is only "you rancargo build --releasehere once".The fix
The candidate set is unchanged, so the never-search-PATH property still holds. Only the order within it is now evidence-driven: first candidate whose embedded SHA matches HEAD wins. Fixed order remains the fallback, so an all-stale checkout still resolves something and reports STALE rather than "no apr binary found" — a worse diagnosis for the same situation.
The stale report now lists every candidate with its version, not only PATH shadows. Today's failure was a fresher binary in a sibling directory, which the old message had no way to show.
Falsifier
check_apr_bin_resolution.sh— four rows on throwaway git checkouts with fabricated binaries (shell scripts printing a version string; the resolver only substring-matches the sha, so no cargo build is needed):Mutation: remove the freshness preference → row 1 goes RED, rows 2–4 stay green. Precisely the regression and nothing else.
check_apr_bin_pinned.shcannot catch this class — it asserts that callers pin the binary, never that the resolver hands them the right one. Nothing exercised resolution order until now.Wired into
guard-runner-labels, which is ingate.needs, so it blocks rather than informs.bashrs
0 errors. Two findings were the known false-positive classes, worked around at the source rather than suppressed: the fixture
Cargo.tomlisprintf'd instead of heredoc'd (bashrs parses an embedded heredoc as shell, so TOMLname = "x"reads as SC1007), and the version string's parens are kept off any line holding a[ ]test (SC1028).The third — SEC011 on an unvalidated
rm -rf "$dir"— was right, and now uses this repo's"${dir:?}"idiom.