Skip to content

fix: make wedge handling aware of decisions and captain holds - #289

Merged
dnth merged 8 commits into
mainfrom
fm/fm-bp-wedge-decision
Nov 1, 2026
Merged

dnth merged 8 commits into
mainfrom
fm/fm-bp-wedge-decision

Conversation

@dnth

@dnth dnth commented Nov 1, 2026 •

Copy link
Copy Markdown
Owner

Summary

wedge threshold:
  worker-owned open decision + opt-in -> defer
  active backlog captain hold -> defer
  existing worktree-write deferral -> unchanged
reminder tick:
  overdue keyed decision -> persisted check wake
  paused/captain-held status or active backlog hold -> no reminder

Reminder suppression matches upstream 1973897e, bin/fm-watch.sh:2616-2617.

Evidence

  • Before (ran): the baseline watcher emitted stale: test:fm-decision-enabled (idle 504s, possible wedge, escalation 1) for a worker waiting on an open decision; tests/fm-watch-triage.test.sh reproduces it.
  • After (ran): the focused reminder regression and full watcher triage suite passed; bash bin/fm-lint.sh, bash bin/fm-doc-audience-check.sh, and the final No-Mistakes pipeline completed with CI green. The preserved Pipeline section below carries its run evidence.

Merge Danger

Door: Two-way

Reverting this change restores the prior wedge and missed-reminder behavior.

Blast Radius: Watcher

Only watcher deferrals, reminder scheduling, and their local configuration and status records change.

Pipeline

Updates from git push no-mistakes

✅ **Intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 error
  • 🚨 bin/fm-watch.sh:1852 - Commit 57fbf86 restores status_is_paused_or_captain_held ... && continue and task_captain_call_open ... && continue, contradicting recorded decision R5: "Remove these two extra eligibility rules." An overdue open key followed by an unrelated pause therefore stops receiving reminders again. The current intent requests these exclusions, but the supplied precedence rule makes R5 authoritative. Confirm which behavior governs before proceeding. Coordinate bin/fm-watch.sh:1852-1853, docs/configuration.md:172, and tests/fm-watch-triage.test.sh:1245 and :1260.
✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Local worker opens a keyed decision or blocker: opt-in defers wedge escalation ✅ pass live live-watcher.json: decision-on, blocked-on; baseline-live.json
Disabled, reserved, resolved, or superseded worker waits preserve wedge escalation ✅ pass live live-watcher.json: decision-off, reserved-decision, reserved-blocked, resolved, newer-working
Captain holds a local backlog task: wedge escalation defers without the worker-wait flag ✅ pass live live-watcher.json: backlog-hold
Local worker writes project output during the quiet interval: existing write deferral remains effective ✅ pass live live-watcher.json: worktree-write
Enable overdue reminders: one check notification per persisted backoff step survives watcher restarts ✅ pass live live-watcher.json: reminder restart 0–2; default-boundaries.json
Resolve and reopen the same local decision key: reminders stop and a fresh lifecycle starts ✅ pass live live-watcher.json: resolved reminder suppressed, same key reopens
Overdue local decisions respect pause, captain-hold, reserved-key, and keyless exclusions ✅ pass live live-watcher.json: reminder paused, captain-held, backlog-hold, reserved, and keyless excluded
  • FM_WATCH_TRIAGE_TEST=<selector> bash tests/fm-watch-triage.test.sh: active-run stale override, worker decision opt-in, persisted reminder backoff, retirement serialization, and backlog captain hold selectors
  • bash tests/fm-wake-drain-unread-status.test.sh
  • python3 .validation-tmp/live_watch.py: real watcher with isolated tmux and synthetic task records
  • python3 .validation-tmp/baseline_live.py: reproduced false wedge using the base watcher
  • python3 .validation-tmp/default_live.py: exercised default reminder threshold and cap
  • Awaited all drivers and test processes, verified disposable tmux servers stopped, removed scratch files, and confirmed a clean working tree
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@dnth
dnth merged commit 9fc4da8 into main Nov 1, 2026
20 checks passed
@dnth
dnth deleted the fm/fm-bp-wedge-decision branch November 1, 2026 23:23
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