Skip to content

feat: add external host-root mode with isolated workers - #1

Closed
YrFnS wants to merge 39 commits into
mainfrom
feat/host-root-mode-upstream
Closed

feat: add external host-root mode with isolated workers#1
YrFnS wants to merge 39 commits into
mainfrom
feat/host-root-mode-upstream

Conversation

@YrFnS

@YrFnS YrFnS commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Intent

Update FirstMate PR kunchenguid#1238 so Second Brain remains the instruction and lifecycle root only for the primary supervisor, while ordinary ship and scout workers launch from their isolated target worktree. Workers must load target-repository instructions natively, avoid the full Second Brain startup context, retain FirstMate task briefs, completion signaling, durable host/target identity, recovery, teardown safety, and all supported harness/backend behavior. Preserve secondmate isolation. Rebase the existing PR onto current upstream main, resolve conflicts without dropping newer upstream semantic busy-state, Herdr, dispatch, teardown, or documentation behavior, validate focused and full suites, update the existing PR, and do not merge it.

What Changed

  • Add optional host-root operation and Pi activation so the primary supervisor can run from an external instruction root while keeping FirstMate code and state separate.
  • Launch ship and scout workers from isolated target worktrees with target-native instructions, task briefs, completion signaling, and durable host/target identity across supported harnesses and backends.
  • Harden overlap checks, endpoint binding, recovery, supervision, and teardown while preserving secondmate isolation, with supporting documentation and regression coverage.

Risk Assessment

⚠️ Medium: Captain, no material defects remain, but the broad cross-harness worker-routing, recovery, and teardown changes retain moderate integration risk pending the dedicated test stage.

Testing

HEAD and diff checks, a real Herdr/Treehouse worker lifecycle, the focused acceptance suite, and the full non-analysis behavior suite were exercised; the full run’s only failure was a Pi TUI observation race, its durable export proved the product had succeeded, and the minimal test correction passed the complete Pi Calm suite, while expected opt-in/live-backend skips remained. An initial broad attempt ran one passing embedded ShellCheck check before selection was corrected; no dedicated lint or static-analysis suites ran. No screenshot was applicable because this is a CLI/runtime isolation change, so reviewer-visible evidence is provided as a real lifecycle transcript and rendered HTML export.

Evidence: Real Herdr host-root lifecycle transcript

A real Herdr worker launched in an isolated Treehouse target, loaded target instructions, retained distinct FM_HOST_ROOT/FM_TARGET_WORKTREE identity, completed through status-log reconciliation, and tore down without dirtying the host or primary target.

