`:List` reconcile의 비파괴 반환 sentinel 이름을 사용자와 후보 검토(Bench/ Stash/Hold/Detach 등) 끝에 Detach로 확정 — 이미 있는 Extract(호출자 직접 호출, 명령형 소유권 이관)와 동사가 겹쳐도 "화면에서만 떼고 관리 주체는 reconcile"이라는 의미가 자연스럽게 구분됨. 공개 표면 위치도 같이 확정 — Slot이 함수라 Slot.Detach로 못 붙이므로, None sentinel의 선례(공개 표면은 패키지 최상위 export, 정의는 관련 로직 옆)를 그대로 따름. base/slot-plan.md 전량 반영(가칭 표기 제거, 이름/배치 두 결정 불릿 신설), question.md/todos.md/ROADMAP.md/archive/question-resolved.md/README.md 인덱스 갱신, session/2026-08-19-02-*.md로 논의 원문 남김. 키 소멸 시 홀드 중이던 요소 처분 문제는 이름과 무관한 별개 항목으로 여전히 미결. quad-doc-auditor 1라운드(무발견) 거쳐 doc-check.py ERROR 0 확인 후 커밋. Co-authored-by: qwreey <me@qwreey.moe>
4.6 KiB
2026-08-19 — PopOnly → Detach 리네임 + 공개 표면 위치 확정
요청: base/slot-plan.md에 가칭으로 남아있던 PopOnly(:List
reconcile에서 "파괴하지 말고 자리만 비우라"는 반환 센티널)의 이름을 사용자가
직접 못 정해 아이디어를 요청 — "지금은 다른 에이전트들이 있어서 쓰지는
말아달라"는 조건으로 브레인스토밍만 먼저 진행.
1. 메커니즘 재확인
base/slot-plan.md의 "nil 리턴은 파괴가 기본" 절을 다시 읽고 의미를
정리: :List reconcile에서 updateFn이 반환하는 sentinel로, 이 자리를
언마운트(Parent = nil)는 하되 파괴는 하지 말고 userdata를 들고 있다가
나중에 재사용하라는 지시 — 목적은 Instance.new/Destroy 비용을 아끼는
재사용(오브젝트 풀링에 가까움). nil 반환(파괴)과도, 새 값 반환(언마운트만,
즉시 교체)과도 구분되는 세 번째 경로.
2. 이름 후보 제시
풀링/보관 은유 계열(Bench/Stash/Shelve/Park), "언마운트+보류" 계열
(Hold/Detach/Suspend), 기존 조어 구조를 살리는 계열(PopKeep/
KeepOnly/SoftPop)을 제시하고 Bench(가장 직관적인 은유) 또는 Hold
(문서가 이미 "홀드"라는 용어를 쓰고 있어 도입 마찰이 적음) 둘 중 하나를
추천.
3. 사용자가 Detach 선택 — 근거 검증
사용자: "Detach 많이 괜찮아보이는데, Slot 에서 뽑아내다라는 Extract 를 지금 쓰고 있으니까, 이미 있는 Extract 를 쓰긴 뭐하니 Detach 를 넣는건 어때보임?"
Extract/ExtractAll은 호출자가 직접 부르는 명령형 추출(소유권을
통째로 호출자에게 넘김)인 반면, Detach(구 PopOnly)는 reconcile 내부에서
여전히 userdata로 추적하며 화면(부모 계층)에서만 떼는 선언적 sentinel —
"소유권 이관" vs "내부 보류 상태"로 성격이 갈려 Extract와 이름이 겹쳐도
혼동 소지가 적다고 판단, 채택 추천. Roblox 개발자가 Attachment/
WeldConstraint류의 물리적 "detach"를 먼저 연상할 여지는 있지만 "부모
계층에서 떼어낸다"는 실제 동작과 크게 어긋나지 않아 큰 문제 아니라고 정리.
Detach 채택 확정.
4. 공개 표면 위치 — 최상위 export
사용자: "근데 그러면, Detach 는 어디에서 던져줘야한다 생각함? 그냥 base 모듈 바로 최상위? Slot 이랑 연관인데 Slot 옆에 존재하게 되는게 뭔가 느낌이 애매한거 같긴 함. 그런데 Slot 은 또 함수라서, 뭔가 넣기 애매해. 넣으려면 메타테이블이 되어야하기도 하고. 그냥 최상위가 좋음?"
architecture.md의 패키지 트리를 확인해 None sentinel의 선례를 찾음 —
None도 Slot 요소/Attribute/offsetSource 등 여러 곳에서 쓰이는 sentinel
이지만, 공개 표면은 패키지 최상위(quad-base/src/init.luau 재노출)이고
실제 정의는 관련 로직 옆(Dispatch/None.luau)에 있음(공개 표면과 구현
위치가 분리돼 있는 기존 패턴). Detach도 같은 성격의 sentinel이므로 같은
자리(최상위)에 두는 게 일관적이라고 판단 — Slot이 함수라 Slot.Detach
형태로 붙이려면 callable-table+메타테이블이 새로 필요한데, sentinel 상수
하나 때문에 그 구조를 들이는 건 conventions.md의 "드문 오용이나 가상의
미래 요구까지 방어/최적화하려고 구조를 복잡하게 만들지 않는다" 원칙에
안 맞음. 정의 파일 위치(Slot.luau 또는 Dispatch/Slot.luau)는 None과
같은 패턴(정의는 관련 로직 옆, 재노출만 init.luau에서)을 따르되 정확한
배치는 M6 구현 시점에 확정하기로 함.
5. 반영
사용자: "이거 base/slot-plan.md에 정리해서 반영해줘. 세션 기록도 남겨주고, 핸드오버 준비해줘. 적절히 정해진것 같아서 커밋해줘도 될듯."
base/slot-plan.md("이름은 가칭" 불릿을 "이름 확정"/"공개 표면 위치 확정"
두 불릿으로 교체, 본문 전체의 PopOnly 표기를 Detach로 치환하되 사용자
발언 직접 인용과 히스토리 서술은 유지), question.md(용어 정리 1번 항목을
DI→D와 같은 형식의 [해소됨] 항목으로 교체, 3번의 남은 열린 항목 이름만
치환), todos.md(00번/2번 항목 갱신), archive/question-resolved.md(새
[해소됨, 2026-08-19] 절 추가), ROADMAP.md(M6 체크리스트의 PopOnly
표기 치환)에 반영. 인덱스 레이어(README.md)와 session-summary.md도
같이 갱신, 이 문서가 그 포인터.