Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,16 @@ jobs:
exit 1
}

# The composer classifier runs under stock /bin/bash on every macOS
# fleet, and its fixtures must be pure UTF-8 (Bash 3.2 has no \u).
composer_output=$(/bin/bash tests/fm-composer-lib.test.sh)
printf '%s\n' "$composer_output"
composer_count=$(printf '%s\n' "$composer_output" | grep -c '^ok - ')
[ "$composer_count" -eq 33 ] || {
echo "::error::expected 33 composer classifier tests, got $composer_count"
exit 1
}

command -v npm >/dev/null || { echo "::error::npm is required to install tasks-axi"; exit 1; }
npm install -g tasks-axi@0.2.5 >/dev/null
PATH="$(npm prefix -g)/bin:$PATH"
Expand Down
1 change: 1 addition & 0 deletions docs/fm-test-isolation-proof.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ Admitting the family moves that tail into the bounded concurrent group.
Current runner-file selection was verified on 2026-08-28 with the runner and its tests bound to each measured Bash version.
Because the runner uses `#!/usr/bin/env bash` and invokes each test with `bash` from `PATH`, the stock macOS measurement used `PATH=/bin:$PATH bin/fm-test-run.sh --changed --max-wall-ms 300000` so both resolved to `/bin/bash` 3.2.57.
Two runs selected all 33 scripts, passed the five-minute result check in 153.5s and 166.8s, and reported the same two failures as `main`: `tests/fm-muse-harness.test.sh` and `tests/fm-composer-lib.test.sh`.
`tests/fm-composer-lib.test.sh` passes under that shell as of 2026-09-03: its failure was an escaped `\u` fixture that Bash 3.2 cannot decode, and the stock macOS Bash lane in [`.github/workflows/ci.yml`](../.github/workflows/ci.yml) now runs the suite under real `/bin/bash` 3.2 so the defect cannot return unnoticed.
With Bash 5.3.9 on `PATH`, three runs of `bin/fm-test-run.sh --changed --max-wall-ms 300000` selected the same 33 scripts, completed with 0 failures, and reported 163.8s, 172.0s, and 166.9s.
All five runs used plain `--changed` with no `--jobs` flag, exercised the production automatic scheduler, and completed under five minutes.

Expand Down
24 changes: 13 additions & 11 deletions tests/fm-composer-lib.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -269,20 +269,22 @@ test_matrix_herdr_halfblock_rule_bounds_bare_wrap() {
# rather than the box-drawing family. Without treating those as edges, a bare
# composer's WRAP region walks through its own closing rule and swallows the
# footer, whose real content turns an idle pane into a false `pending`.
# Captured live from a herdr cursor pane.
local screen plain out
plain=$'transcript\n \u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\n \u2192 Add a follow-up\n \u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\n Cursor Grok 4.5 High \u00b7 6.7% Run Everything\n ~/wt \u00b7 64cdd3a'
# Captured live from a herdr cursor pane. The glyphs are literal UTF-8 on
# purpose: stock macOS Bash 3.2 has no `\u` escape in printf or $'...', so an
# escaped fixture feeds the classifier the six ASCII bytes `\u2580` instead.
local screen esc out
# The closing rule must bound the region, so the footer below is not input.
fm_composer_row_has_edge " $(printf '\u2580\u2580\u2580')" \
fm_composer_row_has_edge ' ▀▀▀' \
|| fail "a half-block rule row must count as a structural edge"
fm_composer_row_has_edge " $(printf '\u2584\u2584\u2584')" \
fm_composer_row_has_edge ' ▄▄▄' \
|| fail "the upper half-block rule must count as a structural edge"
# Non-vacuousness: the footer rows really are non-blank content that would be
# swallowed if the rule did not bound the region.
case "$plain" in *"Run Everything"*) : ;; *) fail "fixture lost its footer content" ;; esac
ESC_LOCAL=$(printf '\033')
screen=$'transcript\n \u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\n'" ${ESC_LOCAL}[2m\u2192 ${ESC_LOCAL}[0;7mA${ESC_LOCAL}[0;2mdd a follow-up${ESC_LOCAL}[0m"$'\n \u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\n Cursor Grok 4.5 High \u00b7 6.7% Run Everything\n ~/wt \u00b7 64cdd3a'
out=$(fm_composer_classify_screen "$CAPS_STYLED" "$(printf '%b' "$screen")")
esc=$(printf '\033')
screen=$'transcript\n ▄▄▄▄▄▄▄▄\n'" ${esc}[2m→ ${esc}[0;7mA${esc}[0;2mdd a follow-up${esc}[0m"$'\n ▀▀▀▀▀▀▀▀\n Cursor Grok 4.5 High · 6.7% Run Everything\n ~/wt · 64cdd3a'
# Non-vacuousness: the classified fixture really carries non-blank footer rows
# below the closing rule, which would be swallowed if the rule did not bound
# the region.
case "$screen" in *"Run Everything"*) : ;; *) fail "fixture lost its footer content" ;; esac
out=$(fm_composer_classify_screen "$CAPS_STYLED" "$screen")
[ "$out" = empty ] \
|| fail "an idle cursor composer inside herdr half-block rules must read empty, got '$out'"
pass "matrix: herdr half-block rules bound a bare composer's wrap region"
Expand Down
8 changes: 4 additions & 4 deletions tests/fm-control-relaunch.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ test_relaunch_serializes_concurrent_durable_metadata_publication() {
FM_FAKE_TRACE_RELEASE="$launch_release" \
run_control "$dir" rl28 relaunch --note "continue after publication" > "$dir/control.out" &
control_pid=$!
while [ ! -e "$prepare" ] && [ "$i" -lt 200 ]; do
while [ ! -e "$prepare" ] && [ "$i" -lt 1000 ]; do
/bin/sleep 0.01
i=$((i + 1))
done
Expand All @@ -367,7 +367,7 @@ test_relaunch_serializes_concurrent_durable_metadata_publication() {
--carry-platform x --carry-max 280 > "$dir/link.out" 2>&1 &
link_pid=$!
i=0
while [ ! -e "$waiting" ] && [ "$i" -lt 200 ]; do
while [ ! -e "$waiting" ] && [ "$i" -lt 1000 ]; do
/bin/sleep 0.01
i=$((i + 1))
done
Expand All @@ -380,7 +380,7 @@ test_relaunch_serializes_concurrent_durable_metadata_publication() {
}
: > "$launch_release"
i=0
while [ ! -e "$ready" ] && [ "$i" -lt 200 ]; do
while [ ! -e "$ready" ] && [ "$i" -lt 1000 ]; do
/bin/sleep 0.01
i=$((i + 1))
done
Expand Down Expand Up @@ -987,7 +987,7 @@ test_prepublication_failure_keeps_concurrent_durable_metadata() {
run_control "$dir" rl30 relaunch --harness codex --note "preserve concurrent metadata" \
> "$dir/control.out" &
control_pid=$!
while [ ! -e "$dir/cwd-race-ready" ] && [ "$i" -lt 200 ]; do
while [ ! -e "$dir/cwd-race-ready" ] && [ "$i" -lt 1000 ]; do
/bin/sleep 0.01
i=$((i + 1))
done
Expand Down