Skip to content

ci: validate fm-brief with stock macOS Bash 3.2 - #1003

Closed
palinopr wants to merge 3 commits into
kunchenguid:mainfrom
palinopr:codex/fm-brief-bash32-parse
Closed

palinopr wants to merge 3 commits into
kunchenguid:mainfrom
palinopr:codex/fm-brief-bash32-parse

Conversation

@palinopr

@palinopr palinopr commented Jul 24, 2026 •

Copy link
Copy Markdown

What Changed

  • Run all 16 fm-brief regression cases in CI using stock macOS Bash 3.2.
  • Document Bash 3.2 parsing requirements and the heredoc-in-command-substitution hazard across the shell-script inventory.
  • Clarify that CI’s stock macOS lane is the authoritative Bash 3.2 compatibility check.

Risk Assessment

✅ Low: Captain, the prior wording defect is corrected, the authorized three-file scope is preserved, and the added macOS Bash 3.2 coverage is well-bounded with no remaining source-verifiable concern.

Testing

After confirming the base-to-target scope, the exact new macOS CI behavior ran successfully on stock Bash 3.2.57 and produced all 16 expected focused results. An end-user CLI exercise then generated a complete 68-line brief with the apostrophe-bearing prose intact; a final parse check passed and the worktree remained clean. This is a CLI/CI-only change, so evidence is provided as a transcript and generated Markdown rather than a screenshot.

Evidence: Stock Bash 3.2 end-to-end transcript

GNU Bash 3.2.57 generated a 68-line brief containing the complete Definition of Done and preserving firstmate's authority check verbatim.

Runtime: GNU bash, version 3.2.57(1)-release (arm64-apple-darwin25)
Command: FM_HOME=/var/folders/tz/1bzrfmb54r1gxlsy78klxvzr0000gn/T/no-mistakes-evidence/01KYQ2A75TCBGXFQ32QR4QNSV6/fm-home /bin/bash bin/fm-brief.sh bash32-e2e-brief sample-project
warn: no registry at /var/folders/tz/1bzrfmb54r1gxlsy78klxvzr0000gn/T/no-mistakes-evidence/01KYQ2A75TCBGXFQ32QR4QNSV6/fm-home/data/projects.md; defaulting sample-project to no-mistakes off
scaffolded: /var/folders/tz/1bzrfmb54r1gxlsy78klxvzr0000gn/T/no-mistakes-evidence/01KYQ2A75TCBGXFQ32QR4QNSV6/fm-home/data/bash32-e2e-brief/brief.md (ship, mode=no-mistakes; replace {TASK})
Generated: /var/folders/tz/1bzrfmb54r1gxlsy78klxvzr0000gn/T/no-mistakes-evidence/01KYQ2A75TCBGXFQ32QR4QNSV6/fm-home/data/bash32-e2e-brief/brief.md (68 lines)
53:# Definition of done
66:- Avoid `--yes`: it would silently bypass firstmate's authority check and any required captain escalation.
59:Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke /no-mistakes, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
Result: PASS - stock Bash 3.2 generated the complete no-mistakes brief with the apostrophe prose intact.
Evidence: Generated end-user brief
You are a crewmate: an autonomous worker agent managed by firstmate. Work on your own; do not wait for a human.

# Task
{TASK}

# Herdr lifecycle declaration - NOT ENABLED
**HARD SAFETY GATE:** this scaffold cannot inspect the task text that replaces `{TASK}` later.
If the task will start, stop, delete, restart, profile, or otherwise drive Herdr lifecycle behavior, stop and regenerate the brief with `--herdr-lab` before dispatch.
Do not add Herdr lifecycle commands to this unguarded brief by hand.

# Setup
You are in a disposable git worktree of sample-project, at a detached HEAD on a clean default branch.

**Verify isolation before anything else.** Run `pwd -P` and `git rev-parse --show-toplevel`; both must resolve to the disposable task worktree you were launched in, such as a treehouse pool path or an Orca-managed worktree, not the primary checkout firstmate operates from.
The path check is authoritative: `git rev-parse --git-dir` and `git rev-parse --git-common-dir` can help inspect the repo, but they do not prove you are outside the primary checkout.
If the top-level path is the primary checkout or not the worktree you were launched in, STOP - do not branch or commit here - append `blocked: launched in primary checkout, not an isolated worktree` to the status file and stop.

