Postmortem — Weekly roadmap summary bash syntax error (2026-05-18)
Postmortem — Weekly roadmap summary bash syntax error (2026-05-18)
Section titled “Postmortem — Weekly roadmap summary bash syntax error (2026-05-18)”
scripts/roadmap-summary.shused[[ "$due" <= "$SOON" ]], which is invalid bash. TheWeekly roadmap summaryworkflow has crashed on every Monday cron since PR #131 (2026-04-23). main-guard finally surfaced the failure asrig-docs#269, attributing it to PR #268 because that was the last merge before the May 18 cron fired.
| Item | Value |
|---|---|
| Reported incident | rig-docs#269 |
| Cited “culprit PR” | #268 (docs-only postmortem; not the actual cause) |
| Real cause | Bash conditional [[ "$due" <= "$SOON" ]] — <= is not a valid [[ ]] operator |
| Introduced in | #131 — 4b6ad66 (2026-04-23) |
| Mondays affected | 2026-04-27, 05-04, 05-11, 05-18 (4 silent failures) |
| Why undetected | main-guard (rig-conductor Phase 1) only recently began monitoring cron workflows |
| Fix | Replace <= with ! > (i.e. [[ ! "$due" > "$SOON" ]]) and add bash -n coverage for scripts/*.sh to npm run build |
What happened
Section titled “What happened”- PR #131 (2026-04-23) added the
Weekly roadmap summaryworkflow andscripts/roadmap-summary.sh. - The script’s
deadline_summaryfunction used the bash conditional[[ "$due" <= "$SOON" ]]. Bash[[ ]]supports<and>for string comparison but not<=or>=. The presence of<=causes the function body to fail parsing at runtime →syntax error in conditional expression→ exit 2. - Because the syntax error fires when
deadline_summaryis invoked, every Monday cron run since 2026-04-23 has failed — but no monitor was watching cron failures. - On 2026-05-18, main-guard (rig-conductor Phase 1) sampled the failed run and filed
rig-docs#269. The cited “culprit” PR #268 was simply the last merge before the cron fired; PR #268 added a markdown postmortem and could not have caused the script failure.
Reproduction
Section titled “Reproduction”git checkout ad0c912e # main HEAD before the fixbash scripts/roadmap-summary.sh# → scripts/roadmap-summary.sh: line 75: syntax error in conditional expression# → exit 2The fix
Section titled “The fix”| Before | After |
|---|---|
elif [[ "$due" <= "$SOON" ]]; then | elif [[ ! "$due" > "$SOON" ]]; then |
! > expresses “not strictly after” — i.e. “on or before”. Equivalent to the intended <=.
Verification
Section titled “Verification”bash -n scripts/roadmap-summary.sh # parse-okPlus an inline truth-table check (overdue and soon counts match expectations for sample dates around TODAY and SOON).
Lessons
Section titled “Lessons”| # | Lesson |
|---|---|
| 1 | Bash [[ ]] does not support <= or >=. Use ! > / ! < or fall back to ((..)) for numeric / date -d for dates. |
| 2 | Run bash -n script.sh in CI for every new shell script. A single shellcheck/parse step would have caught this in PR #131. |
| 3 | set -euo pipefail does not protect against syntax errors that only surface inside function bodies — those fire at call time, not at script load. |
| 4 | main-guard correctly identified a real failing run but mis-attributed the culprit PR. Cron workflows have no merge-to-blame mapping; attribution should be <unknown culprit — cron schedule> rather than “last merge before fire time”. Track follow-up in rig-conductor. |
| 5 | Long-running cron failures need a separate alert path. main-guard waited a month before catching this. |
Guardrail added
Section titled “Guardrail added”The build command now runs:
npm run check:shell && astro buildcheck:shell runs bash -n scripts/*.sh. That would have failed PR #131 before merge because bash -n scripts/roadmap-summary.sh exits with syntax error in conditional expression on the invalid operator.
Remaining follow-ups
Section titled “Remaining follow-ups”- File
rig-conductorissue: main-guard should not attribute cron failures to the last merged PR; cron workflows lack a culprit. - Backfill: confirm no roadmap status was actually missed beyond the silent gap (no Discord posts since 2026-04-23).