Skip to content

feat: add external host-root mode - #1238

Open
YrFnS wants to merge 36 commits into
kunchenguid:mainfrom
YrFnS:feat/host-root-mode-upstream
Open

feat: add external host-root mode#1238
YrFnS wants to merge 36 commits into
kunchenguid:mainfrom
YrFnS:feat/host-root-mode-upstream

Conversation

@YrFnS

@YrFnS YrFnS commented Jul 29, 2026

Copy link
Copy Markdown

What Changed

  • Add optional FM_HOST_ROOT execution and managed Pi activation so an external host can remain authoritative while FirstMate code, state, and target worktrees stay isolated.
  • Bind spawning, supervision, recovery, and teardown to recorded physical roots and backend endpoint identity, failing closed on overlap or ambiguous cleanup.
  • Document the four-root contract and add host-root setup, lifecycle, teardown, and backend regression coverage.

Risk Assessment

⚠️ Medium: The Pi worker-role blocker is correctly closed and no new material defects were found, though this broad multi-backend lifecycle change retains integration risk pending the dedicated test step.

Testing

Independently exercised the focused four-root safeguards and real Pi installer, Pi 0.83.0 host-only activation, and Herdr 0.7.5 spawn/completion/decision-inventory/cleanup path; all succeeded, the host stayed unchanged, and the source worktree stayed clean. No screenshot was captured because this is a CLI/Pi RPC change; the real status and RPC artifacts show the reviewer-visible surface.

Evidence: Operator install/status transcript

FirstMate Pi host activator: installed host: /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/host firstmate home: /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/firstmate-home worker backend: herdr

installed /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions/fm-firstmate-host.ts
FirstMate Pi host activator: installed
host: /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/host
firstmate root: /home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB
firstmate home: /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/firstmate-home
worker backend: herdr
FirstMate Pi host activator: installed
host: /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/host
firstmate root: /home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB
firstmate home: /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/firstmate-home
worker backend: herdr
Evidence: Real Pi activation and dormancy summary

At the configured host: active marker present, watcher command available, AFK skill available. Outside it: all three absent.

