fix(bin): repair fm-brief.sh for macOS Bash 3.2 and guard bin/ scripts in CI#979
Open
hnvivek wants to merge 2 commits into
Open
fix(bin): repair fm-brief.sh for macOS Bash 3.2 and guard bin/ scripts in CI#979hnvivek wants to merge 2 commits into
hnvivek wants to merge 2 commits into
Conversation
The three ship-mode Definition-of-done blocks built the brief text with `DOD=$(cat <<EOF ... EOF)` nested inside `case`. Bash 3.2's lexer loses quote state across a heredoc-in-$(...) inside `case`, so a single apostrophe anywhere in the body (reintroduced in kunchenguid#945) aborted the whole script with "unexpected EOF while looking for matching ')'". The scout and secondmate paths use a plain `cat > file <<EOF` redirect (no $(...)) and were unaffected. Rewrite each DOD block as `IFS= read -r -d '' DOD <<EOF || true` plus a single `${DOD%$'\n'}` strip. Byte-for-byte identical brief output proven against the bash-5 baseline for no-mistakes, direct-PR, local-only, and scout scaffolds, under both /bin/bash 3.2 and bash 5. Also extend the existing macos-stock-bash CI job to loop /bin/bash -n over every bin/*.sh and bin/backends/*.sh, so any future bash-3.2-only syntax regression in any tracked shell script fails before merge.
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.
Intent
Repair fm-brief.sh so it parses under stock macOS Bash 3.2 (regression introduced in PR #945), and add CI protection so the same class of bash-3.2-only syntax regression in any tracked bin/ shell script is caught before merge.
What Changed
bin/fm-brief.shthat failed to parse under stock macOS Bash 3.2 (regression introduced in PR fix: enforce contract boundaries for ask-user findings #945)./bin/bash -nacross all trackedbin/*.shandbin/backends/*.shscripts so bash-3.2-only syntax regressions are caught before merge./bin/bash -n, pinning the check to the macOS stock shell instead of a brew Bash 5.Risk Assessment
✅ Low: Well-bounded regression fix verified to produce byte-identical brief output under bash 3.2 and bash 5, with the same class of bug now blocked by an expanded macOS-stock-bash CI loop over every tracked bin/*.sh script.
Testing
On macOS stock Bash 3.2.57: regressed base fm-brief.sh reproduces the issue-#958 parse error, target fm-brief.sh parses clean, end-to-end scaffolds for all three delivery modes produce byte-correct DOD output under /bin/bash, and the new CI loop passes all 92 tracked bin/ scripts while faithfully catching the actual pre-fix fm-brief.sh as a regression.
Evidence: Negative CI-loop test (catches the actual pre-fix fm-brief.sh)
bin/fm-brief-regressed.sh: line 314: unexpected EOF while looking for matching `)' bin/fm-brief-regressed.sh: line 388: syntax error: unexpected end of file ::error::bin/fm-brief-regressed.sh fails /bin/bash -n (bash 3.2 parse regression) FAIL (correct: regression caught)Evidence: fm-brief.sh direct-PR mode stdout (target fix, stock /bin/bash 3.2)
Evidence: fm-brief.sh local-only mode stdout (target fix, stock /bin/bash 3.2)
Evidence: fm-brief.sh no-mistakes (default) mode stdout (target fix, stock /bin/bash 3.2)
Evidence: Extracted DOD body — direct-PR brief
Evidence: Extracted DOD body — local-only brief
Evidence: Extracted DOD body — no-mistakes brief
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
/bin/bash -n bin/fm-brief.sh(target) — parses OK under macOS stock Bash 3.2.57/bin/bash -n bin/fm-brief.sh(base commit 10ee779, restored) — reproduces issue #958:line 314: unexpected EOF while looking for matching)`'/bin/bash -c '… loop …'againstbin/*.sh bin/backends/*.sh— all 92 tracked scripts parse OKNegative CI-loop test: loop vs. the actual pre-fix fm-brief.sh — caught with::error::… fails /bin/bash -nand exit 1End-to-end:/bin/bash bin/fm-brief.sh <id> <project>for each of directproj / localproj / defaultproj (via a scratch projects.md registry) — all exit 0, briefs contain correct DOD body per mode, trailing newline correctly stripped (no blank line)FM_HOME=<scratch> /bin/bash bin/fm-project-mode.sh <project>— resolves direct-PR / local-only / no-mistakes correctly for the three fixturesdocs/arm-pretool-check.md:249- docs/arm-pretool-check.md:249, docs/subagent-guard.md:352, and docs/cd-guard.md:133 each show a scoped local-validation snippetbash -n bin/<one-script>.sh. This change establishes a principle in CONTRIBUTING.md:73 that local syntax checks should use/bin/bash -nto pin macOS to stock Bash 3.2. These three snippets still use plainbash -n, which on a macOS machine with brew Bash 5 would not catch a bash-3.2-only regression. They are not factually stale (bash -n still validates syntax) and serve a different purpose than the CONTRIBUTING toolbelt loop, so they are out of this change's scope, but a follow-up could align them with the new principle for consistency.✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.