Problem
On the OpenCode harness, a secondmate (a firstmate running in its own FM_HOME) never arms its own supervision watcher. Its .opencode/plugins/fm-primary-watch-arm.js shows WATCHER DOWN - SUPERVISION IS OFF (last beat: never) while a crewmate is in flight, so it receives no proactive wakes and has to hand-supervise.
Reproduced 2026-07-15 (OpenCode 1.18.0, GLM 5.2): a secondmate spawned a crewmate; state/.last-watcher-beat in the secondmate home was absent and no fm-watch.sh process existed for that home for the entire session.
Root cause
isPrimaryRoot(root, home) in .opencode/plugins/fm-primary-watch-arm.js returns false for any root that carries a .fm-secondmate-home marker:
if (existsSync(`${root}/.fm-secondmate-home`)) return false;
A secondmate home always has that marker, so ensureArm() returns "not-primary" on every session.idle and the watcher never arms. But a secondmate IS the primary of its own home and must arm its own watcher to supervise its own crewmates - consistent with the turn-end guard, which already "guards both the main primary and a secondmate's own primary session".
Proposed patch
Drop the blanket exclusion; keep only the home/root MISMATCH guard, which already prevents arming a foreign secondmate home. sessionOwnsLock() continues to gate arming to the lock-owning session, so this can never arm a foreign home's watcher.
- if (existsSync(`${root}/.fm-secondmate-home`)) return false;
- if (home && home !== root && existsSync(`${home}/.fm-secondmate-home`)) return false;
+ // A secondmate home carries a .fm-secondmate-home marker but IS the primary of its own
+ // home and must arm its own watcher to supervise its own crewmates. Only a home/root
+ // MISMATCH is disqualifying; a secondmate's own session has root === home.
+ // sessionOwnsLock() still gates arming to the session that owns this home's lock.
+ if (home && home !== root && existsSync(`${home}/.fm-secondmate-home`)) return false;
Offer
Happy to open a PR with this change plus a regression test if that is welcome.
Problem
On the OpenCode harness, a secondmate (a firstmate running in its own
FM_HOME) never arms its own supervision watcher. Its.opencode/plugins/fm-primary-watch-arm.jsshowsWATCHER DOWN - SUPERVISION IS OFF(last beat: never) while a crewmate is in flight, so it receives no proactive wakes and has to hand-supervise.Reproduced 2026-07-15 (OpenCode 1.18.0, GLM 5.2): a secondmate spawned a crewmate;
state/.last-watcher-beatin the secondmate home was absent and nofm-watch.shprocess existed for that home for the entire session.Root cause
isPrimaryRoot(root, home)in.opencode/plugins/fm-primary-watch-arm.jsreturnsfalsefor any root that carries a.fm-secondmate-homemarker:A secondmate home always has that marker, so
ensureArm()returns"not-primary"on everysession.idleand the watcher never arms. But a secondmate IS the primary of its own home and must arm its own watcher to supervise its own crewmates - consistent with the turn-end guard, which already "guards both the main primary and a secondmate's own primary session".Proposed patch
Drop the blanket exclusion; keep only the home/root MISMATCH guard, which already prevents arming a foreign secondmate home.
sessionOwnsLock()continues to gate arming to the lock-owning session, so this can never arm a foreign home's watcher.Offer
Happy to open a PR with this change plus a regression test if that is welcome.