diff --git a/.claude/base/effect-plan.md b/.claude/base/effect-plan.md index 9a11507..5c9c4cd 100644 --- a/.claude/base/effect-plan.md +++ b/.claude/base/effect-plan.md @@ -617,6 +617,9 @@ quad의 반응형 그래프/cleanup 인체공학만 재사용하는 경우)로 Observer 쪽 의사코드는 가드가 첫 줄이라 이 문제가 없었다. ```lua +-- ⭐ [2026-08-29 `H-174`/`H-194`] 이 블록은 `Effect.Init(module)`이 만드는 **인스턴스별 임플 팩토리 +-- 안**이다 — `Subscribed`/`WeakSubscribed`는 `Observer.implFor(module)`에서 받은 그 인스턴스의 +-- 레지스트리이고, `canBound`는 `module.canBound`(인스턴스 필드, 발화 시점에 읽음)다. -- ⭐⭐ [2026-08-27 확정 (b), 9라운드 `H-144` 후속 — 감사 4라운드] **`EffectHandle`은 -- 네 진입점을 자기 것으로 가진다 — Observer의 함수 본문을 배정하지 않는다.** -- 공유하는 건 **레지스트리 두 개**(`Subscribed`/`WeakSubscribed`, 소유 모듈은 @@ -671,7 +674,7 @@ end -- **[2026-08-28 `H-149`]** Observer 쪽도 같은 이유로 위임을 풀고 인라인했다). function EffectHandle:WeakSubscribe() if isRunning(self) then error("cannot change subscription from inside fn or cleanup", 2) end -- `H-147` - if not canBound(self) then + if not module.canBound(self) then error(if self.Subscribed then "already subscribed" else "already bound to an Instance", 2) end self.Subscribed = true @@ -682,7 +685,7 @@ end function EffectHandle:Subscribe() if isRunning(self) then error("cannot change subscription from inside fn or cleanup", 2) end -- `H-147` - if not canBound(self) then + if not module.canBound(self) then error(if self.Subscribed then "already subscribed" else "already bound to an Instance", 2) end self.Subscribed = true diff --git a/.claude/base/lifecycle-pattern.md b/.claude/base/lifecycle-pattern.md index 607dfe2..33f88eb 100644 --- a/.claude/base/lifecycle-pattern.md +++ b/.claude/base/lifecycle-pattern.md @@ -491,12 +491,15 @@ end `base/effect-plan.md`의 "`EffectHandle:Subscribe()`" 절이 소스: ```lua +-- ⭐ [2026-08-29 `H-174`/`H-194`] 이 블록 전체는 `Observer.Init(module)`이 만드는 **인스턴스별 임플 +-- 팩토리 안**이라고 읽을 것 — 두 레지스트리는 그 클로저 로컬(인스턴스마다 한 벌)이고, +-- `canBound`는 탑레벨 함수가 아니라 `module.canBound`(발화 시점에 읽는 인스턴스 필드)다. local Subscribed = {} -- 강한 레지스트리(살려두는 게 목적) local WeakSubscribed = setmetatable({}, {__mode = "k"}) -- 약한 레지스트리 -- ── 프리미티브 ────────────────────────────────────────────── function Observer:WeakSubscribe() - if not canBound(self) then -- bindLifetime과 정확히 같은 게이트(같은 isBoundAlive 공유) + if not module.canBound(self) then -- bindLifetime과 정확히 같은 게이트(같은 isBoundAlive 공유) error(if self.Subscribed then "이미 구독된 값" -- 강/약 어느 쪽이든 이 분기 else "이미 Instance에 바인딩된 값", 2) -- [2026-08-27] `level 2` — 아래 둘과 같게 @@ -534,7 +537,7 @@ function Observer:Subscribe() -- 가리키고(`H-104` level 계약 위반), (2) 콜론 위임은 서브 테이블의 오버라이드를 -- 탄다(`H-144` (b)의 교훈). 사용자: *"weak 나 아닌거나 줄 차이가 그리 안 커서, -- 분리할 큰 이유가 없음."* - if not canBound(self) then + if not module.canBound(self) then error(if self.Subscribed then "이미 구독된 값" else "이미 Instance에 바인딩된 값", 2)