From 28dbc818b0fb56d1b1365b0a9d8432be4662ccf6 Mon Sep 17 00:00:00 2001 From: qwreey-agent-selene Date: Sat, 29 Aug 2026 03:24:59 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=EB=A7=88=EB=AC=B4=EB=A6=AC=20=EA=B0=90?= =?UTF-8?q?=EC=82=AC=20=EB=B0=98=EC=98=81=20=E2=80=94=20Observer/Effect=20?= =?UTF-8?q?=EB=84=A4=20=EC=A7=84=EC=9E=85=EC=A0=90=20=EC=9D=98=EC=82=AC?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=B8=94=EB=A1=9D=EC=9D=84=20H-174=20?= =?UTF-8?q?=EB=AA=A8=EC=96=91=EC=9C=BC=EB=A1=9C(=EC=9E=84=ED=94=8C=20?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EC=95=88,=20module.canBound)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: qwreey --- .claude/base/effect-plan.md | 7 +++++-- .claude/base/lifecycle-pattern.md | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) 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)