+ set -u
+++ dirname tests/fm-backend-herdr-host-root-e2e.test.sh
++ cd tests/..
++ pwd
+ ROOT=/home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC
++ mktemp -d /tmp/fm-herdr-host-root-e2e.XXXXXX
+ TMP_ROOT=/tmp/fm-herdr-host-root-e2e.Uo1jKy
+ SESSION=fm-lab-host-root-e2e-249578
+ ID=host-root-e2e
+ WT=
+ command -v herdr
+ command -v jq
+ command -v treehouse
+ . /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/tests/herdr-test-safety.sh
++ set -u
++ export FM_GATE_REFUSE_BYPASS=1
++ FM_GATE_REFUSE_BYPASS=1
++++ dirname /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/tests/herdr-test-safety.sh
+++ cd /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/tests/..
+++ pwd
++ HERDR_TEST_SAFETY_DIR=/home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC
++ . /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/bin/fm-herdr-lab.sh
+++ set -u
+++ '[' /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/bin/fm-herdr-lab.sh = tests/fm-backend-herdr-host-root-e2e.test.sh ']'
+ export HERDR_SESSION=fm-lab-host-root-e2e-249578
+ HERDR_SESSION=fm-lab-host-root-e2e-249578
+ export FM_HERDR_LAB_STATE_DIR=/tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
+ FM_HERDR_LAB_STATE_DIR=/tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
+ trap cleanup EXIT
+ fm_herdr_lab_prepare fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578 sessions state_dir tripwire
+ fm_herdr_lab_validate_name fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578
+ [[ fm-lab-host-root-e2e-249578 =~ ^fm-lab-[a-zA-Z0-9][a-zA-Z0-9_-]*$ ]]
+ return 0
+ command -v herdr
+ command -v jq
++ fm_herdr_lab_session_list fm-lab-host-root-e2e-249578
+ sessions='{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
+ printf %s '{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
+ jq -e --arg name fm-lab-host-root-e2e-249578 '.sessions[]? | select(.name == $name)'
++ fm_herdr_lab_state_dir
++ printf %s /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
+ state_dir=/tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
++ fm_herdr_lab_tripwire_path fm-lab-host-root-e2e-249578
+++ fm_herdr_lab_state_dir
+++ printf %s /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
++ printf %s/%s.fleet-state.json /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state fm-lab-host-root-e2e-249578
+ tripwire=/tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json
+ mkdir -p /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
+ '[' '!' -e /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json ']'
+ fm_herdr_lab_fleet_state fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578 sessions snapshot
++ fm_herdr_lab_session_list fm-lab-host-root-e2e-249578
+ sessions='{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
++ printf %s '{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
++ jq -c $'\n    [.sessions[]? | select(.default == true)]\n    | if length == 1 and .[0].name == "default" and .[0].running == true\n      then .[0] | {name, default, running, socket_path}\n      else empty\n      end\n  '
+ snapshot='{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}'
+ '[' -n '{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}' ']'
+ printf '%s\n' '{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}'
+ HOST=/tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ PROJECT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/target
+ HOME_ROOT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/home
+ FAKEBIN=/tmp/fm-herdr-host-root-e2e.Uo1jKy/fakebin
+ OBS=/tmp/fm-herdr-host-root-e2e.Uo1jKy/home/worker-observation
+ make_repo /tmp/fm-herdr-host-root-e2e.Uo1jKy/host make_host
+ local dir=/tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ shift
+ mkdir -p /tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/host init -q
+ make_host /tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ printf 'host instructions\n'
+ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/host add .
+ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/host -c 'user.name=Firstmate Tests' -c [email protected] commit -qm initial
+ make_repo /tmp/fm-herdr-host-root-e2e.Uo1jKy/target make_target
+ local dir=/tmp/fm-herdr-host-root-e2e.Uo1jKy/target
+ shift
+ mkdir -p /tmp/fm-herdr-host-root-e2e.Uo1jKy/target
+ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/target init -q
+ make_target /tmp/fm-herdr-host-root-e2e.Uo1jKy/target
+ printf 'target instructions\n'
+ printf 'target\n'
+ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/target add .
+ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/target -c 'user.name=Firstmate Tests' -c [email protected] commit -qm initial
+ mkdir -p /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/data /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/config /tmp/fm-herdr-host-root-e2e.Uo1jKy/fakebin
+ cat
+ chmod +x /tmp/fm-herdr-host-root-e2e.Uo1jKy/fakebin/codex
+ cd /tmp/fm-herdr-host-root-e2e.Uo1jKy/host
++ basename /tmp/fm-herdr-host-root-e2e.Uo1jKy/target
+ FM_ROOT_OVERRIDE=/home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC
+ FM_HOME=/tmp/fm-herdr-host-root-e2e.Uo1jKy/home
+ FM_HOST_ROOT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/bin/fm-brief.sh host-root-e2e target
warn: no registry at /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/data/projects.md; defaulting target to no-mistakes off
+ SPAWN_OUT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/spawn.out
+ cd /tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ PATH=/tmp/fm-herdr-host-root-e2e.Uo1jKy/fakebin:/home/e2next/.codex/packages/standalone/releases/0.146.0-x86_64-unknown-linux-musl/codex-path:/home/e2next/.supercode/bin:/home/e2next/.local/bin:/home/e2next/.npm-global/bin:/home/e2next/.npm-global/bin:/home/e2next/.bun/bin:/home/e2next/.supercode/bin:/home/e2next/.local/bin:/home/e2next/.supercode/bin:/home/e2next/.local/bin:/home/e2next/.cargo/bin:/home/e2next/.npm-global/bin:/home/e2next/.npm-global/bin:/home/e2next/.bun/bin:/home/e2next/.local/bin:/usr/local/bin:/usr/bin:/bin
+ FM_SPAWN_NO_GUARD=1
+ FM_ROOT_OVERRIDE=/home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC
+ FM_HOME=/tmp/fm-herdr-host-root-e2e.Uo1jKy/home
+ FM_HOST_ROOT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/bin/fm-spawn.sh host-root-e2e /tmp/fm-herdr-host-root-e2e.Uo1jKy/target --harness codex --backend herdr --scout
++ seq 1 100
+ for _ in $(seq 1 100)
+ '[' -s /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/worker-observation ']'
+ '[' -e /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.turn-ended ']'
+ sleep 0.1
+ for _ in $(seq 1 100)
+ '[' -s /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/worker-observation ']'
+ '[' -e /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.turn-ended ']'
+ break
+ '[' -s /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/worker-observation ']'
+ '[' -e /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.turn-ended ']'
+ META=/tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.meta
+ '[' -f /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.meta ']'
++ sed -n 's/^worktree=//p' /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.meta
+ WT=/home/e2next/.treehouse/target-df91f7/1/target
++ sed -n 's/^herdr_pane_id=//p' /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.meta
+ PANE=w1:p2
+ '[' -n /home/e2next/.treehouse/target-df91f7/1/target ']'
+ '[' -d /home/e2next/.tree