1. First action: create your branch: `git checkout -b fm/bash32-e2e-brief`
2. Run `no-mistakes doctor`; if it reports the repo is not initialized here, run `no-mistakes init`.

# Rules
1. Never push to the default branch. Never merge a PR.
2. Stay inside this worktree; modify nothing outside it.
3. Use gh-axi for GitHub operations and chrome-devtools-axi for browser operations.
4. Report status by appending one line:
   `echo "{state}: {one short line}" >> '/var/folders/tz/1bzrfmb54r1gxlsy78klxvzr0000gn/T/no-mistakes-evidence/01KYQ2A75TCBGXFQ32QR4QNSV6/fm-home/state/bash32-e2e-brief.status'`
   States: working, needs-decision, blocked, paused, done, failed.
   Each append wakes firstmate, so report sparingly: only phase changes a supervisor
   would act on (setup done, bug reproduced, fix implemented, validation passed) and the
   needs-decision/blocked/paused/done/failed states. No step-by-step FYI progress lines;
   firstmate reads your pane for that.
   A mid-task `working:` line (including setup complete) is nonterminal: do not end the
   turn after it; continue the same stage until a defined `done:` gate under Definition of done.
   Use `paused: {why}` - distinct from `blocked:` - ONLY when you are deliberately idling on a
   known external wait you expect to clear on its own (an upstream release, a rate-limit reset,
   a scheduled window): firstmate then leaves your idle pane alone and rechecks it on a long
   cadence instead of treating it as a possible wedge. Use `blocked:` when you are stuck and need help.
5. If you hit the same obstacle twice, append `blocked: {why}` and stop; firstmate will help.
6. If a decision belongs above the implementation worker (product choices, destructive actions, ask-user findings),
   append `needs-decision: {summary of options}` and stop. Firstmate will apply the configured authority and reply with the decision.
   When firstmate replies or a blocker clears and you resume, append `resolved: {how it was decided or unblocked}` (add the same `[key=<slug>]` if you opened it with one) so the decision or blocker is durably closed and does not keep resurfacing.
7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
   daemon error, append `blocked: {the daemon error}` and stop; only firstmate manages the daemon.

# Project memory
If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `/Users/jaimeortiz/.no-mistakes/worktrees/056850ff374d/01KYQ2A75TCBGXFQ32QR4QNSV6/bin/fm-ensure-agents-md.sh .` in the worktree.
Record only project knowledge useful to almost every future session.
For anything the codebase already shows, prefer a pointer to the authoritative file, command, or doc over copying the detail.
If you touch a project `AGENTS.md` that lacks `## Maintaining this file`, add that short self-governance section from `/Users/jaimeortiz/.no-mistakes/worktrees/056850ff374d/01KYQ2A75TCBGXFQ32QR4QNSV6/bin/fm-ensure-agents-md.sh` in the same pass.
Keep it proportionate: skip `AGENTS.md` edits for trivial tasks that produced no durable project knowledge.

# Definition of done
The task is complete only when committed on your branch.
When you believe it is complete, append `done: {summary}` to the status file and stop.
Firstmate will then instruct you to run /no-mistakes to validate and ship a PR.

You drive no-mistakes by responding to its gates, not by implementing fixes.
Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke /no-mistakes, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
Do not hand-edit, commit, or fix findings yourself while a run is active - the pipeline applies every fix.

Two firstmate-specific rules layer on top of that guidance:
- ask-user findings are never yours to answer: escalate to firstmate (rule 6) and stop.
  Firstmate applies the authority contract in its `AGENTS.md` and obtains any required captain decision.
  When the decision comes back, feed it to the gate with `no-mistakes axi respond` and let the pipeline apply it - do not route the question to "the user" or implement the fix yourself.
- Avoid `--yes`: it would silently bypass firstmate's authority check and any required captain escalation.

After /no-mistakes reports CI green (the CI-ready return point - do not wait for it to keep monitoring in the background until merge), append `done: PR {url} checks green` and stop. You are finished.

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ .agents/skills/firstmate-coding-guidelines/SKILL.md:100 - The new guidance overstates the Perl scanner’s coverage. Its frame counter treats any unquoted ) as closing $(), so a valid case-pattern such as case x in x) can pop the frame before a later nested heredoc, allowing that unsafe structure through the scanner. The real Bash 3.2 CI parse sweep still catches it; describe the scanner as a partial local guard and the CI sweep as authoritative.

