The bashrs gate stopped the 0.67.0 train twice in four hours, both times on findings that a PR had introduced and nothing had checked.
| time |
findings |
introduced by |
| 17:33Z |
9 SEC/DET/IDEM over 293 files |
#3115 and #3127 |
| 20:58Z |
2 SEC010, same file family |
#3187, merged four hours after #3188 cleared the first nine |
Cause. The bashrs gate lives inside scripts/dogfood.sh, and no CI job runs bashrs on a pull request. grep -rn bashrs .github/workflows/ finds the bashrs job, but nothing enforces the SEC/DET/IDEM class per PR. So any PR may add findings freely, and they surface only when a release train reaches its pre-publish gate, where they are maximally expensive: the train is already cut, the tag is waiting, and the fix has to go round the merge queue.
This is the "gate that fires at the worst moment" shape. The gate is correct; its placement is not.
Ask: run the same enumeration and the same SEC/DET/IDEM filter on every PR, as a required check. The gate's own logic in dogfood.sh already does the hard parts and should be lifted into a script both callers share:
Second defect: bashrs fix corrupts scripts
Measured on scripts/check_roadmap_diff_additive.sh with bashrs 7.3.0. It reported fixed 21 issues and produced a file that is not valid shell:
- trap 'rm -rf -- "${TD:?}"' EXIT
+ trap "rm -rf -- "${TD:?}"" EXIT
- assert_row 'append one entry' PASS "$TD/append.yaml" 'added=1'
+ assert_row 'append one entry" PASS "$TD/append.yaml" "added=1'
It swapped the quote characters inside five assert_row calls, turning working code into a syntax error, and rewrote a correct trap into a broken one. This is a data-loss-class bug in a tool the release gate depends on: anyone who runs bashrs fix on a repo script and commits the result ships broken shell.
Both belong upstream in paiml/bashrs; filing here because this repo is where both were measured and where the release keeps paying for them.
Third, smaller: SEC010 does not honour an intervening validation
Measured twice tonight. On a cd "$var" site, adding a real validation of $var immediately before the cd does not clear SEC010, while changing how $var was assigned does, with no check at all:
| form |
SEC010 |
read -r v < f then validate then cd "$v" |
fires |
v=$(cat f) then cd "$v", no validation |
clean |
So the rule can be satisfied by a rewrite that adds no safety and refuses a change that does. Worth reporting with the rest.
The bashrs gate stopped the 0.67.0 train twice in four hours, both times on findings that a PR had introduced and nothing had checked.
Cause. The bashrs gate lives inside
scripts/dogfood.sh, and no CI job runs bashrs on a pull request.grep -rn bashrs .github/workflows/finds the bashrs job, but nothing enforces the SEC/DET/IDEM class per PR. So any PR may add findings freely, and they surface only when a release train reaches its pre-publish gate, where they are maximally expensive: the train is already cut, the tag is waiting, and the fix has to go round the merge queue.This is the "gate that fires at the worst moment" shape. The gate is correct; its placement is not.
Ask: run the same enumeration and the same SEC/DET/IDEM filter on every PR, as a required check. The gate's own logic in
dogfood.shalready does the hard parts and should be lifted into a script both callers share:git ls-filesand assert N, so a.bashrsignorecannot silently zero itSecond defect:
bashrs fixcorrupts scriptsMeasured on
scripts/check_roadmap_diff_additive.shwith bashrs 7.3.0. It reportedfixed 21 issuesand produced a file that is not valid shell:It swapped the quote characters inside five
assert_rowcalls, turning working code into a syntax error, and rewrote a correcttrapinto a broken one. This is a data-loss-class bug in a tool the release gate depends on: anyone who runsbashrs fixon a repo script and commits the result ships broken shell.Both belong upstream in paiml/bashrs; filing here because this repo is where both were measured and where the release keeps paying for them.
Third, smaller: SEC010 does not honour an intervening validation
Measured twice tonight. On a
cd "$var"site, adding a real validation of$varimmediately before thecddoes not clear SEC010, while changing how$varwas assigned does, with no check at all:read -r v < fthen validate thencd "$v"v=$(cat f)thencd "$v", no validationSo the rule can be satisfied by a rewrite that adds no safety and refuses a change that does. Worth reporting with the rest.