... [3044 bytes truncated] ...

DE=/home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC
+ FM_HOME=/tmp/fm-herdr-host-root-e2e.Uo1jKy/home
+ FM_HOST_ROOT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/bin/fm-decision-hold.sh complete host-root-e2e --none
+ TEARDOWN_OUT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/teardown.out
+ cd /tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ FM_ROOT_OVERRIDE=/home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC
+ FM_HOME=/tmp/fm-herdr-host-root-e2e.Uo1jKy/home
+ FM_HOST_ROOT=/tmp/fm-herdr-host-root-e2e.Uo1jKy/host
+ /home/e2next/.no-mistakes/worktrees/b3d28f9e34f5/01KYY0FT6X7BB6X6PZFN82RYAC/bin/fm-teardown.sh host-root-e2e
+ '[' '!' -e /tmp/fm-herdr-host-root-e2e.Uo1jKy/home/state/host-root-e2e.meta ']'
+ '[' '!' -f /home/e2next/.treehouse/target-df91f7/1/target/worker-edit.txt ']'
++ cd /tmp/fm-herdr-host-root-e2e.Uo1jKy/target
++ treehouse status
+ TREEHOUSE_OUT='1     available    ~/.treehouse/target-df91f7/1/target'
+ printf '%s\n' '1     available    ~/.treehouse/target-df91f7/1/target'
+ awk '$2 == "available" { found = 1 } END { exit !found }'
+ herdr pane get w1:p2 --session fm-lab-host-root-e2e-249578
+ WT=
++ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/host status --short
+ '[' -z '' ']'
++ git -C /tmp/fm-herdr-host-root-e2e.Uo1jKy/target status --short
+ '[' -z '' ']'
+ herdr_safe_stop_and_delete fm-lab-host-root-e2e-249578
+ fm_herdr_lab_teardown fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578 tripwire sessions delete_status=0
+ fm_herdr_lab_validate_name fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578
+ [[ fm-lab-host-root-e2e-249578 =~ ^fm-lab-[a-zA-Z0-9][a-zA-Z0-9_-]*$ ]]
+ return 0
++ fm_herdr_lab_tripwire_path fm-lab-host-root-e2e-249578
+++ fm_herdr_lab_state_dir
+++ printf %s /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
++ printf %s/%s.fleet-state.json /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state fm-lab-host-root-e2e-249578
+ tripwire=/tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json
+ '[' -f /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json ']'
++ fm_herdr_lab_session_list fm-lab-host-root-e2e-249578
+ sessions='{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"},{"default":false,"name":"fm-lab-host-root-e2e-249578","running":true,"session_dir":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578","socket_path":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578/herdr.sock"}]}'
+ printf %s '{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"},{"default":false,"name":"fm-lab-host-root-e2e-249578","running":true,"session_dir":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578","socket_path":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578/herdr.sock"}]}'
+ jq -e --arg name fm-lab-host-root-e2e-249578 '.sessions[]? | select(.name == $name)'
+ fm_herdr_lab_stop fm-lab-host-root-e2e-249578
+ sleep 0.5
+ fm_herdr_lab_refuse_if_default fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578 info flag
+ fm_herdr_lab_validate_name fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578
+ [[ fm-lab-host-root-e2e-249578 =~ ^fm-lab-[a-zA-Z0-9][a-zA-Z0-9_-]*$ ]]
+ return 0
++ fm_herdr_lab_session_list fm-lab-host-root-e2e-249578
+ info='{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"},{"default":false,"name":"fm-lab-host-root-e2e-249578","running":false,"session_dir":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578","socket_path":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578/herdr.sock"}]}'
++ printf %s '{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"},{"default":false,"name":"fm-lab-host-root-e2e-249578","running":false,"session_dir":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578","socket_path":"/home/e2next/.config/herdr/sessions/fm-lab-host-root-e2e-249578/herdr.sock"}]}'
++ jq -r --arg name fm-lab-host-root-e2e-249578 '.sessions[]? | select(.name == $name) | .default'
+ flag=false
+ '[' false = false ']'
+ return 0
+ fm_herdr_lab_raw fm-lab-host-root-e2e-249578 session delete fm-lab-host-root-e2e-249578 --json
++ fm_herdr_lab_session_list fm-lab-host-root-e2e-249578
+ sessions='{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
+ printf %s '{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
+ jq -e --arg name fm-lab-host-root-e2e-249578 '.sessions[]? | select(.name == $name)'
+ fm_herdr_lab_verify_tripwire fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578 tripwire
+ fm_herdr_lab_check_tripwire fm-lab-host-root-e2e-249578
+ local name=fm-lab-host-root-e2e-249578 tripwire before after
++ fm_herdr_lab_tripwire_path fm-lab-host-root-e2e-249578
+++ fm_herdr_lab_state_dir
+++ printf %s /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
++ printf %s/%s.fleet-state.json /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state fm-lab-host-root-e2e-249578
+ tripwire=/tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json
+ '[' -f /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json ']'
++ cat /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json
+ before='{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}'
++ fm_herdr_lab_fleet_state fm-lab-host-root-e2e-249578
++ local name=fm-lab-host-root-e2e-249578 sessions snapshot
+++ fm_herdr_lab_session_list fm-lab-host-root-e2e-249578
++ sessions='{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
+++ printf %s '{"sessions":[{"default":true,"name":"default","running":true,"session_dir":"/home/e2next/.config/herdr","socket_path":"/home/e2next/.config/herdr/herdr.sock"}]}'
+++ jq -c $'\n    [.sessions[]? | select(.default == true)]\n    | if length == 1 and .[0].name == "default" and .[0].running == true\n      then .[0] | {name, default, running, socket_path}\n      else empty\n      end\n  '
++ snapshot='{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}'
++ '[' -n '{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}' ']'
++ printf '%s\n' '{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}'
+ after='{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}'
+ '[' '{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}' = '{"name":"default","default":true,"running":true,"socket_path":"/home/e2next/.config/herdr/herdr.sock"}' ']'
++ fm_herdr_lab_tripwire_path fm-lab-host-root-e2e-249578
+++ fm_herdr_lab_state_dir
+++ printf %s /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state
++ printf %s/%s.fleet-state.json /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state fm-lab-host-root-e2e-249578
+ tripwire=/tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json
+ rm -f /tmp/fm-herdr-host-root-e2e.Uo1jKy/lab-state/fm-lab-host-root-e2e-249578.fleet-state.json
+ trap - EXIT
+ rm -rf /tmp/fm-herdr-host-root-e2e.Uo1jKy
+ printf 'ok - real Herdr host-root spawn, completion, decision inventory, and teardown\n'
ok - real Herdr host-root spawn, completion, decision inventory, and teardown
- Evidence: Successful Pi Calm export captured while diagnosing the test race (local file: /tmp/no-mistakes-evidence/01KYY0FT6X7BB6X6PZFN82RYAC/fm-calm-pi-extension.SFdisk/calm-export.html)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 3 issues found → auto-fixed ✅
  • ⚠️ bin/fm-watch.sh:283 - The host-tmux supervision reference is now the task ID, but the stale path passes it to stale_is_terminal(), whose fallback strips a leading fm-. A supported ID such as fm-foo therefore reads foo.status, delaying terminal wakes until the heartbeat catch-all. Pass the recorded task ID or actual endpoint to the status check.
  • 🚨 bin/fm-spawn.sh:1831 - sq_turnend is shell quoting embedded inside a TOML -c value. Apostrophes produce an invalid TOML escape, while quotes or backslashes can corrupt the value, causing Codex to reject the launch and lose required completion signaling. Serialize the notify command as TOML/JSON before shell-quoting the complete override.
  • 🚨 docs/verification/supervision.md:66 - Intent requires ordinary workers to “avoid the full Second Brain startup context,” but this verification record says Codex and OpenCode “loaded the host AGENTS.md” and emitted a host session-start event. Confirm whether this is stale evidence that must be marked superseded, or whether forbidden host context still enters workers.

