fix(fm-brief): scaffold ship briefs under bash 3.2 - #194
spuserswag wants to merge 1 commit into
Conversation
The ship-mode section built each mode's "Definition of done" text with a
heredoc wrapped in command substitution (DOD=$(cat <<EOF ... EOF)). The
no-mistakes DOD body contains apostrophes ("no-mistakes' own guidance",
"no-mistakes' respond"). Bash 3.2 (macOS stock /bin/bash) mis-parses a
single quote inside a heredoc body that is itself nested in $(...): it
treats the apostrophe as an opening quote and runs to EOF looking for the
match, aborting the whole script with:
fm-brief.sh: line 211: unexpected EOF while looking for matching `''
Modern bash (5.x) parses it fine, so it was missed. Because the failure is
at parse time, fm-brief.sh could not scaffold ANY ship brief on a stock
macOS box, not just no-mistakes.
Fix the structural pattern rather than the wording: drop the DOD variable
and the command substitution, and append each mode's Definition of done
directly into the brief with a plain `cat >> "$BRIEF" <<EOF` (the same
non-nested heredoc form the scout path already uses). The pre-write case
now only prepares the mode-specific Setup/Rule-1 text. Any future
apostrophe in a DOD/Setup body is now safe.
The generated brief is byte-for-byte identical to the previous intended
output on modern bash: the common body ends with the "Project memory"
blank line and each DOD is concatenated exactly where $DOD used to expand
(command substitution stripped the heredoc's single trailing newline, and
the direct append reproduces that join).
Verified under bash 3.2.57 (/bin/bash) that all four delivery paths
(no-mistakes, direct-PR, local-only, scout) plus the secondmate charter
scaffold with no syntax error and correct content; DOD body text diffs
identical to HEAD for all three ship modes.
fm-bootstrap.sh has the same $(cat <<EOF) shape but its heredoc bodies
carry no lone apostrophes, so it parses fine under bash 3.2 and is left
unchanged.
|
thanks for this. quick note on process - i require PRs to come through no-mistakes, which is why the "PR must be raised via no-mistakes" check is red here (this was opened directly). the reason i ask for it: no-mistakes runs review, tests, lint, and docs on your branch before the PR is opened, so contributions arrive already validated. that keeps the quality bar high and keeps me from having to hand-review every change - i maintain this solo, so it's the only way i keep up. can you re-raise it through no-mistakes? running the pipeline on your branch opens/updates the PR through the gate and turns that check green. the change looks useful, it just needs to come through that path. ping me if the setup gives you trouble. |
|
Measured, then declined. Closing with the numbers rather than a bare close. Six sweep cells of 80 rounds each across The premise does not hold on the shipped map. The What the dash buys on that advance: 0.087s ( What it costs is exact and total. Every bot that would have reached its first enemy holding a On On On the #190 stall axis the instrument returns NO verdict, and that is not the same as a negative. Not measured: the Objective producer of What would reopen this: a map whose spawn anchors are genuinely a long walk apart, or a profile A duration-gated variant was sketched (threshold in ticks on how long the bot has been advancing, |
|
Speaking as Kun's firstmate: scheduled 7:10pm PT 8/24 pass (FM-FMOSS-CRON). First look on current class=corrective leftover. The bash 3.2 ship-brief parse failure this PR names is already on main via #1093 ( Verified on THIS main This DIFF vs main: 377 commits behind; one file VISION.md: closing aligns. The macOS parse hole is already closed on main. Authority/scripts/restart/spine/vendor/scope are n/a for a leftover close. Scripts-own-the-mechanics is already satisfied by the landed structural guard (and CI stock-macOS bash job from #1093). This HEAD: The later nikzorz comment on this thread is unrelated (game-bot dash measurements) and is not firstmate evidence. Land-eligible rec: NO (already on main via #1093). Captain-flag NOW: no. Closing as leftover of #1093. |
|
Speaking as Kun's firstmate: closing as already fixed on main by #1093. |
|
Speaking as Kun's firstmate: first look on current class=corrective leftover. The bash 3.2 abort ( This DIFF restates the same three mode texts via The 2026-08-25 nikzorz comment on this thread is off-topic (game-map dash sweep) and is not a reason to close. Closing because main already has the scaffold fix. VISION.md: closing aligns. Authority/scripts/restart/spine/vendor/scope are n/a for a leftover close. This HEAD: Land-eligible rec: NO. Captain-flag NOW: no. Closing as already fixed on main. This is not waiting-on-author and not a captain-decision. |
Problem
bin/fm-brief.shfails to run under macOS's stock bash 3.2 (/usr/bin/env bashresolves to/bin/bash, GNU bash 3.2.57) whenever it scaffolds a ship brief. Because the failure is at parse time, the script cannot scaffold any ship brief on a stock macOS box:Root cause
The ship-mode section built each mode's "Definition of done" with a heredoc wrapped in command substitution:
The no-mistakes DOD body contains apostrophes (
no-mistakes'). Bash 3.2 has a well-known parser bug where a single quote inside a heredoc body that is itself nested in$(...)command substitution is treated as an opening quote, so the parser runs to EOF looking for its match and aborts. Modern bash (5.x) parses it fine, which is why it was never caught. The scout path was unaffected because it uses a plaincat > "$BRIEF" <<EOF(no command substitution).Fix
Fix the structural pattern, not the wording (the apostrophes are intentional and future DOD/Setup bodies could gain more): drop the
DODvariable and the command substitution, and append each mode's Definition of done directly into the brief with a plaincat >> "$BRIEF" <<EOF- the same non-nested heredoc form the scout path already uses. The pre-writecasenow only prepares the mode-specific Setup/Rule-1 text. Any future apostrophe in a DOD/Setup body is now safe.The shebang is untouched (
#!/usr/bin/env bash); no hard-coded bash path.Byte-for-byte identical output
The generated brief is unchanged from the previous intended output on modern bash. Command substitution stripped the heredoc's single trailing newline before
$DODexpanded; the common body now ends at the "Project memory" blank line and each DOD is appended exactly where$DODused to expand, reproducing the same join and the same single trailing newline. DOD body text diffs identical toHEADfor all three ship modes.Verification
Before (on macOS,
/bin/bash= 3.2.57):After:
Generated real briefs under bash 3.2.57 for no-mistakes, direct-PR, local-only, and scout, plus the secondmate charter - all scaffold with no syntax error and correct content (apostrophes render intact). Confirmed the join point keeps a single blank-line separator and the file ends in exactly one trailing newline (no double newline).
Scope
Tightly scoped to
fm-brief.sh.bin/fm-bootstrap.shhas the same$(cat <<EOF)shape, but its heredoc bodies carry no lone apostrophes, so it parses cleanly under bash 3.2 (/bin/bash -n bin/fm-bootstrap.sh-> OK) and is left unchanged.