Skip to content

fix(backend): detach Herdr server from caller lifecycle - #4

Merged
ruby-dlee merged 6 commits into
mainfrom
codex/herdr-server-detach
Jul 17, 2026
Merged

fix(backend): detach Herdr server from caller lifecycle#4
ruby-dlee merged 6 commits into
mainfrom
codex/herdr-server-detach

Conversation

@ruby-dlee

Copy link
Copy Markdown
Owner

Intent

Harden fm_backend_herdr_server_ensure against caller tmux-pane death using a verified setsid-based detached lifecycle while keeping the adapter as the single Herdr lifecycle owner; add honest regression coverage and empirical lab documentation; repair the merge-main conformance baseline resolver exposed by PR #2 post-merge CI; validate, push, and open the fix PR, but do not merge it without fresh Captain authorization.

What Changed

  • Launch Herdr servers through a portable nohup and double-forked setsid path so they survive the initiating tmux pane while the backend adapter remains the lifecycle owner.
  • Register nohup and perl as Herdr prerequisites, provide actionable bootstrap guidance, and document the detached lifecycle with empirical verification.
  • Add detachment and dependency regressions, and harden the conformance baseline resolver to use a verified main-at-HEAD parent without accepting unrelated topic merges.

Risk Assessment

✅ Low: The changes are well-bounded, preserve lifecycle ownership, register the new dependencies, and correctly gate baseline fallback on verified main-at-HEAD state.

Testing

The already-green full shell suite, focused Herdr lifecycle/baseline/bootstrap regressions, and a real Herdr 0.7.3 tmux-pane-death flow all passed after correcting evidence-harness-only setup issues; the transcript proves the compatible server and working pane survived, followed by exact cleanup.

Evidence: Herdr pane-death end-to-end transcript

POST_STATUS running=true compatible=true POST_PANE pane=w1:p1 reachable=true agent_status=working PASS: real Herdr server and working pane survived caller tmux-pane death CLEANUP: isolated session stopped/deleted and transient configuration removed

REAL USER-FLOW: production adapter launch from a disposable tmux pane
versions: tmux 3.7b; herdr 0.7.3; perl=v5.34.1
isolation: XDG_CONFIG_HOME=.test-herdr-xdg-3765-1784318694 (inside test worktree), HERDR_SESSION=fm-lab-nm-detach-3765-1784318694
lifecycle owner: bin/backends/herdr.sh via fm_backend_herdr_container_ensure; no external server launcher
DRIVER_PHASE container_ensure
DRIVER_PHASE use_seeded_pane
DRIVER pid=3918 ppid=3773 pgid=3918 tty=ttys001
SERVER pid=3995 ppid=1 pgid=3992 tty=??
SERVER_ARGS /Users/dongkeun/.local/bin/herdr server --session fm-lab-nm-detach-3765-1784318694
STATUS pre_running=true compatible=true herdr_native_detached_capability=false
PANE workspace=w1 tab=w1:t1 pane=w1:p1 agent_status=working
READY
ASSERT pre-kill: server is already reparented and isolated from caller process group
ACTION: destroyed launching tmux session nm-herdr-detach-3765-1784318694; launching driver PID 3918 is gone
POST_SERVER 3995     1  3992 ??       /Users/dongkeun/.local/bin/herdr server --session fm-lab-nm-detach-3765-1784318694
POST_STATUS running=true compatible=true
POST_PANE pane=w1:p1 reachable=true agent_status=working
PASS: real Herdr server and working pane survived caller tmux-pane death
CLEANUP: stopped and deleted only fm-lab-nm-detach-3765-1784318694
CLEANUP: removed transient worktree-local Herdr config .test-herdr-xdg-3765-1784318694
- Outcome: 🔧 1 issue found → auto-fixed ✅ across 2 runs (1h27m11s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 2 issues found → auto-fixed (2) ✅
  • ⚠️ tests/fm-backend.test.sh:98 - When CI runs after a squash, rebase, fast-forward, or ordinary single-parent push to main, every main ref equals HEAD and is skipped, while this fallback only accepts merge commits. BASE_REF resolution then aborts the suite despite HEAD^ being available. Handle verified main-at-HEAD single-parent commits as well.
  • ⚠️ bin/backends/herdr.sh:142 - The launcher makes nohup and perl mandatory, but the canonical fm_backend_required_tools registry still declares only herdr, jq, and treehouse. Bootstrap can report a healthy Herdr environment before spawn or recovery fails. Register and document both dependencies, or use the already-required python3 runtime.

🔧 Fix: Fix Herdr preflight and single-parent baseline resolution
2 warnings still open:

  • ⚠️ tests/fm-backend.test.sh:107 - The merge fallback returns HEAD^1 whenever HEAD has multiple parents, even if no candidate main ref equals HEAD. With absent or stale main refs—or an arbitrary topic-branch merge—this silently selects an unrelated baseline. Gate this fallback on verified main-at-HEAD state or otherwise prove HEAD is integrated main.
  • ⚠️ bin/fm-backend.sh:319 - Registering nohup and perl routes missing dependencies through bootstrap, but neither tool has an install_cmd or manual_install_url entry. Bootstrap therefore emits MISSING: <tool> (install: ), and fm-bootstrap.sh install <tool> reports it as unknown. Add actionable install/manual mappings or use the already-required python3 runtime.

🔧 Fix: Gate baseline fallback and guide Herdr dependency recovery
✅ Re-checked - no issues remain.

🔧 **Test** - 1 issue found → auto-fixed ✅
  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"

🔧 Fix: Fix baseline fixture helper dependencies
✅ Re-checked - no issues remain.

  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
  • Baseline supplied as successful: command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
  • bash tests/fm-backend-herdr.test.sh
  • FM_TEST_FOCUSED=review-round-35 bash tests/fm-backend.test.sh
  • FM_TEST_FOCUSED=review-round-35 bash tests/fm-bootstrap.test.sh
  • Manual real-stack check: invoked production fm_backend_herdr_container_ensure from a disposable tmux pane, destroyed it with tmux kill-session, then verified survival using scoped herdr status --json, herdr pane get, and herdr agent get calls
  • Verified exact isolated-session cleanup, absence of test processes/configuration, and a clean git status --short
✅ **Document** - passed

✅ No issues found.

🔧 **Lint** - 1 issue found → auto-fixed ✅
  • ⚠️ linter found issues (exit code 1)

🔧 Fix: Captain: fix detached Herdr lint findings
✅ Re-checked - no issues remain.

✅ **Push** - passed

✅ No issues found.

@ruby-dlee
ruby-dlee merged commit 906f9c8 into main Jul 17, 2026
4 checks passed
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