🔧 Fix: Captain: fix host-root review regressions
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • git rev-parse HEAD and git diff --stat e595611291247368b982eb729097c54f2b45aa78..b174555be5698848cfef54ac401a0a24ca71d02e
  • /bin/bash -x tests/fm-backend-herdr-host-root-e2e.test.sh
  • bin/fm-test-run.sh tests/fm-host-root-mode.test.sh tests/fm-host-setup.test.sh tests/fm-backend-herdr.test.sh tests/fm-backend.test.sh tests/fm-backend-tmux-smoke.test.sh tests/fm-backend-cmux.test.sh tests/fm-backend-orca.test.sh tests/fm-backend-zellij.test.sh tests/fm-brief.test.sh tests/fm-session-start.test.sh tests/fm-spawn-dispatch-profile.test.sh tests/fm-daemon.test.sh tests/fm-watch-triage.test.sh tests/fm-gate-refuse.test.sh tests/fm-decision-hold-lifecycle.test.sh tests/fm-pr-check-security.test.sh tests/fm-review-diff.test.sh tests/fm-secondmate-harness.test.sh tests/fm-secondmate-lifecycle-e2e.test.sh tests/fm-secondmate-liveness.test.sh tests/fm-secondmate-safety.test.sh tests/fm-teardown-endpoint-safety.test.sh tests/fm-teardown.test.sh --json /tmp/no-mistakes-evidence/01KYY0FT6X7BB6X6PZFN82RYAC/focused-tests.json
  • Full behavior selection from full-tests-no-analysis-selected.txt through bin/fm-test-run.sh, excluding the three dedicated static-analysis suites and masking embedded ShellCheck checks
  • Two isolated pre-fix reruns of tests/fm-calm-pi-extension.test.sh plus preserved pane/export inspection
  • /bin/bash tests/fm-calm-pi-extension.test.sh after the test-only race correction
  • Final git status --short and herdr lab list cleanup checks
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

YrFnS added 30 commits July 30, 2026 10:12
@YrFnS

YrFnS commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

Closing this duplicate fork-local PR. The branch is already the head of upstream PR kunchenguid#1238.

@YrFnS YrFnS closed this Aug 1, 2026
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