You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Windows/Git Bash: agmsg_agent_pid never resolves (MSYS ppid walk cannot cross into native processes) — cc-instance.* is never written, actas locks always GC as stale, despawn reports no-live-lock #371
Shell: Git for Windows 2.42.0 / GNU bash 5.2.15 (MSYS), uname -s = MINGW64_NT-10.0-26200
sqlite3 3.53.3 on the Git Bash PATH
Symptom
Everything user-visible works well on Windows (join, send/inbox, monitor delivery, spawn with a custom spawn.terminal template, readiness handshake). But:
Every script that derives an instance id prints: agmsg: instance-id falling back to bare session_id (agent pid unresolved for type=claude-code); parallel --continue/--resume isolation is degraded
despawn.sh <team> <from> <name>always answers '<name>' holds no live actas lock — nothing to confirm a teardown against — even while the spawned member's session is alive, actively working, and its watcher is receiving messages.
$SKILL_DIR/run/ never contains any cc-instance.<pid> files and no actas.*.session files survive (they are GC'd as stale almost immediately).
Root cause
compat_get_ppid (scripts/lib/compat.sh) walks the parent chain with MSYS ps -l. MSYS ps only sees MSYS-world processes — the walk terminates at the MSYS pseudo-init (pid 1) as soon as it reaches the boundary to the native Windows process tree, so it can never reach the enclosing Claude Code process (a native node.exe/claude.exe).
Measured from a Claude Code Bash tool on this machine:
hop1: pid=37113 -> ppid=37111
hop2: pid=37111 -> ppid=1 <- MSYS boundary; native ancestors are invisible
agmsg_agent_pid claude-code -> "" (falls back to bare session_id)
Consequence chain
agmsg_agent_pid always fails → every token degrades to the bare session_id (the documented fallback in instance-id.sh).
session-start.sh resolves CC_PID="" → the cc-instance.$CC_PID liveness record is never written.
agmsg_instance_alive(<bare sid>) scans cc-instance.* — there are none — so every bare token is judged dead.
Notably, the liveness check itself is already Windows-aware (_agmsg_pid_alive uses tasklist for native pids, #134). Only the resolution of the agent pid is broken — if a composite <sid>.<native pid> token existed, everything downstream would work.
Suggested fix direction
In the msys branch of compat_get_ppid (or in agmsg_agent_pid), when the MSYS-side walk hits the boundary without finding the agent: translate the current pid to its native pid via the existing _compat_get_winpid helper, then continue the walk in the native process tree, e.g.
(or wmic process where ProcessId=<winpid> get ParentProcessId on older systems), matching the type's detect_proc names against native image names (claude.exe, node.exe running the claude CLI). _agmsg_pid_alive's tasklist path already validates such native pids.
Happy to test a patch on this environment — the failure reproduces deterministically here.
Workaround we use meanwhile
Teardown via the terminal manager instead of despawn (close the member's pane/tab, then reset.sh <project> <type> <agent>); operationally fine, just loses the graceful ctrl:despawn path.
Environment
install.sh --cmd agmsg --agent-type claude-code)uname -s=MINGW64_NT-10.0-26200Symptom
Everything user-visible works well on Windows (join, send/inbox, monitor delivery, spawn with a custom
spawn.terminaltemplate, readiness handshake). But:agmsg: instance-id falling back to bare session_id (agent pid unresolved for type=claude-code); parallel --continue/--resume isolation is degradeddespawn.sh <team> <from> <name>always answers'<name>' holds no live actas lock — nothing to confirm a teardown against— even while the spawned member's session is alive, actively working, and its watcher is receiving messages.$SKILL_DIR/run/never contains anycc-instance.<pid>files and noactas.*.sessionfiles survive (they are GC'd as stale almost immediately).Root cause
compat_get_ppid(scripts/lib/compat.sh) walks the parent chain with MSYSps -l. MSYSpsonly sees MSYS-world processes — the walk terminates at the MSYS pseudo-init (pid 1) as soon as it reaches the boundary to the native Windows process tree, so it can never reach the enclosing Claude Code process (a nativenode.exe/claude.exe).Measured from a Claude Code Bash tool on this machine:
Consequence chain
agmsg_agent_pidalways fails → every token degrades to the bare session_id (the documented fallback in instance-id.sh).session-start.shresolvesCC_PID=""→ thecc-instance.$CC_PIDliveness record is never written.agmsg_instance_alive(<bare sid>)scanscc-instance.*— there are none — so every bare token is judged dead.actas_lock_gc_stalereclaims them on the next pass →despawnfinds no live lock, and the Parallel claude --continue / --resume sessions share session_id, breaking actas lock distinctness #93 parallel-resume isolation is fully degraded on Windows.Notably, the liveness check itself is already Windows-aware (
_agmsg_pid_aliveusestasklistfor native pids, #134). Only the resolution of the agent pid is broken — if a composite<sid>.<native pid>token existed, everything downstream would work.Suggested fix direction
In the
msysbranch ofcompat_get_ppid(or inagmsg_agent_pid), when the MSYS-side walk hits the boundary without finding the agent: translate the current pid to its native pid via the existing_compat_get_winpidhelper, then continue the walk in the native process tree, e.g.powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=<winpid>').ParentProcessId"(or
wmic process where ProcessId=<winpid> get ParentProcessIdon older systems), matching the type'sdetect_procnames against native image names (claude.exe,node.exerunning the claude CLI)._agmsg_pid_alive'stasklistpath already validates such native pids.Happy to test a patch on this environment — the failure reproduces deterministically here.
Workaround we use meanwhile
Teardown via the terminal manager instead of
despawn(close the member's pane/tab, thenreset.sh <project> <type> <agent>); operationally fine, just loses the graceful ctrl:despawn path.