Skip to content

fix(bridge): unmanaged-instance lifecycle bugs in start.sh + pid-file race in health cleanup#326

Merged
seoseo-ai merged 1 commit into
mainfrom
fix/bridge-startsh-unmanaged-instance
Jul 8, 2026
Merged

fix(bridge): unmanaged-instance lifecycle bugs in start.sh + pid-file race in health cleanup#326
seoseo-ai merged 1 commit into
mainfrom
fix/bridge-startsh-unmanaged-instance

Conversation

@jinon86

@jinon86 jinon86 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

대교(daegyo) 진단에서 발견된 브릿지 수명주기 구조 결함 5건 수정.

Symptom (daegyo, 2026-07-08)

실제로 메시지를 처리 중인 봇이 --status에선 dead(no PID file)로 보고 — ssh 세션의 자식 foreground 프로세스로 방치, TM-1247 3중 방어 무력화.

Fixes

  1. unknown flag 묵살--start 같은 비실재 플래그가 *)로 조용히 삼켜져 foreground 실행됨 → unknown --*는 즉시 에러
  2. --status pid-file 단독 신뢰 — 파일 없으면 무조건 dead → project-scoped pgrep fallback(워치독과 동일 규칙)으로 unmanaged 인스턴스를 degraded로 보고 + 복구 힌트
  3. foreground 경로 중복기동 가드 부재 (daemon 경로만 있었음) → managed/unmanaged 모두 감지해 거부
  4. --stop이 unmanaged 인스턴스를 못 잡음 → project-scoped 종료 추가 ("not running" 보고하며 토큰 점유 방치하던 것 해소)
  5. health.py pid-file race (직접 원인) — 동시 인스턴스 경합 시 나중에 죽는 쪽이 살아있는 쪽 bot.pid를 무조건 unlink → 자기 pid일 때만 삭제

Evidence

  • tests/test_start_status.py + tests/test_health.py: 18/18 OK (신규 테스트 4종 포함: unknown-flag 거부, unmanaged status 보고, unmanaged stop, 타 프로세스 pid 파일 보존)
  • bash -n clean

발견 경위: daegyo ccc-node 진단 (fix-forward 정책). Wiki LOG 후속 기록 예정.

🤖 Generated with Claude Code

… 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>
@jinon86 jinon86 requested a review from seoseo-ai as a code owner July 8, 2026 02:30

@seoseo-ai seoseo-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@seoseo-ai seoseo-ai merged commit 46a709f into main Jul 8, 2026
7 checks passed
@seoseo-ai seoseo-ai deleted the fix/bridge-startsh-unmanaged-instance branch July 8, 2026 02:32
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