# 2026-08-27 — 9라운드 후속: `/code-review`가 낸 새 메커니즘 넷(`H-143`~`H-146`) 결정·반영 **무엇을 했나**: 앞 세션(`session/2026-08-27-02-handtrace-round9-q4-q10.md`)이 `question.md` 최우선 절에 올려둔 넷을 사용자에게 갈래·권고와 함께 제시하고 한 턴에 회신을 받아 `base/`·`ROADMAP.md`에 반영했다. 결정과 회신 원문은 `qa-request/pre-implementation-handtrace-round9-followup.md`의 "`H-143`~`H-146`" 절이 소스. 여기는 흐름과 문서에 안 들어간 것. ## 흐름 1. 컴팩트 직후 넷의 원문(`-round9.md` 620행 이하)과 관련 `base/` 서술(`Rerun`· `_bindDestroying`·`Observer` 네 진입점·`EpochMap` API·`SlotHandler` retractor· `H-142` 항목·`slot-plan.md`의 "동적 자식은 반드시" 절)을 읽고, 항목마다 **트레이스 → 왜 새 메커니즘인가 → 갈래와 결과 → 권고 → 채택 시 고칠 자리**로 정리해 올렸다. 하위 결정 둘을 같이 올렸다 — `H-143`의 판정 predicate (`canExecute` 하나 vs 강한 해제만)와 `H-144`의 `WeakSubscribe` 래퍼 여부. 2. 사용자가 넷 다 (a)에 동의하되 `H-144`에 **재트레이싱을 요청**했다 — "재구독 뒤 emit이 꼬여도 괜찮은가"와 "재구독 시점에 epoch를 다 맞춰두는 게 낫지 않은가(Blocker로 막힌 뒤 늦게 오는 것 처리가 갈린다)", 그리고 Observer도 같은 문제가 있는지. 3. 재트레이싱 결과(followup에 기록): 첫 질문은 `fire`의 가드 순서 (`canExecute`가 `_epochs:Update` **앞**)로 안전, 둘째는 **leaf 경로 `_bindDestroying`이 이미 `Refresh()` 먼저**라 같은 모양으로 맞추면 된다 — 게이트 유보 중 재구독 케이스가 그 차이를 실제로 드러낸다. Observer는 epoch가 없고 설치 발화도 없어 무관. 래퍼 모양을 제시하고 반영으로 넘어갔다. ## 시행착오 / 다음 세션이 알아야 할 것 - **문서에 이미 있는 모양을 먼저 찾았다.** `H-144`의 래퍼는 새로 발명한 게 아니라 `_bindDestroying`(`H-65`)의 꼬리를 그대로 옮긴 것이다 — 앞 세션 교훈 ("어디에도 없다"고 쓰기 전에 grep)의 반대 방향 적용: 새 메커니즘을 제안하기 전에 같은 문제를 이미 푼 자리가 있는지 grep했다. 그 덕에 사용자의 "epoch를 맞춰두자"가 곧 기존 캐비엇(287행)의 재발견이라는 걸 바로 연결할 수 있었다. - `H-145` weak-key는 `InstanceChildHandler`가 5번째 인자를 안 넘기는 **근거 한 줄을 무효화**한다(옛 키 잔존) — 결정 하나가 다른 자리의 *근거*를 바꾸는 패턴이라 그 자리도 같이 고쳤다. 감사자가 잡을 종류의 stale을 반영 시점에 닫은 것. - `slot-plan.md` 233행 *"v2는 mount 함수 자체가"*는 v1식 `Mount(parent, tree)` 표면이 v2에 있는 것처럼 읽혔다(`H-146` 발견의 부수) — Slot의 마운트 경로를 뜻하는 문장이라 그렇게 고쳤다. ## 감사 루프가 뒤집은 것 둘 (같은 날, 반영 뒤) - **2라운드**: `H-143` 판정식 `not canExecute`가 **생성자 최초 설치를 죽였다** (바인드·구독 전이라 항상 거짓 → 첫 cleanup 즉시 소진, `_installed` 거짓, 첫 바인드에서 `fn` 재실행 = `H-58` 재현). `wasAlive and not canExecute`("실행 중에 죽었는가") + 죽은 핸들의 `_pending` 버림으로 정정. 사용자: *"오 그렇네. 실행중 죽으면 클린업만 하기, 해당 방식 맞아보여"*. - **4라운드**: `H-144` 래퍼가 Q4의 "Observer 함수 배정" 위에 얹히면서 `Observer:Subscribe`의 콜론 위임 `self:WeakSubscribe()`가 `EffectHandle` 오버라이드로 가 꼬리 2회 + 강한 킵 전 `Rerun`. 사용자가 *"그게 진짜 날 수 있어?"*(Effect는 Observer가 아닌데)라 물어 로컬 `luau`로 재현해 보였고, (a) dot 위임 / (b) 본문 공유 자체를 접기 중 **(b) 확정** — *"내 머리에서 나왔던 처음 구조는 그것이였어"*. 원칙 *"하나의 무언가가 두 일을 동작하지 않는가에 유의하자"*를 `conventions.md` "설계 원칙"으로 승격. 사용자가 이어서 *"그게 정확히 invalid after 문제에서 났던 이야기였어"* — 같은 원칙의 첫 사례가 8라운드의 `invalidAfter` 두 필드 분리였다는 출처를 원칙 항목에 붙였다(필드 하나가 두 뜻 / 함수 본문 하나가 두 타입). - 교훈: **두 건 다 "반영분 자체가 만든 결함"**이고, 둘 다 "권고 (a)의 의도는 맞는데 내가 고른 판정식·배선이 틀린" 종류다. 감사 1라운드(문구 잔존)로는 못 잡고 2·4라운드(의미론·수정분 재검토) 각도에서만 나왔다 — 각도를 바꾸는 라운드가 실제로 값을 한다는 재확인. ## 마무리 (2026-08-28) — `/code-review high`와 10라운드로의 이관 감사 8라운드 수렴 뒤 `/code-review high` 10건 — 일곱 반영(`-round9-followup.md` 마지막 절), 셋은 판단 필요(`H-147` 죽은 핸들에서 `Rerun` / `H-148` `Parent` 전용 문구가 새 메커니즘 / `H-149` Observer 위임과 `level 2`). 사용자: *"너무 길어지고 있어서, round10 으로 옮기고 싶은데 … 인간을 기다리는거 엄청 비효율이라서 … batch 로 처리될 필요가 있는듯. 지금 결정해야할 분 10 으로 올리자. 커밋하고 정리한 다음 깔끔한 컨텍스트의 fable 탐사자 하나 띄워서 광범위한 핸드트레이싱, 테스팅, 문제 검사를 하도록 해줘."* → `-round10-brief.md`/`-round10.md` 신설, 커밋 후 탐사자 기동. 교훈: **대화형 처리는 발견 하나당 한 왕복이라 사람 쪽 대기 비용이 크다** — 라운드 단위 배치가 이 프로젝트의 기본 리듬이고, 이번처럼 반영분 리뷰에서 문항이 또 나오면 그 자리에서 다음 라운드로 넘긴다.