Skip to content

bashrs gates the release but never a PR — it stopped the 0.67.0 train twice in four hours; and bashrs fix corrupts scripts #3196

Description

@noahgift

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High prioritybugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions