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
31 changes: 30 additions & 1 deletion bin/backends/herdr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2189,6 +2189,16 @@ fm_backend_herdr_busy_state() { # <target>
FM_BACKEND_HERDR_SUBMIT_POLLS=${FM_BACKEND_HERDR_SUBMIT_POLLS:-6}
FM_BACKEND_HERDR_SUBMIT_MIN_SLEEP=${FM_BACKEND_HERDR_SUBMIT_MIN_SLEEP:-0.6}

# FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY (default 3): seconds to wait before
# re-checking a `blocked` transition. herdr can emit transient `blocked` events
# when the OpenCode TUI shows a brief input prompt between tool calls; the
# re-check queries the live agent status and absorbs the transition if the
# agent has already resumed `working`. This also covers long-running commands
# (e.g. `sleep 600`) where herdr correctly reports `working` during execution.
# A real wedge (permission dialog, stuck prompt) persists far longer than this
# delay, so genuine escalations are only delayed by this many seconds.
FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY=${FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY:-3}

fm_backend_herdr_submit_confirm_budget() { # <caller-budget-seconds>
awk -v b="${1:-0}" -v m="$FM_BACKEND_HERDR_SUBMIT_MIN_SLEEP" 'BEGIN {
b += 0
Expand Down Expand Up @@ -2383,7 +2393,7 @@ fm_backend_herdr_escalation_marker() { # <state_dir> <window>
# with no output. <session> reconstructs the window ("<session>:<pane_id>") for
# the marker key, matching the watcher's own key scheme.
fm_backend_herdr_apply_transition() { # <state_dir> <session> <record>
local state=$1 session=$2 record=$3 pane_id to action window marker
local state=$1 session=$2 record=$3 pane_id to action window marker current_status
pane_id=$(fm_transition_pane_id "$record")
[ -n "$pane_id" ] || return 1
to=$(fm_transition_to_status "$record")
Expand All @@ -2393,6 +2403,25 @@ fm_backend_herdr_apply_transition() { # <state_dir> <session> <record>
case "$action" in
actionable)
if [ ! -e "$marker" ]; then
# Re-check: herdr can emit transient `blocked` transitions when the
# OpenCode TUI shows a brief input prompt between tool calls. Wait a
# short time, then re-query the live agent status. If the agent has
# already resumed `working` (or gone `idle`/`done`), absorb the
# transition instead of escalating a false alarm. This also covers
# long-running commands (e.g. `sleep 600`) where herdr reports
# `working` during command execution. A real wedge (permission dialog,
# stuck prompt) persists far longer than the confirm delay, so genuine
# escalations are only delayed by that many seconds.
# Set FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY=0 to skip the re-check
# (used by tests that lack a live herdr server).
if [ "${FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY:-3}" != "0" ]; then
sleep "$FM_BACKEND_HERDR_BLOCKED_CONFIRM_DELAY"
current_status=$(fm_backend_herdr_agent_status_raw "$session" "$pane_id")
if [ -n "$current_status" ] && [ "$current_status" != "blocked" ]; then
command -v triage_log >/dev/null 2>&1 && triage_log "absorbed transient blocked transition (agent now $current_status): $window"
return 1
fi
fi
printf '%s' "$record"
return 0
fi
Expand Down
8 changes: 8 additions & 0 deletions bin/fm-brief.sh
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ The report is the only thing that survives, so anything worth keeping must be in
7. Never stop, restart, or update the shared \`no-mistakes\` daemon - it is one instance serving
every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
daemon error, append \`blocked: {the daemon error}\` and stop; only firstmate manages the daemon.
8. Use the existing global git identity for every commit. Never set \`user.name\`, \`user.email\`,
\`GIT_AUTHOR_NAME\`, \`GIT_AUTHOR_EMAIL\`, \`GIT_COMMITTER_NAME\`, or \`GIT_COMMITTER_EMAIL\`
to invent an agent identity. The captain's global git config already has the correct author;
do not override it.

# Definition of done
Write your findings to \`$DATA/$ID/report.md\`.
Expand Down Expand Up @@ -374,6 +378,10 @@ $RULE1
7. Never stop, restart, or update the shared \`no-mistakes\` daemon - it is one instance serving
every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
daemon error, append \`blocked: {the daemon error}\` and stop; only firstmate manages the daemon.
8. Use the existing global git identity for every commit. Never set \`user.name\`, \`user.email\`,
\`GIT_AUTHOR_NAME\`, \`GIT_AUTHOR_EMAIL\`, \`GIT_COMMITTER_NAME\`, or \`GIT_COMMITTER_EMAIL\`
to invent an agent identity. The captain's global git config already has the correct author;
do not override it.

# Project memory
If \`AGENTS.md\` or \`CLAUDE.md\` already exists, or if this task produced durable project-intrinsic knowledge, run \`$FM_ROOT/bin/fm-ensure-agents-md.sh .\` in the worktree.
Expand Down
Loading