{
  "atConfiguredHost": {
    "activeStatusMarkers": 1,
    "firstmateWatchCommand": true,
    "afkSkill": true
  },
  "outsideConfiguredHost": {
    "activeStatusMarkers": 0,
    "firstmateWatchCommand": false,
    "afkSkill": false
  }
}
Evidence: Raw Pi RPC response at configured host
{"type":"extension_ui_request","id":"b4571807-eb07-408f-af0e-3ff0919a4389","method":"setStatus","statusKey":"firstmate-host","statusText":"\u001b[38;5;109mFirstMate active\u001b[39m"}
{"type":"response","command":"get_commands","success":true,"data":{"commands":[{"name":"fm-watch-arm-pi","description":"Arm firstmate watcher supervision through the Pi extension instead of foreground bash.","source":"extension","sourceInfo":{"path":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions/fm-firstmate-host.ts","source":"auto","scope":"user","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent"}},{"name":"llama","description":"Manage llama.cpp router models","source":"extension","sourceInfo":{"path":"<inline:llama.cpp>","source":"inline","scope":"temporary","origin":"top-level"}},{"name":"skill:afk","description":"Enter away-mode supervision when the captain invokes /afk, says they are going afk, `state/.afk` exists, an incoming message starts with `FM_INJECT_MARK`, or any `state/.subsuper-*` marker is involved. It sets a durable away-mode flag so the sub-supervisor daemon can self-handle routine wakes and escalate captain-relevant events plus bounded declared-external-wait rechecks as batched digests during walk-away stretches, then exits automatically when any real unmarked message returns firstmate to full per-wake responsiveness.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/afk/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:ahoy","description":"Recap visible session events since the prior real captain message plus visibly unanswered captain decisions when the captain explicitly invokes /ahoy, with a Bearings fallback when /ahoy is the session's first real captain message.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/ahoy/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:ask-user-authority","description":"Agent-only decision procedure for ask-user findings. Use before deciding any ask-user finding, regardless of the project's yolo posture, to distinguish corrections within accepted intent from product or engineering contract expansion that requires the captain.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/ask-user-authority/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:bearings","description":"Generate a \"pick up where I left off\" fleet digest from firstmate's live fleet state. Use when the captain invokes /bearings or asks for a bearings report, morning brief, status report, catch-up, \"where did I leave off\", or \"what's in the works\". Plain /bearings is chat-only by default, while /bearings file explicitly writes the dated data/status-report-<YYYY-MM-DD>.md artifact; live PR enrichment remains opt-in and composes with file mode.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/bearings/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:bootstrap-diagnostics","description":"Agent-only handling playbook for session-start bootstrap diagnostics. Use whenever the session-start digest's bootstrap section prints an actionable diagnostic line - MISSING, MISSING_MANUAL, BACKEND_INVALID, NEEDS_GH_AUTH, TANGLE, CREW_DISPATCH invalid, FLEET_SYNC, PR_CHECK_MIGRATION, SECONDMATE_SYNC, SECONDMATE_LIVENESS, NUDGE_SECONDMATES, or FMX - or when a standalone bin/fm-bootstrap.sh run prints one of those lines. A silent bootstrap section, or a BOOTSTRAP_INFO fact, means no skill load.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/bootstrap-diagnostics/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:decision-hold-lifecycle","description":"Agent-only policy for completing investigations and visual reviews without losing unresolved captain decisions. Load before treating an investigation, scout report, structured review, or Lavish review as complete, before ending a visual review that exposed a decision, and when recording or routing the captain's answer.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/decision-hold-lifecycle/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:diagnostic-reasoning","description":"Agent-only procedure for diagnosing reported bugs. Use before scoping a reported bug and before acting on a diagnostic report. Owns end-user-aligned reproduction, causal separation, divergent-path and history inspection, counterfactual testing, and disconfirming evidence.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/diagnostic-reasoning/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:firstmate-codexapp","description":"Agent-only playbook for coordinating visible Codex Desktop threads alongside Firstmate without pretending they are a selectable shell backend. Use before creating, reading, steering, archiving, debugging, or reviewing a Codex App visible thread for Firstmate work, and before responding to requests to make Codex App native to Firstmate.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/firstmate-codexapp/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:firstmate-coding-guidelines","description":"Agent-only reference for changing firstmate's shared, tracked material per AGENTS.md section 1. Use before editing any of that material, whether working as firstmate directly or as a crewmate briefed on a firstmate-repo task. Covers the knowledge-placement decision tree, the one-owner rule for contracts, the inline-stub pattern for content moved into a skill, AGENTS.md size discipline, trigger hygiene for new skills, and repo style rules (one sentence per line, plain dash, no agent co-author, shellcheck-clean bin scripts, colocated tests, and maintainer-verification evidence).","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/firstmate-coding-guidelines/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:firstmate-orca","description":"Agent-only operator checklist for Firstmate's Orca runtime backend. Use when switching to Orca, spawning or supervising Orca-backed work, smoke-testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/firstmate-orca/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:fmx-respond","description":"Agent-only playbook for handling X mode mentions and follow-ups. Use on an \"x-mention <request_id>\" check wake to read the stashed mention, classify it, act autonomously on eligible requests, reply or dismiss, and link spawned work. Also use on an \"x-mode-error ...\" check wake to report the X-mode configuration blocker instead of answering a mention. Also use on milestone and terminal wakes for an X-mode-linked task before posting completion follow-ups, ending terminal outcomes with --final. Loaded only when X mode is enabled.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/fmx-respond/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:harness-adapters","description":"Agent-only reference for firstmate harness operations. Use before spawning or recovering a crewmate or secondmate, handling a trust dialog, sending a harness-specific skill invocation, interrupting or exiting an agent, resuming an exited agent, or verifying a new harness adapter. Contains verified facts for claude, codex, opencode, pi, pi-signed, grok, and kimi.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/harness-adapters/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:project-management","description":"Agent-only procedure for Firstmate project management. Use before adding, creating, removing, or initializing a project. Cloning or registering a project is add intake and uses the same trigger. Owns project add, create, clone, remove, initialization, registry, delivery-mode, autonomy, and outward-consent decisions.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/project-management/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:quota-array-dispatch","description":"Agent-only decision procedure for resolving a matched crew-dispatch profile array from current quota-axi output, including quota-window pace signals. Load when a dispatch rule or default resolves to more than one profile candidate.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/quota-array-dispatch/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:secondmate-provisioning","description":"Agent-only reference for persistent secondmate setup and retirement. Use when creating, seeding, validating, launching, recovering, handing backlog to, pushing inherited local material into, or retiring a secondmate home, or when editing data/secondmates.md. Covers home leases, transactional seeding, project clone restrictions, secondmate harness pins, inherited local-material push, idle charter, handoff helper, and teardown safety.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/secondmate-provisioning/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:stow","description":"Sweep the current session for uncaptured durable knowledge and file it to disk before a context reset. Use when the captain invokes /stow (e.g. \"/stow\", \"stow what you've learned\"), before a session reset or context compaction, or periodically to keep operational memory current.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/stow/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:stuck-crewmate-recovery","description":"Agent-only playbook for stuck or missing ordinary Firstmate direct reports. Use when the session-start digest reports an ordinary direct report's endpoint dead or its metadata has no window, or after a stale wake, looping pane, repeated confusion, an answered-by-brief question, an unresponsive crewmate, or a failed steer. Reconciles recorded work before escalating from targeted inspection through safe relaunch or failure.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/stuck-crewmate-recovery/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}},{"name":"skill:updatefirstmate","description":"Self-update a running firstmate and its secondmates to the latest from origin. Use when the captain invokes /updatefirstmate (e.g. \"/updatefirstmate\", \"update firstmate\", \"pull the latest firstmate\"). Fast-forwards this firstmate repo's default branch and every secondmate home from origin (fast-forward only, never forced, never disruptive), then re-reads AGENTS.md and nudges each updated secondmate to do the same, so the whole tree runs the latest bin/ and instructions.","source":"skill","sourceInfo":{"path":"/home/e2next/.no-mistakes/worktrees/cc6f7d3ce8aa/01KYRXQJTDTT9535C4ENEZFYGB/.agents/skills/updatefirstmate/SKILL.md","source":"extension:fm-firstmate-host","scope":"temporary","origin":"top-level","baseDir":"/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent/extensions"}}]}}
{"type":"extension_ui_request","id":"ccffb567-6321-46b7-996f-1e6b9a2173fe","method":"setStatus","statusKey":"firstmate-host"}
Evidence: Raw Pi RPC response outside configured host
{"type":"response","command":"get_commands","success":true,"data":{"commands":[{"name":"llama","description":"Manage llama.cpp router models","source":"extension","sourceInfo":{"path":"<inline:llama.cpp>","source":"inline","scope":"temporary","origin":"top-level"}}]}}
Evidence: Host immutability evidence

Baseline and current AGENTS.md SHA-256 values matched; host repository unchanged: yes.

baseline AGENTS.md sha256: e4418d0a112bbfeef8e3fe1510f83dd85c468d185bccd277e225f0fdcb55333a
current AGENTS.md sha256:  e4418d0a112bbfeef8e3fe1510f83dd85c468d185bccd277e225f0fdcb55333a
host repository unchanged: yes

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

✅ No issues found.

🔧 **Rebase** - 2 issues found → auto-fixed ✅
  • ⚠️ tests/fm-backend-herdr.test.sh - merge conflict rebasing onto origin/main
  • ⚠️ tests/fm-kimi-harness.test.sh - merge conflict rebasing onto origin/main

🔧 Fix applied.
✅ Re-checked - no issues remain.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • 🚨 .pi/extensions/lib/fm-host-activator.ts:92 - Host-root Pi workers start from FM_HOST_ROOT with FM_TARGET_WORKTREE set, but this activator gates only on cwd. It therefore activates inside every Pi worker too, appending primary supervisor policy and loading the primary guard/watcher extensions alongside the worker’s task extension. Return early when FM_TARGET_WORKTREE is non-empty and add a worker-shaped activation regression.

🔧 Fix: Captain: guard host-root Pi workers from supervisor activation
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • bin/fm-test-run.sh --json /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/focused-tests.json tests/fm-host-root-mode.test.sh tests/fm-host-setup.test.sh
  • tests/fm-backend-herdr-host-root-e2e.test.sh
  • env -u FM_ROOT_OVERRIDE -u FM_HOME -u FM_HOST_ROOT -u FM_BACKEND PI_CODING_AGENT_DIR=/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/pi-agent HOME=/tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/user-home bin/fm-host-setup.sh install /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/host --home /tmp/no-mistakes-evidence/01KYRXQJTDTT9535C4ENEZFYGB/manual-host-demo/firstmate-home --backend herdr and status
  • Real pi --approve --mode rpc --no-session probes from the configured host and an outside directory with PI_OFFLINE=1
  • Compared committed/current host AGENTS.md SHA-256 values and ran git -C &lt;host&gt; status --short
  • git rev-parse HEAD; git status --short --branch; git diff --name-only; git diff --cached --name-only
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@kunchenguid

kunchenguid commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Automated reminder: thanks for the PR! This branch currently has a merge conflict with the base branch.

When you get a chance, please rebase onto (or merge) the latest base branch, resolve the conflict, and push. After that, checks will re-run and the PR will get looked at again.

Noted for firstmate#1238 at eb42af2e.

YrFnS added 27 commits July 30, 2026 10:12
@YrFnS
YrFnS force-pushed the feat/host-root-mode-upstream branch from eb42af2 to 39e7244 Compare July 30, 2026 07:48
@YrFnS YrFnS changed the title feat: activate FirstMate from external host roots feat: add external host-root mode Jul 30, 2026
@kunchenguid kunchenguid removed the wheelhouse:pending-contributor-action Managed by Wheelhouse label Jul 30, 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.

2 participants