fix: treat Cursor counter progress as watcher liveness - #2952
fix: treat Cursor counter progress as watcher liveness#2952taimurrabuske wants to merge 7 commits into
Conversation
Confidence Score: 4/5The PR appears safe to merge from a runtime perspective, but its rigid Cursor UI parsing should be reconciled with the repository’s semantic-adapter policy. Progress recognition depends on fixed row positions and presentation literals, making future presentation-only Cursor changes capable of reviving false wedge alarms. Files Needing Attention: bin/fm-watch.sh Reviews (1): Last reviewed commit: "no-mistakes(document): Clarify Cursor nu..." | Re-trigger Greptile |
| block=$(printf '%s\n' "$tail40" | awk ' | ||
| { line[NR] = $0 } | ||
| END { | ||
| for (i = NR - 1; i >= 5; i--) { | ||
| if (line[i - 4] ~ /^[[:space:]]*[^[:alnum:][:space:]]+[[:space:]]*$/ && | ||
| line[i - 3] ~ /^[[:space:]]*.*Add a follow-up[[:space:]]+ctrl\+c to stop[[:space:]]*$/ && | ||
| line[i - 2] ~ /^[[:space:]]*[^[:alnum:][:space:]]+[[:space:]]*$/ && | ||
| line[i - 1] ~ /^[[:space:]]*[0-9]+ tasks?[[:space:]]*$/ && | ||
| line[i] ~ /^[[:space:]]*Cursor .+ · [0-9]+([.][0-9]+)?[[:space:]]*%[[:space:]]+Run Everything[[:space:]]*$/ && | ||
| line[i + 1] ~ /^[[:space:]]*[^[:space:]].* · [[:xdigit:]]+[[:space:]]*$/) { | ||
| printf "%s\t%s\n", line[i - 5], line[i] | ||
| exit | ||
| } | ||
| } | ||
| } | ||
| ') |
There was a problem hiding this comment.
Progress recognition now depends on fixed row positions and presentation literals such as Add a follow-up and Run Everything. This conflicts with the repository requirement to bind harness adapters to exposed semantics rather than rendered pixels, and makes presentation-only Cursor changes restore false wedge alarms and require repeated parser updates.
Context Used: If there is a VISION.md file at the root of the re... (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Intent
Fix the watcher false possible-wedge alarms seen on healthy Cursor workers during long reasoning stretches. Scope this honestly: the fleet moved off Cursor to Codex on 2026-08-24, so this is currently a fix for a runtime nobody is using. Do the smallest correct thing: make a changed Cursor numeric token count or context percentage positive liveness evidence, including after the completed-turn age bound, while an unchanged counter and spinner-only redraw must still permit genuine wedge escalation. Match the progress property itself regardless of the spinner/status verb preceding the counter; do not enumerate a closed verb list. Live observed forms include Working, Thinking, Reading, and Running, and behavioral coverage must prove each known form is read plus prove a spinner-only redraw with a static counter still escalates. Keep the change Cursor-aware; do not raise the global idle threshold and do not build a general presentation-liveness framework. If the correct fix becomes large, stop for reconsideration. Follow Firstmate's one-owner, shared-tracked-material, test, shellcheck, documentation, and no-agent-coauthor conventions.
What Changed
Risk Assessment
✅ Low: The Cursor-only change is narrowly bounded, fails closed when structural or marker evidence is unavailable, and preserves wedge escalation for static numeric counters and spinner-only redraws.
Testing
After inspecting the commit scope, the targeted watcher and supervisor suites passed, and a manual production-watcher check demonstrated that genuine numeric progress suppresses the false alarm while static spinner-only redraw still emits a possible-wedge wake; all evidence was captured and the worktree is clean.
Evidence: Manual production-watcher evidence
Source: Manual production-watcher evidence
Advancing 59→60 tokens kept supervision active and reset the old wedge timer. Static 60-token spinner redraw emittedstale: test:fm-cursor-static (idle 501s, possible wedge, escalation 1).Evidence: Cursor watcher behavioral suite
Source: Cursor watcher behavioral suite
Evidence: Supervisor marker-lifecycle suite
Source: Supervisor marker-lifecycle suite
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed (3) ✅
bin/fm-watch.sh:337- The progress-marker write result is ignored. If an existing marker records59 tokens, the pane advances to60 tokens, and this write fails, every later poll rereads59and treats the now-static60as fresh progress, indefinitely clearing wedge tracking. Require the marker update to succeed before returning positive liveness so an unwritable marker fails closed.🔧 Fix: Fail closed on Cursor progress marker writes
1 error still open:
bin/fm-watch.sh:338- The required criterion limits positive liveness to a changed numeric token count or context percentage, but this compares the entire signature including field presence. For example,token=60tokens context=7%followed by the same60 tokenswith the context footer temporarily absent compares unequal and clears the wedge timer despite no numeric progress; alternating footer visibility can suppress escalation indefinitely. Compare numeric fields only when present in both samples, or preserve the last observed value for a temporarily absent field.🔧 Fix: Require shared Cursor fields for progress
1 error still open:
bin/fm-watch.sh:314- The required evidence is Cursor's rendered numeric progress field, and the prior decision says field absence must never count as progress. However, this scans all 40 captured lines for any text such as61 tokens(and similarly anycontext ... 8%), including ordinary response/tool content. A concrete sequence of a realWorking 60 tokenssample followed by the progress row disappearing while displayed content says61 tokenscompares as progress and resets the wedge timer. Scope extraction to Cursor-owned status/footer rows without enumerating verbs, and cover disappearance with misleading numeric content.🔧 Fix: Anchor Cursor progress to reserved footer structure
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
Inspectedgit diff 7b88520c055408a18f1476ecce08be60b2885fc9..26fc66c0329ab66169edcc17f8a3bc094f21f10eto map the authoritative intent to executable coverage.tests/fm-watch-triage.test.shtests/fm-daemon.test.shRan a hermetic two-case productionbin/fm-watch.shfixture and captured its real wake output tocursor-watcher-manual-transcript.txt.Verified cleanup withgit status --short.✅ **Document** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.