Commit graph

4 commits

Author SHA1 Message Date
9b7f847014
design: Detach 보존 주체/KeyGone/Owned 확정 + attachSlot 분해
QA 4라운드 followup의 마지막 열린 항목(F-3)이 사용자 회신으로 전량
닫히면서 :List 요소 소유권 모델과 attachSlot 책임 분해를 base/에 반영.

- Detach 보존 주체를 userdata → slot._detached 필드로 전면 정정.
  근거는 gcconn 트릭 — detach된 quad-제작 Instance는 GC 폴백이 없어
  명시적 정리 경로가 필수인데 userdata는 :List에게 opaque라 처분 불가.
  재-Detach는 nop, prev 반환은 재마운트. raw 3형제(rawRemove/rawUnmount/
  rawDetach)로 "파괴하는가"와 "소유권을 놓는가"를 분리.
- KeyGone 센티널 신설 — 키가 사라진 자리도 조용히 처분하지 않고
  updateFn(KeyGone, 0, offset, prev, ud)로 한 번 더 묻는다. owner 사망
  시 최종 정리는 mountSlotTree가 거는 Effect가 담당.
- Owned 설치 플래그 신설 — Detach(사이클 단위)와 직교하는 축.
  state<Frame> 의미론 충돌(C-2)이 이걸로 닫힘.
- attachSlot을 materializeSlotTree(부기) + mountSlotTree(물리)로 분해.
  "부모에게 미는 길이는 최종값"(C6)과 "부기가 물리보다 먼저"(C7)가 한
  함수 안에선 동시 만족 불가라는 진단이 근거. 공개 표면은 두 줄짜리
  래퍼로 유지해 호출부 무변경. research/slot-attach-decomposition.md 확정.
- ROADMAP M6의 옛 Detach 서술 2건과 미결 마커 정정, question.md/todos.md
  해소 반영, session/2026-08-21-01 원문 + session-summary 색인 공백 4건 보강.

doc-check.py ERROR 0.

Co-authored-by: qwreey <me@qwreey.moe>
2026-08-21 11:55:11 +09:00
1e6cb0111d
design: QA 4라운드 3차 회신 반영 + attachSlot 분해 논의 자료 준비
확인받은 것 반영:
- Owned 설치 플래그 확정 — "누가 요소를 만들었는가"는 사이클마다 달라지는 게
  아니라 설치 시점 속성이라는 사용자 판단. Detach(사이클 판단)와 직교하는
  축이므로 반환값 계열에 unowned 센티널을 더 만들지 않는다. destroySlotTree/
  dispose도 이 플래그를 봐야 해서 클로저가 아닌 Slot 필드여야 함.
- props 순회를 일반화 for 한 번으로 정정 — flattened는 항상 평범한 Luau
  테이블(__pairs/__ipairs를 갈아끼운 ud가 들어올 경로가 없음)이라 옛 근거
  "다른 백엔드가 Lua 테이블이 아닌 자료구조로"는 inst엔 해당해도 flattened엔
  해당하지 않았다. 계약(배열 먼저)은 그대로, 구현만 1회 순회로. 스파이크 01은
  두 루프 버전이라 재작성 필요로 STATUS에 표시.

attachSlot 분해는 research/slot-attach-decomposition.md로 준비:
setLength를 flush 앞/뒤 어디에 둘지가 안 풀린 이유가 자리 선택이 아니라
"한 함수가 책임 일곱을 지고 있어서"라는 사용자 진단에 따라, 책임 목록과
순서 제약(전부 RC-1/RC-3/RC-4 등 실제로 밟은 버그가 출처)을 모으고 C6(길이
최종값은 flush 뒤에야 정해짐)와 C7(부기가 물리보다 먼저)이 단일 함수로는
동시 만족 불가능함을 보인 뒤 분해 후보 넷을 대조. 확정은 아무것도 안 함.

