Skip to content

fix(watch): absorb redraw-only stale wakes for an already-surfaced status#955

Open
pchuri wants to merge 7 commits into
kunchenguid:mainfrom
pchuri:fm/fm-stale-rewake-fix-d4
Open

fix(watch): absorb redraw-only stale wakes for an already-surfaced status#955
pchuri wants to merge 7 commits into
kunchenguid:mainfrom
pchuri:fm/fm-stale-rewake-fix-d4

Conversation

@pchuri

@pchuri pchuri commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Intent

The transcript contains no developer request or discussion — only a single assistant message stating it set up a background wait for a test suite to complete and would report back once finished. There is no explicit user goal, requirement, or constraint captured in this excerpt to summarize.

What Changed

  • bin/fm-watch.sh: the stale-pane classifier now compares a changed pane hash against .hb-surfaced-<task> (the durable record of what was already surfaced); when the last status line is unchanged and terminal, the hash change is absorbed as a redraw/reattach blip instead of re-waking, and trailing whitespace is stripped before hashing as secondary hardening against the same false-positive.
  • bin/fm-spawn.sh: the task metadata write now exits on failure instead of silently continuing.
  • docs/architecture.md and docs/configuration.md: describe the new already-surfaced redraw-absorb path and its effect on FM_STALE_ESCALATE_SECS.
  • tests/fm-watch-triage.test.sh (new) covers the redraw-absorb and still-surfaces-new-status cases end to end; tests/herdr-test-safety.sh gains a shared herdr_default_session_live() precondition, adopted by several Herdr-gated tests so they skip cleanly when no default Herdr session is running instead of failing.

Risk Assessment

✅ Low: The functional fix in bin/fm-watch.sh (absorb a pane-redraw/reattach hash change when the crew's terminal status line was already durably recorded as surfaced) is narrowly scoped, reuses an existing marker mechanism, is backed by two new targeted regression tests plus one proving new statuses still fire, and the bin/fm-spawn.sh change is a small, well-contained fail-closed hardening consistent with the file's existing trap-based abort-cleanup; only issue found is minor test-code duplication.

Testing

Captain, all targeted tests are green: the two new regression tests directly demonstrate the stale-rewake fix end-to-end via real fm-watch.sh subprocesses (redraw absorbed, genuine new status still surfaces), and the herdr-gated test skip fix was independently confirmed live in this environment (herdr installed, no default session running → clean skip, not a failure) — no findings to raise.

Evidence: fm-watch-triage.test.sh full run (35/35 passing, including the 2 new regression tests)
ok - a pane redraw of an already-surfaced terminal status is absorbed, not re-woken
ok - a genuinely new captain-relevant status still surfaces despite a prior already-surfaced marker
...
FM_TEST_END ... exit=0 duration_ms=146955
FM_TEST_SUMMARY total=1 failed=0 skipped_gate=0
Evidence: herdr-gated tests now skip cleanly with no default Herdr session running
FM_TEST_BEGIN tests/fm-backend-autodetect-smoke.test.sh family=real-herdr-gated expected_gate_skip=herdr
skip: no running default Herdr session (fleet-state tripwire precondition)
FM_TEST_END ... exit=0 duration_ms=77 gate_skip=true

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

🔧 **Rebase** - 1 issue found → auto-fixed ✅
  • ⚠️ tests/fm-afk-launch.test.sh - merge conflict rebasing onto origin/main

🔧 Fix applied.
✅ Re-checked - no issues remain.

⚠️ **Review** - 2 warnings
  • ⚠️ tests/fm-backend-autodetect-smoke.test.sh:43 - This diff adds herdr_default_session_live() to tests/herdr-test-safety.sh specifically to centralize the 'is there a running default Herdr session' fleet-state-tripwire check, and 6 of 8 updated test files call it via . tests/herdr-test-safety.sh; herdr_default_session_live || .... This file (and tests/fm-backend-herdr-presentation-e2e.test.sh) instead re-implements the same check inline with a hand-rolled herdr session list --json | jq -e &#39;...&#39; pipeline, duplicating the exact predicate fm_herdr_lab_fleet_state encodes. Any future change to the tripwire semantics (e.g. loosening/tightening the running-session condition) will silently miss these two copies.
  • ⚠️ tests/fm-backend-herdr-presentation-e2e.test.sh:19 - Same duplicated inline fleet-state-tripwire check as tests/fm-backend-autodetect-smoke.test.sh instead of sourcing tests/herdr-test-safety.sh and calling the new herdr_default_session_live helper.
✅ **Test** - passed

✅ No issues found.

  • bin/fm-test-run.sh tests/fm-watch-triage.test.sh — full 35-test suite green, including new test_terminal_stale_absorbed_when_status_already_surfaced_by_redraw and test_terminal_stale_new_status_still_surfaces, each driving a real fm-watch.sh subprocess against crafted state/pane fixtures and asserting on its exit behavior, printed wake reason, and wake-queue contents
  • bin/fm-test-run.sh tests/fm-backend-autodetect-smoke.test.sh — confirms the new herdr fleet-state precondition check causes a clean skip rather than a failure when no default Herdr session is running
  • bin/fm-test-run.sh tests/fm-backend-herdr-smoke.test.sh tests/fm-afk-inject-herdr-e2e.test.sh — same clean-skip confirmation for two more herdr-gated tests touched by the same guard
  • bin/fm-test-run.sh tests/fm-spawn-batch.test.sh — sanity check that the incidental || exit 1 hardening on the fm-spawn.sh metadata write did not regress spawn batch dispatch
  • git status --short — confirmed no leftover test artifacts in the worktree after the run
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

pchuri added 7 commits July 24, 2026 11:27
Consult the durable surfaced-status record first: when it already names
the task's current status line, absorb the redraw instead of waking
again. Only a status line the record does not yet know about surfaces.
Also strip trailing whitespace before hashing the pane, hardening
against redraw-only churn.
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.

1 participant