Conversation
`serve` opens every agent before it binds, so a daemon that loses a start race — two can both pass the socket check while neither has bound — has the whole roster open by the time `bind` tells it so. That error returned straight out of `run`, and the teardown sat at the far end of the accept loop, so nothing killed what the boot had started. Nothing observable, today. The boot of a real roster spawns no processes at all: `uses_pty_program` makes `grok`, `claude` and `codex` headless, and a headless agent is registered rather than run. A PTY roster does spawn one process per bot, and those die with the daemon anyway when its end of the pty closes — measured, six bots raced, six left afterwards, not twelve. So this is the invariant, not a fix: whatever `serve` starts, `run` ends, and the next side effect added to boot does not have to rediscover that. Only the agents. The socket, pid and version name whoever is serving, and on this path that is the daemon that won — clearing them here would unlink its live socket. The race itself stays, documented in the README. Closing it needs the check and the claim to be one operation, and the stale-socket unlink that crash recovery depends on is what stops `bind` from being that.
Owner
Author
|
닫습니다. 측정으로 이 PR 이 main 에 없는 data loss 를 만든다는 걸 확인했어요. 경로: 제 PR 본문의 검증은 프로세스 수·transcript·channel 파일만 봤고 리뷰의 다른 지적도 맞아요:
이 레이스에 대해 저는 #20·#23·#24 로 일곱 번 시도했고, 매번 shipped 코드보다 나쁜 걸 넣었어요. 코드는 더 안 건드립니다. |
This was referenced Sep 21, 2026
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.
TL;DR
부팅이 로스터를 전부 열고 나서
bind에서 실패하면, 그 로스터를 아무도 정리하지 않았어요. teardown 이 accept 루프 맨 끝에 있어서?로 빠지는 경로가 거기 도달하지 못했어요.오늘 관측되는 효과는 없어요. 이건 수정이 아니라 불변식이에요.
어떻게 확인했는지
계측 바이너리로 경쟁 시 실제 순서를 확정했어요:
검사와
bind가 하나의 연산이 아니어서, 두 데몬이 동시에 시작하면 둘 다 "소켓 없음"을 보고 둘 다 로스터를 열어요.왜 오늘은 효과가 없는지 (그리고 왜 그래도 넣는지)
uses_pty_program이grok/claude/codex를 헤드리스로 분류해요. 측정: 헤드리스 봇 6개 부팅 →registered6줄, CLI 프로세스 0개. 진 데몬이 띄우는 게 없어요.main바이너리로도 실패 부팅 뒤 0개.seal_all_now()는 아무것도 안 써요. 기존 대화 파일을 심어두고 실패 부팅을 돌린 before/after 둘 다 transcript·channel 파일 무변경.그래서 이 PR 은 "
serve가 시작한 건run이 끝낸다"는 불변식을 세우는 것뿐이에요. 지금은 PTY hangup 이라는 OS 동작에 기대 무해한 상태이고, 부팅에 지속적 side effect 가 하나라도 추가되면 그때 다시 발견해야 하는 종류의 문제예요.에이전트만 정리해요. 소켓·pid·버전 파일은 "지금 서비스하는 쪽"을 가리키고, 이 경로에서 그건 이긴 데몬이에요. 여기서 지우면 살아있는 소켓을 unlink 해요 — 이전 시도들에서 리뷰가 반복해 지적한 함정이라 명시적으로 피했어요.
테스트를 안 붙인 이유
효과가 관측되지 않으니 테스트도 관측할 게 없어요. "실패 부팅 뒤 봇 프로세스 0개" 를 단정하는 테스트는
main에서도 통과해요 (SIGHUP 이 해 주니까) — 통과하는 척하는 테스트가 돼요.run()을 in-process 로 돌려 내부 상태를 보는 방법은 join 되지 않는 ticker 스레드 3개를 실제 홈에 남겨서 더 나빠요.남기는 것
레이스 자체는 README
개발섹션에 알려진 한계로 적었어요. 닫으려면 검사와 claim 이 한 연산이어야 하는데, 크래시 복구에 필요한 stale 소켓 unlink 가bind를 claim 이 아니게 만들어요.이 결론에 이르기까지 #20·#23 에서 여섯 번 시도했고, 그 과정에서 제가 넣은 결함이 넷이었어요 (
kill(-1), 방금 띄운 데몬 자살,kill(0), 무한 재귀). #20·#23 은 근거와 함께 닫았어요.검증
cargo test --locked -p crew— 214 passedcargo fmt --check— 변경한 코드 cleanremove_stale_socket은remove_file이라 못 지움 →bind반드시 실패): 로스터 5개 열고 실패, 남은 프로세스 0