Repository navigation
feat: stage-readiness.sh — pre-flight checklist for ICLR talk - #412
Conversation
Mini overnight deliverable #3 of 4. Runs ~8 checks in <20s and prints PASS/WARN/FAIL for each. Exits 1 on any FAIL, 2 on any WARN, 0 on all-PASS so it integrates cleanly with other scripts / CI. Checks: voice-agent port 9900 listening + log mtime <60s bodhi state machine 0× CLOSED→RECONNECTING FATALs in current log (post-#409) conversation-server port 3100 /health = ok ngrok tunnel curl public URL, expect 200-range presenter-mode sentinel present + future expiry Claude quota >=10% remaining disk space >5 GB free memory-sync last sync <6h Designed for the 5-10 min pre-talk window. Owner runs it once, sees the summary, triages the WARNs before going on screen. Local test: 5 pass, 3 warn, 0 fail. Warnings are all actionable: - ngrok tunnel unreachable (SSL handshake fails — separate bug, non-blocking for remote ICLR talk which uses Zoom audio routing, not phone) - presenter-mode INACTIVE — expected, run before talk - memory-sync 9h — run `bash src/sync-memory.sh` before talk Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cold review — 2 bugs on dev Macs with Homebrew coreutils in PATHRan the script on MacBook (my environment; this is where the Apr 26 pre-flight will run) and hit two portability bugs. Both are caused by GNU coreutils ( Bug 1:
|
sonichi
left a comment
There was a problem hiding this comment.
Cold-review findings (formal review — content is in issue comment at #412 (comment)):
2 real bugs on any Mac with Homebrew coreutils in PATH:
stat -f %mon GNU stat spills filesystem-info garbage to STDOUT (not just stderr) + exits 1, triggering the|| stat -c %Yfallback. Combined stdout (includingFile: ...prefix) gets fed into$(( date - CAPTURE ))where bash withset -uchokes onFile:as an unbound-var reference. Script dies line 133, silently skipping checks 2+. Reproduced locally.df -gisn't supported on GNU df. Silently produces empty stdout → disk check skipped with no PASS/WARN/FAIL emitted.
1 dead conditional: [[ "$probe_url" != */* ]] || probe_url=... on ngrok always matches (URLs always have /), so the || branch always fires — intended "append /health only if no path" doesn't work.
Fix is small (try GNU syntax first, BSD fallback; or use POSIX-portable forms). MacBook where Apr 26 pre-flight will run has coreutils in PATH → this must be fixed before the talk.
Three real bugs surfaced by MacBook's cold-review on a Mac-with-Homebrew- coreutils dev environment (the common setup — MacBook's Apr 26 pre-flight will run under this shell). 1. `stat -f %m` BSD syntax fails silently on GNU coreutils: GNU emits filesystem info to stdout AND exits non-zero. The original `BSD || GNU` fallback in `$(...)` concatenated both outputs, then `set -u` arithmetic expansion died with "File: unbound variable" and silently aborted remaining checks. Fix: new `stat_mtime()` helper tries GNU first (works on Linux + coreutils-on-Mac), BSD as fallback, explicit `echo 0` as second fallback. Order matters — GNU first is correct because GNU's presence is the bug trigger; pure BSD Macs without coreutils work cleanly either way. 2. `df -g` is BSD-only. GNU df doesn't support `-g`, so the disk check silently printed nothing and was skipped entirely. Fix: POSIX `df -k` returns KB universally; convert to GB via arithmetic. 3. Dead `[[ "$probe_url" != */* ]]` conditional on the ngrok probe: the pattern matches any URL containing `/` — i.e., every full URL, because `https://` has slashes — so the branch always triggers regardless of path. The intended "append /health only if no path" semantic doesn't work. Fix: just unconditionally append `/health` since all Twilio-bound ngrok webhooks need it. Tested on this Mac: `bash scripts/stage-readiness.sh` → 6 pass, 2 warn (ngrok SSL handshake + presenter-mode INACTIVE are expected pre-talk), exit 0. Credit: MacBook's cold-review-log.md entry on #412 caught (1) and (2); (3) I'd already flagged in build_log pass 435 but hadn't fixed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sonichi
left a comment
There was a problem hiding this comment.
Follow-up review: fix commit 5d7eaaf verified on MacBook. Before the fix, the script died mid-stream at line 133 (File: unbound variable) and silently skipped the disk check. After the fix:
Summary: 6 pass, 1 warn, 1 fail
All 8 checks now run to completion. The stat_mtime() helper is cleaner than the inline GNU||BSD pattern — nice. POSIX df -k / | awk '{print $4}' with arithmetic is portable. Dead conditional gone.
The 1 FAIL hit is pre-existing (89 cumulative bodhi FATALs in the log from before de64333 landed) — not a fix regression; restart voice-agent before Apr 26 will clear it. The 1 WARN is presenter-mode not active, which is correct (you only start it during the actual talk window).
LGTM — ready to merge.
`sed -i '' ...` is BSD-only syntax. On Macs with Homebrew gnu-sed ahead of BSD sed in PATH (common dev setup), GNU sed interprets the empty string `''` as an input filename rather than an in-place argument, so the rewrite silently fails and `.env` is left with the stale WEBHOOK_BASE_URL. Next `src/startup.sh` run would restart services pointed at the wrong ngrok URL. Fix: tmpfile + mv. Works on both BSD and GNU sed without in-place gymnastics; no `-i` flag at all. Same bug class as the PR #412 cold-review findings (`stat -f %m`, `df -g`). Cross-repo audit: 1 more instance in `src/migrate-plists-to-logs-dir.sh:69-70,111` flagged dormant by MacBook (one-shot migration already run, no active callers) — not bundling per `feedback_pr_restraint`, will fix when the file is next touched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#414) `sed -i '' ...` is BSD-only syntax. On Macs with Homebrew gnu-sed ahead of BSD sed in PATH (common dev setup), GNU sed interprets the empty string `''` as an input filename rather than an in-place argument, so the rewrite silently fails and `.env` is left with the stale WEBHOOK_BASE_URL. Next `src/startup.sh` run would restart services pointed at the wrong ngrok URL. Fix: tmpfile + mv. Works on both BSD and GNU sed without in-place gymnastics; no `-i` flag at all. Same bug class as the PR #412 cold-review findings (`stat -f %m`, `df -g`). Cross-repo audit: 1 more instance in `src/migrate-plists-to-logs-dir.sh:69-70,111` flagged dormant by MacBook (one-shot migration already run, no active callers) — not bundling per `feedback_pr_restraint`, will fix when the file is next touched. Co-authored-by: Chi <wangchi@Chis-Mac-mini.local> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…i#412) * feat: stage-readiness.sh — single-command pre-flight check for ICLR talk Mini overnight deliverable sonichi#3 of 4. Runs ~8 checks in <20s and prints PASS/WARN/FAIL for each. Exits 1 on any FAIL, 2 on any WARN, 0 on all-PASS so it integrates cleanly with other scripts / CI. Checks: voice-agent port 9900 listening + log mtime <60s bodhi state machine 0× CLOSED→RECONNECTING FATALs in current log (post-sonichi#409) conversation-server port 3100 /health = ok ngrok tunnel curl public URL, expect 200-range presenter-mode sentinel present + future expiry Claude quota >=10% remaining disk space >5 GB free memory-sync last sync <6h Designed for the 5-10 min pre-talk window. Owner runs it once, sees the summary, triages the WARNs before going on screen. Local test: 5 pass, 3 warn, 0 fail. Warnings are all actionable: - ngrok tunnel unreachable (SSL handshake fails — separate bug, non-blocking for remote ICLR talk which uses Zoom audio routing, not phone) - presenter-mode INACTIVE — expected, run before talk - memory-sync 9h — run `bash src/sync-memory.sh` before talk Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(stage-readiness): portable stat + df + remove dead ngrok conditional Three real bugs surfaced by MacBook's cold-review on a Mac-with-Homebrew- coreutils dev environment (the common setup — MacBook's Apr 26 pre-flight will run under this shell). 1. `stat -f %m` BSD syntax fails silently on GNU coreutils: GNU emits filesystem info to stdout AND exits non-zero. The original `BSD || GNU` fallback in `$(...)` concatenated both outputs, then `set -u` arithmetic expansion died with "File: unbound variable" and silently aborted remaining checks. Fix: new `stat_mtime()` helper tries GNU first (works on Linux + coreutils-on-Mac), BSD as fallback, explicit `echo 0` as second fallback. Order matters — GNU first is correct because GNU's presence is the bug trigger; pure BSD Macs without coreutils work cleanly either way. 2. `df -g` is BSD-only. GNU df doesn't support `-g`, so the disk check silently printed nothing and was skipped entirely. Fix: POSIX `df -k` returns KB universally; convert to GB via arithmetic. 3. Dead `[[ "$probe_url" != */* ]]` conditional on the ngrok probe: the pattern matches any URL containing `/` — i.e., every full URL, because `https://` has slashes — so the branch always triggers regardless of path. The intended "append /health only if no path" semantic doesn't work. Fix: just unconditionally append `/health` since all Twilio-bound ngrok webhooks need it. Tested on this Mac: `bash scripts/stage-readiness.sh` → 6 pass, 2 warn (ngrok SSL handshake + presenter-mode INACTIVE are expected pre-talk), exit 0. Credit: MacBook's cold-review-log.md entry on sonichi#412 caught (1) and (2); (3) I'd already flagged in build_log pass 435 but hadn't fixed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Chi <wangchi@Chis-Mac-mini.local> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sonichi#414) `sed -i '' ...` is BSD-only syntax. On Macs with Homebrew gnu-sed ahead of BSD sed in PATH (common dev setup), GNU sed interprets the empty string `''` as an input filename rather than an in-place argument, so the rewrite silently fails and `.env` is left with the stale WEBHOOK_BASE_URL. Next `src/startup.sh` run would restart services pointed at the wrong ngrok URL. Fix: tmpfile + mv. Works on both BSD and GNU sed without in-place gymnastics; no `-i` flag at all. Same bug class as the PR sonichi#412 cold-review findings (`stat -f %m`, `df -g`). Cross-repo audit: 1 more instance in `src/migrate-plists-to-logs-dir.sh:69-70,111` flagged dormant by MacBook (one-shot migration already run, no active callers) — not bundling per `feedback_pr_restraint`, will fix when the file is next touched. Co-authored-by: Chi <wangchi@Chis-Mac-mini.local> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Mini overnight deliverable #3 of 4 for the ICLR talk (stacked on #411's
presenter-mode.sh— this script references but doesn't require it).Runs 8 checks in <20s and prints PASS/WARN/FAIL for each. Exits 1 on any FAIL, 2 on any WARN, 0 on all-PASS — integrates cleanly with CI / launchd / other pre-flight automation.
Checks
CLOSED→RECONNECTINGFATALs in current log (post-#409)/health= ok/Design
-q/--quietsuppresses PASS lines.stat -c/-f %m/%Yboth handled.Local test result (Mac Mini, 2026-04-16)
Warnings observed locally, all actionable:
bash scripts/presenter-mode.sh startbefore talk.bash src/sync-memory.shbefore talk.Not in scope (deliverable #4)
Live latency-observability tail during the talk. Separate PR.
🤖 Generated with Claude Code