Co-authored-by: qwreey <me@qwreey.moe>
2026-08-21 11:10:42 +09:00
f36bdcbe5d
design: QA 4라운드 2차 회신 반영 — B절 확인분 + C절 결정 7건
B절(설명 보강 재질문) 전부 확인됨. 확인 과정에서 나온 보강:
- B-1: (A) 분기는 "교체"라 stack-down이 아니고 retractFrom만 스택을 역순으로
  푼다는 구분을 명시. "자기 아래는 이미 정리된 뒤" 보장도 retractFrom 한정이고,
  (A)에서 아래가 살아 있는 게 깜빡임 없는 갈아끼우기의 근거.
- B-3: 고아 체인이 실제로 어떻게 생기는지 가상 위반 예시(MaybeWrapHandler) 추가.
- B-4: "Brand는 데이터 타입에 부작용 없이 런타임 명시 타이핑을 하기 위한 것"을
  존재 이유로 명시하고, duck-typing 기각 근거를 정확성/안전성 둘로 분리.

C절 결정 반영:
- C-3: flatten의 정확한 형태 확정 — in-place 뮤테이션(클론 안 함),
  ProcessedModifier로 소진, 인라인 우선이 `~= nil` 하나로 성립. 단 주신 코드의
  반복 방향은 역순이어야 "나중 modifier가 우선"이 성립해서 그것만 정정(F-4-2).
- C-4: destroySlotTree의 명시적 releaseOwner 제거. 파괴된 걸 재사용하는 코드는
  그 자체로 버그이므로 "비결정적으로 실패"보다 "항상 실패"가 낫다.
- C-6: recompute의 sourceList[i] == nil을 skip에서 즉시 error로 승격. 재추적
  결과 도달 경로가 없으므로 관측되면 부기가 깨진 것.
- C-7: "부기가 물리 트리 조작보다 항상 먼저"를 일반 계약으로 승격. 빼기는 물리
  먼저/넣기는 부기 먼저가 같은 원칙(좁은 쪽이 먼저)의 두 얼굴이라는 것과,
  yield 금지 덕에 프레임 경계가 안 끼므로 진짜 근거는 "백엔드가 전제할 수
  있게 하나로 고정"이라는 것까지.

followup F절에 남은 것: KeyGone 홀드 + Owned 설치 플래그 설계 제안(F-3),
단일 일반화 for 전환 여부/flatten 반복 방향/setLength 위치(F-4).

Co-authored-by: qwreey <me@qwreey.moe>
2026-08-21 10:47:45 +09:00
9642cf8f18
qa: QA 4라운드 followup — 회신 처리 결과 + 재질문 정리
사용자 회신을 (a) 바로 반영 (b) 설명 부족으로 재질문 (c) 사용자 판단 필요
(d) 조사로 닫힘으로 갈라 followup 문서로 정리했다. A절(반영 완료)은 앞
커밋에서 이미 base/에 들어갔고, 이 커밋은 그 기록과 남은 항목이다.

가장 큰 두 미결:

- C-1 KeyGone 센티널 — 키 소멸 시 updateFn을 한 번 더 불러 처분을 묻는
  사용자 제안. SL-45의 "파괴도 반환도 안 되고 참조만 끊기는" 상태를 정확히
  메우지만, 반환값 의미/userdata 수명/소멸 루프 순회 대상/index 인자 넷이
  안 정해지면 구현이 못 나감.
- C-2 "밀려난 prev는 dispose" vs state<Frame> 의미론 충돌 — 회신의 SL-43과
  SL-51이 서로 반대를 가리켰는데, 따져보니 둘 다 맞고 갈리는 축이 "누가 그
  요소를 만들었는가"였다. :List의 updateFn이 만든 건 reconcile이 지워야 하고
  (만든 쪽이 자기 손으로 못 지움), Slot:Add(state) sugar로 온 건 사용자
  소유라 죽이면 안 됨. 지금 설계엔 후자를 표현할 방법이 없어 선택지 셋을
  올리고 per-installation 소유권 옵션을 추천.

부수로 사용자가 문서에 아예 없던 갭 둘을 찾아냄 — Attribute 생성자 자신의
이름 겹침 정책(앞 커밋에서 "뒤가 이김"으로 명시)과, flatten이 소진한
Modifier 자리 처리(C-3, ProcessedModifier 센티널 vs flatten 압축).

Co-authored-by: qwreey <me@qwreey.moe>
2026-08-20 00:57:19 +09:00