Corrects a foundational error: "handler type unchanged -> retract skipped,
process diffs" was never actually true. StoreBind unconditionally calls
Dispatch.retractUnder before every re-dispatch (already stated in the
original dispatch model doc) -- Tag's old assert(v==nil) was taken at
face value and the general rule was wrongly back-derived from it.
Tag, Ref, Slot, and Attribute (the last three designed earlier this same
session) all inherited the flawed premise. Fixes across all four:
- Tag: rewritten around kTagMap/tagNameMap reference counting so
AddTag is entirely process's job, RemoveTag entirely retract's,
using a Contains hint to skip engine calls that would be immediately
redone. Also fixes the case where two independent Tag(...) values at
different positions share a name (union semantics, like className).
- Ref/Slot: drop the incorrect assert(v==nil), split into "retract
unbinds/destroys the old, process binds/mounts the new" with an
identity check on both sides to avoid spurious re-fire.
- Attribute: AttributeKeyHandler.retract gated on v==nil so ordinary
value updates don't flicker the attribute to nil; the group's
"unchanged name" delegation now also retracts before reprocessing,
since skipping it was silently stacking chain entries every cycle.
Reversal preserved in archive/retract-always-fires-reversed.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
state:Compute(fn)'s fn receives lazy State handles, not raw values, per
the confirmed self/with contract. Found and fixed the same class of bug
the user caught in the Animate example in three more spots (slot-plan.md
x2, tag-plan.md). Added a warning note near the contract since this is
an easy mistake to repeat.
.claude/base/ 전체를 배치별로 리스팅해 사용자 확인을 받는 중간검토
세션 — Ref 콜백/대기자 배열의 None 소진이 무한 성장 버그였던 것을
nil로 되돌리고, isRef/isPreRef를 isState/isSource와 같은 상위-하위
합성으로 재정정, Slot CRUD 식별 기준을 element 레퍼런스에서 인덱스
기준으로 전환(ExtractAll/Get/IndexOf 신설), 컴포넌트 리프 바인딩에서
Source 직접 사용이 정상 경로라는 정정, Dispatch 직접 호출 UB 명시,
Tag retract 전제 명시, Attribute 타입 파라미터화 확정, EffectHandle
내부 Observer cascade/Subscribe GC 예외 경고 등을 반영. CLAUDE.md에
세션 요약, stale해진 research/documentation-content-map.md 일부 항목도
동기화.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYfAz3BsaTrmMM8hnzn6mj
Add/Remove→Added/Removed, Merge→Merged와 같은 분사형 네이밍 컨벤션을
Override에도 적용하되, override가 불규칙동사임을 반영해 정확한 과거분사
Overridden을 채택(Overrided는 오기). question.md 용어 재검토 목록에서
제거하고 관련 base/research 문서 전반에 반영.
Tag를 해시 파트 boolean DI 키에서 Modifier식 immutable clone 체이닝 값
객체로 재설계(구 모델은 archive/tag-hash-key-model-reversed.md로 보존).
이 과정에서 재귀 재-dispatch(StoreBind/Tween/NoneHandler)의 retract가
다단 체인까지 정확히 전파되지 않던 설계 공백(pre-implementation-audit.md
1-2번)이 드러나, Dispatch가 (inst,k)별 핸들러 체인을 직접 소유하고
retractUnder로 꼬리부터 정리하는 방식으로 해결.