fix(bridge): unmanaged-instance lifecycle bugs in start.sh + pid-file race in health cleanup#326
Merged
Merged
Conversation
… race in health cleanup
Diagnosed on daegyo (2026-07-08): a live, message-serving bot that
`start.sh --status` reported as dead ("no PID file"), running foreground
as a child of an ssh session. Five defects compounded:
1. start.sh silently swallowed unknown flags: `--start` (not a real flag)
fell through the `*)` parser arm and produced an unmanaged foreground
run whose lifecycle is tied to the invoking ssh session. Unknown `--*`
flags now fail fast with an error.
2. `--status` trusted the pid file alone: missing/stale pid file meant
"dead" even when a project bot process was alive. Now falls back to a
project-scoped process match (same rule the fleet watchdogs use) and
reports "degraded / unmanaged PID(s)" with a recovery hint.
3. The plain foreground path had no double-start guard (only the daemon
path did) — it now refuses to start when a managed or unmanaged
instance is already running.
4. `--stop` could not stop unmanaged instances; it now terminates
project-scoped bot processes not covered by pid files, so
status/stop/watchdog agree on what "running" means.
5. health.py `cleanup_runtime_files()` unlinked bot.pid unconditionally.
With two concurrent instances the newer one overwrites the shared pid
file, then the loser of the Telegram getUpdates conflict deletes it on
exit — destroying the survivor's pid file (the direct cause of the
daegyo state). The pid file is now only removed if it still records
the exiting process's own pid.
Evidence:
- bridge tests: tests/test_start_status.py + tests/test_health.py — 18/18
OK (1 macOS-only skip) under the CI pythonpath shim, including new
tests: unknown-flag rejection, status reporting an unmanaged live
process, stop terminating an unmanaged process, and cleanup preserving
a pid file owned by another process.
- bash -n clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
seoseo-ai
approved these changes
Jul 8, 2026
seoseo-ai
left a comment
Collaborator
There was a problem hiding this comment.
LGTM — bridge unmanaged-instance lifecycle fixes. Root-cause chain (unknown-flag swallow → foreground under ssh → pid-file race in health cleanup) is well-evidenced from the daegyo diagnosis; project-scoped pgrep fallback keeps status/stop consistent with the fleet watchdog rule. 18/18 bridge tests incl. 4 new regression tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
대교(daegyo) 진단에서 발견된 브릿지 수명주기 구조 결함 5건 수정.
Symptom (daegyo, 2026-07-08)
실제로 메시지를 처리 중인 봇이
--status에선 dead(no PID file)로 보고 — ssh 세션의 자식 foreground 프로세스로 방치, TM-1247 3중 방어 무력화.Fixes
--start같은 비실재 플래그가*)로 조용히 삼켜져 foreground 실행됨 → unknown--*는 즉시 에러Evidence
tests/test_start_status.py+tests/test_health.py: 18/18 OK (신규 테스트 4종 포함: unknown-flag 거부, unmanaged status 보고, unmanaged stop, 타 프로세스 pid 파일 보존)bash -nclean발견 경위: daegyo ccc-node 진단 (fix-forward 정책). Wiki LOG 후속 기록 예정.
🤖 Generated with Claude Code