🔧 Fix: Clarify Bash 3.2 scanner and CI authority
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • git diff --stat 99533c5d7d3702050e6084429dddff6ea4fe1aa0 09041c56f6d789deb06098ff29d57d1086f83834 and git diff --name-status 99533c5d7d3702050e6084429dddff6ea4fe1aa0 09041c56f6d789deb06098ff29d57d1086f83834
  • env PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/homebrew/bin /bin/bash -c 'set -eu; brief_output=$(/bin/bash tests/fm-brief.test.sh); brief_count=$(printf "%s\n" "$brief_output" | grep -c "^ok - "); [ "$brief_count" -eq 16 ]'
  • FM_HOME=/var/folders/tz/1bzrfmb54r1gxlsy78klxvzr0000gn/T/no-mistakes-evidence/01KYQ2A75TCBGXFQ32QR4QNSV6/fm-home /bin/bash bin/fm-brief.sh bash32-e2e-brief sample-project
  • Checked the generated brief for # Definition of done, firstmate&#39;s authority check, and no-mistakes axi run --help.
  • env PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/homebrew/bin /bin/bash -n bin/fm-brief.sh
  • git status --short
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@kunchenguid

Copy link
Copy Markdown
Owner

thanks for digging into this. i merged #1093, which covers the core bash 3.2 parse fix, so most of this diff is now superseded. there are still two useful pieces here that main doesn't have: actually running the fm-brief behavior suite under stock macOS bash 3.2, and the bash 3.2/heredoc contributor guidance. if you're up for it, could you rebase and trim this down to those two pieces? no rush - the user-facing breakage is already fixed. appreciate the work here.

@palinopr

Copy link
Copy Markdown
Author

Sounds good — agreed that #1093 covers the core parse fix. I'll drop bin/fm-brief.sh and tests/fm-brief.test.sh from this entirely and rebase onto main.

What's left is the two pieces you named:

  1. Run the brief suite on the macos-stock-bash lane. Main's lane already does the bash -n sweep over the fm-lint.sh --list-files set, so what's still missing is actually executing tests/fm-brief.test.sh under 3.2.57 — the parse sweep proves the file loads, not that scaffolding still produces correct briefs there. I'll add it as an ok-count assertion in the same shape as the existing snapshot (15) and bearings (42) checks, pinned at 16.
  2. The bash 3.2 / heredoc contributor guidance — the two style rules in firstmate-coding-guidelines (bin scripts must parse under 3.2, and never nest a heredoc in $() when the body carries free-form English prose), plus the one-line CONTRIBUTING.md fix so it names the stock Bash 3.2 lane instead of "macOS snapshot compatibility."

I'll re-anchor the wording to main's actual structure since #1093 rewrote the guard, then force-push. Appreciate the review.

@palinopr
palinopr force-pushed the codex/fm-brief-bash32-parse branch from f6b565d to 7d05dc2 Compare July 29, 2026 13:45
@palinopr palinopr changed the title fix(bin): restore ship briefs on macOS Bash 3.2 ci: validate fm-brief with stock macOS Bash 3.2 Jul 29, 2026
@palinopr

Copy link
Copy Markdown
Author

Done — rebased and trimmed to those two pieces.

The macos-stock-bash lane now runs the fm-brief suite under 3.2.57, pinned at 16 results alongside the existing snapshot and bearings assertions; it was parsing the scripts before but never exercising them. The Bash 3.2 and heredoc guidance is in as well, written against main as it stands rather than ported across, since #1093 replaced the mechanism the old wording described.

My changes to bin/fm-brief.sh and tests/fm-brief.test.sh are gone entirely. Three files left.

Worth checking on your side: every workflow run on this branch is sitting in action_required going back to the 24th, so CI has never actually run here.

@palinopr
palinopr force-pushed the codex/fm-brief-bash32-parse branch from 549080e to 9ae70c4 Compare August 2, 2026 21:49
@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate: closing this as stale. It has been waiting on a contributor update for 14+ days with no author push or comment. Reopen if you want to pick it back up.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants