The startup takeover guard SIGTERMed any live bot.pid holder, so starting a
second Claude Code session stole the Telegram polling slot from the session
already using it — and when that second session exited, no poller remained
at all and the bot went permanently silent (anthropics/claude-code#81571).
Replace the kill-on-startup pattern with cooperative slot ownership:
- slot free (no pid file, holder dead, or pid recycled to an unrelated
process — identity-checked via /proc cmdline or ps args) → claim and poll
- live healthy holder → standby: outbound tools stay fully usable, and a
watcher claims the slot the moment the holder exits, so the channel hands
off to the last session standing instead of dying
- nothing is ever killed; genuinely orphaned pollers are already reaped by
the stdin orphan watchdog, and the pid file is removed by its owner on
shutdown
Adds a regression test (bun test external_plugins/telegram/test) that spawns
two real servers against an isolated state dir: the second must not kill the
first, the slot must hand off when the holder exits, and the pid file must
be cleaned up by the last server out. Fails on 0.0.7, passes on 0.0.8.
Fixesanthropics/claude-code#81571
No-Verification-Needed: fix is in the plugins repo; verified by its own regression test plus a two-session CLI e2e