Skip to content

fix(herdr): add blocked-transition confirm delay to suppress transient OpenCode false alarms - #1237

Open
burakgizlice wants to merge 1 commit into
kunchenguid:mainfrom
burakgizlice:fm/herdr-blocked-confirm-delay
Open

fix(herdr): add blocked-transition confirm delay to suppress transient OpenCode false alarms#1237
burakgizlice wants to merge 1 commit into
kunchenguid:mainfrom
burakgizlice:fm/herdr-blocked-confirm-delay

Conversation

@burakgizlice

Copy link
Copy Markdown

Problem

Herdr reports agent-status changes via its transition event stream. When a pane
transitions to blocked, firstmate immediately escalates it as a stale wake,
with the message: stale: <window> (herdr: agent blocked - waiting on human, escalated immediately, not via wedge timer).

The OpenCode TUI briefly shows a "waiting for input" state between tool calls
as the agent cycles through its working loop. Herdr correctly reports these
transitions as blocked -> working -> blocked -> working on every tool
call. The existing per-pane dedupe marker prevents re-escalating the same
blocked edge, but each working transition clears the marker, so the next
blocked edge is treated as a fresh actionable event -- producing a firehose
of stale wake notifications every few seconds.

This is especially visible during:

  • Normal agent working cycles (transient prompts between tool calls)
  • Long-running commands like sleep 600 && no-mistakes axi status (not a
    wedge, just the agent waiting for itself)

Solution

Add a re-check step in fm_backend_herdr_apply_transition (the herdr
backend function that routes transition events through the shared policy
table). When a blocked transition arrives:

  1. Wait 3 seconds (configurable via FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY).
  2. Re-query the live agent status via herdr's agent.get API.
  3. If the agent has already resumed working (or gone idle/done),
    absorb the transition silently -- this was a transient false alarm.
  4. If the agent is still blocked, escalate as before -- this is a real
    wedge (permission dialog, stuck prompt, interactive menu).

This handles all three cases correctly:

  • Transient prompts (1-2s): after 3s the agent is working -> absorbed.
  • Long-running commands (sleep 600): herdr correctly reports working
    during command execution, so no blocked transition is emitted at all.
  • Real wedges: the agent stays blocked for 3+ seconds -> escalated.

The 3-second delay is a deliberate trade-off: a real wedge is delayed by
3 seconds, but the firehose of false alarms (dozens per minute) is eliminated.
The captain sees a notification only when something is genuinely wrong.

Config

FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY (default 3, in seconds). Set to 0
to skip the re-check entirely (used by tests that lack a live herdr server).

Additional change

Also adds a git-identity rule (rule 8) to the crewmate brief scaffold
(bin/fm-brief.sh). Workers sometimes invent an agent identity
(firstmate <firstmate@local>) when committing, instead of using the
captain's global git config. The new rule explicitly forbids overriding any
git identity field.

Testing

  • apply_transition tests pass with FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY=0
  • Shellcheck clean on the modified files
  • When the re-check API call fails (no herdr server, test environment), the
    function falls back safely to the old escalation behavior (fail-safe)

…t OpenCode false alarms

Herdr's agent-status change events can report 'blocked' when the OpenCode
TUI briefly shows an input prompt between tool calls. The agent is actually
working - it has just finished one tool call and is about to start the next -
but the transient 'blocked' edge was treated as actionable immediately,
producing a firehose of stale wake notifications.

The existing per-pane dedupe marker prevents re-escalating the same
blocked edge, but OpenCode cycles through working -> blocked -> working ->
blocked on every tool call, so each new blocked transition is a fresh edge
that re-escalates.

Fix: add a re-check step in fm_backend_herdr_apply_transition. When a
blocked transition arrives, wait 3 seconds (FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY),
then re-query the live agent status via herdr's agent.get API. If the agent
has already resumed 'working' (or gone 'idle'/'done'), absorb the transition
silently. If the agent is still 'blocked', escalate as before.

This also handles long-running commands (e.g. 'sleep 600') correctly:
herdr reports 'working' during command execution, so no blocked
transition is emitted in the first place. A real wedge (permission
dialog, stuck prompt, interactive menu) persists far longer than the
3-second delay, so genuine escalations are only delayed by 3 seconds.

Also adds a git-identity rule to the crewmate brief scaffold (fm-brief.sh
rule 8) so workers never invent an agent identity for commits. They must
use the global git config (user.name/user.email) instead.
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