quad/.claude/archive/observer-cleanup-contract-rejected.md
qwreey 911ab559ea
fix(base): 코퍼스 전체 stale 마커/모순 감사 및 무효화된 인라인 서사 archive 이전
이미 해소된 결정이 미해결로 표시되거나 문서 간 모순되던 항목 7개 파일
수정, 뒤집힌/무효화된 설계 서술이 정정 표시만 붙은 채 본문에 남아있던
곳을 기존 archive 컨벤션대로 이전(quad2-try 리서치, Observer cleanup
계약, keyed collection state method, debug channel ReplicatedStorage).
CLAUDE.md에 세션 로그 반영.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYfAz3BsaTrmMM8hnzn6mj
2026-08-09 16:36:59 +09:00

41 lines
2.1 KiB
Markdown

# [기각됨] `Observer` 자체에 React `useEffect`식 cleanup 반환 계약 추가
**기각 일시**: 2026-08-07 여섯 번째 세션. **현재 유효한 설계**: `base/
effect-plan.md` "Effect와 Observer의 관계" 절 — `Observer`의 기본 계약은
재실행 신호만 주고 cleanup은 클로저로 직접 처리, 자동 cleanup 배선이
필요하면 opt-in 상위 계층인 `Effect(fn, state?)`를 쓸 것. 이 파일은 더
이상 능동적으로 참고할 필요 없음(구현에 안 씀) — "왜 Observer 자체에
cleanup 계약을 안 넣었는가"가 `quadnomicon`(프레임워크 설계자용 심화
콘텐츠) 소재로 가치 있어서 사유를 보존해둔 것.
## 무엇을 검토했었나
React `useEffect`류 패턴 — `state:Observer(fn)``fn``nil | () -> ()`
반환하면, 다음 재실행 직전에 quad가 그 반환값을 자동으로 호출해주는 안.
## 기각 이유
클로저 업밸류로 이미 쉽게 되고 잘 작동함:
```lua
local lastConn
state:Observer(function()
if lastConn then lastConn:Disconnect() end
lastConn = ...
end)
```
**Observer 자체**가 이걸 대신 배선해줘야 할 이유가 약함 — 반환값을 잡아뒀다가
다음 실행 전에 불러주는 기능을 Observer 코어에 넣으면, 그 계약을 안 쓰는
대다수 사용처까지 복잡도가 늘어나는데 클로저로 이미 공짜로 되는 걸 다시
API 표면으로 만드는 셈.
## 왜 완전히 헛수고는 아니었나 — Effect 설계와 상충하지 않음
이 기각과 이후 확정된 `Effect(fn, state?)` 설계는 상충하지 않는다 — 그때
기각한 건 "Observer 자체에 이 복잡도를 넣지 말자"였지 "이 패턴 자체가
무용하다"가 아니었음. 자동 cleanup 배선이 필요한 사람만 opt-in으로 쓰는
별도 계층(`Effect`)으로 분리해 얹었을 뿐, `Observer`의 기본 계약(재실행
신호만, cleanup은 클로저로 직접)은 그대로 가볍게 유지됨 — `Effect`
내부적으로 `state:Observer(...)`를 조합해 이 패턴을 상위 계층에서 정확히
구현한다(`base/effect-plan.md` 참고).