quad/.claude/session/2026-08-28-02-claim-promotion.md
qwreey 253d141096
qa: Claim 갈래 8건 확정 — research/existing-mount-plan → base/claim-plan.md 승격, 루트 .Parent= 밖에서 허용 복원
- 루트 키 센티널(맨 테이블+Claim<<T>> 기각), type <Class>Param 필드 파트 공유, Claim 타입 인자 없음
- 디스크립터 순서 정본 / claim된 부모 안 New 자식 허용(위치는 프로바이더 몫) / 이름 Claim·D.Mapper
- §5-7: Claim은 1회·전체 소유, H-146 루트 .Parent= 예외를 좁혀 복원(H-148 폐기 → 같은 날 복원)
- debug 검사 범위는 research/debug-tooling-plan.md로 이관, nativeFindChild 주입 op 등록
- 감사 8라운드 수렴(2→3→1→3→2→0→4→0) + /code-review high 10건 반영 — 새 메커니즘 넷은
  base/claim-plan.md §10 + question.md "M5 착수 전" 절로(gcconn/gchold 셋업 자리 /
  이중 claim 레지스트리 / PlayerGui own-all vs ResetOnSpawn / <Class>Param 배열 파트)

Co-authored-by: qwreey <me@qwreey.moe>
Claude-Session: https://claude.ai/code/session_01546hjsYNLSMZdHdPyTZaGb
2026-08-28 17:23:30 +09:00

10 KiB
Raw Blame History

2026-08-28 (02) — Claim 갈래 확정, research/에서 base/claim-plan.md로 승격

이 파일은 원문 기록이다(시행착오 포함). 지금 유효한 설계는 base/claim-plan.md. 앞 세션 session/2026-08-28-01-handtrace-round10-resolution.md가 만든 research 문서(옛 existing-mount-plan) §5 갈래 여덟을 사용자와 대화형으로 닫은 기록.

경위

10라운드 후속 2까지 커밋(f020f3f)한 뒤 사용자가 *"research/existing-mount-plan.md 관해서 다뤄보자. 우선 5. 미결을 보자"*로 이어갔다. 사용자가 항목 1~5를 먼저 적어 보냈고("내가 적어둔걸 볼래?"), 에이전트가 사실 셋을 확인한 뒤 의견과 함께 답이 없던 §5-7·§5-8을 되물었다. 사용자가 둘을 답해 전량 확정.

사용자 원문 (1차 메시지)

  1. 의 권고 b는 문제가 생겨. 루트에 대해서 {} 안의 타입체크와 타입 자동완성이 전혀 안 먹음. 내 생각에는 D.Frame 의 함수의 부분들을 type FrameParam = {} 형태로 빼서 공유되는 타입 부분으로 D.Mapper.Frame 도 구성되고, 리턴부분만 다르게 될것 같아. Claim 자체는 타입을 받는건 말이 안되어보임. New 와는 완전 다른 계열이라서: New 는 후행 입력에 대한 타입을 선언시키는 D 계열이지만, Claim 은 공유 부분이고 말한것 처럼 엔진 요소를 알 수 없어. a 가 가장 정확한 구현으로 보임.
  2. 나는 처음에 A 를 생각했어. 권고 그대로 가줘.
  3. 그런데 호출 순서가 달라진다는 문제가 있긴함. D.Mapper 의 프레임이 전부 구워지는 도중에 생기고 각각 claim 매핑 되기 전에 New 가 호출됨. 새로 붙임 자체는 한 배열에 섞이는게 문제는 없어보여. 그 경우에서도 순차 마운트 Add 는 작동할것이거든. 대신 Add 가 위치를 진짜 실어서 보내지 않으면 맨 뒤에 놓인다는게 문제일 뿐.
  4. 는 디버깅 도구 만들 때 고려해야할 점으로 옮겨져야해. 부분 부분 디버깅 가능성을 아직 다 논한게 없어서 지금 그림으로 보면 작은 그림을 먼저 그리는거라서, 미결상황으로, 위치 이동이 필요함
  5. 표면 이름은 Claim 이 가장 마음에 들어. D.Mapper 가 이미 있는걸 매핑해서 내가 가진다는 의미적으로 가장 맞고. 승격은 지금도 가능해보임. 간단한 레이어라서.

에이전트가 확인한 사실과 되물은 것

  • D.Frame = New<<Frame>> "Frame" :: (({ ...타입명시 }) -> Frame) — props 타입이 캐스트 안 인라인이고 D 전체가 생성기 산출물(base/bind-system-plan.md) → type FrameParam 공유는 생성기 한 줄. InstanceChildHandlerv.Parent = inst이고 H-154 문단이 이미 "같은 값, 엔진 no-op"을 전제 → §5-8 근거. nativeInsert는 Roblox가 offset을 무시(architecture.md) → §5-3의 위치 문제는 web 프로바이더 요구사항.
  • 제안 둘(사용자 거부 없음, 결정은 아님으로 표시): 센티널을 D.Mapper.Root에 두기 / Claim<T>(inst: T, desc: MapperDescriptor<T>): T 추론(타입 인자 없음은 사용자 결정).
  • §5-7 문항을 다시 세움 — "여러 quad 인스턴스"가 아니라 한 quad·여러 스크립트(같은 quad 모듈 require)가 흔한 경우라 이중 claim error가 그 사례를 막는 게 진짜 문제. 갈래 (α) Claim은 전체 소유만, 루트 .Parent =는 밖에서 (H-146 복원, 새 메커니즘 0) [권고] / (β) 다중 claim·부분 소유(web에서 offset이 남의 자식을 못 봄) / (γ) 별도 표면(H-146 인용문이 반대한 것).

사용자 원문 (2차 메시지) — §5-7·§5-8

5-8 확인완료. 5-7 에서는 정확히는 두번 Claim 불가하다는 의미. 필요하다면 Slot 을 안에 만들고 리턴하는 중간 모듈을 만들어야함. 밖에서 .Parent 설정하는건 괜찮아. 루트도 quad 소유이긴 한데, .Parent 를 밖에서 설정하는건 괜찮음. 정확히는 ScreenGUI 가 이미 존재해도 똑같음.

읽기: (α) 채택. Claim은 같은 inst에 1회, 소유는 전체. 루트의 Parent만든 방법과 무관하게(NewClaim한 기존 ScreenGui든) 부기 밖이라 밖에서 대입 허용 — H-146의 예외가 좁혀서(그리고 Claim한 루트까지 넓혀서) 복원됐다. PlayerGui 직하 Slot을 여러 스크립트가 공유하려면 Claim 한 번 + Slot 반환 중간 모듈.

반영

git mv research/existing-mount-plan.md base/claim-plan.md 후 전면 재작성(§7 결정 기록, §8 안 만들기로 한 것, §9 구현 체크리스트·문서화 대상). 포인터 갱신: bind-system-plan.md H-146 배너("폐기" → "좁혀서 복원") / slot-plan.md 두 곳 / architecture.md 주입 op 목록에 nativeFindChild(조합 폴백 예외) / ROADMAP.md M2 배너·M5 두 체크박스 / question.md 최우선 절 비움 + archive/question-resolved.md 절 / debug-tooling-plan.md "열린 질문"에 검사 범위 이관 / documentation-content-map.md §4 21번 / README.md 행 이동 / CLAUDE.md·todos.md·project-context.md / -round10-followup.md 후속 3 절. 코퍼스의 옛 경로는 새 경로로 일괄 치환(히스토리 문서 포함 — 파일 참조가 깨지지 않게).

옛 §5 원문 (승격 직전 커밋 f020f3fresearch/existing-mount-plan.md §5 — 갈래 a/b/c 선택지 전문)

  1. 루트 디스크립터의 이름 — 루트는 Claiminst를 직접 받으니 매칭 키가 필요 없다. 사용자: "최상위는 이름을 뭐로 둬야할지 아직 모르겠음. 비워두는걸 D.Mapper.Frame{} 으로 제공하는건 더 나빠보이는데. 아니면 테이블로써 MapperRoot = {} Mapper.Frame (MapperRoot) {} 모양이 되어도 될것같음." 갈래: (a) 센티널 MapperRoot(M.Frame(MapperRoot) {…}) / (b) 루트는 Claim(inst, { … })처럼 클래스 없는 맨 테이블(클래스는 inst가 이미 안다) / (c) 이름을 받되 무시. 권고 (b) — 루트 클래스를 두 번 말하지 않고, M.<Class>는 "찾아야 하는 자식"에만 쓰여 뜻이 하나가 된다. 단 타입(D 생성기가 만든 props 타입)을 잃으므로 Claim<<"Frame">>(inst, {…})처럼 타입 인자로 보완 — New<<X>>와 같은 관용구.
  2. 물리 순서 계약 — 디스크립터 배열 순서와 기존 트리의 실제 순서가 다를 때. Roblox는 물리 순서가 의미 없어 무관, web은 DOM 순서라 nativeInsert 위치가 어긋난다. 갈래: (a) 디스크립터 순서가 정본이고 일치는 사용자 책임(UB, debug 검사) / (b) claim 시 quad가 nativeMove로 실제 순서를 디스크립터에 맞춘다. 권고 (a) — "이미 있는 걸 그대로"의 취지, Roblox에선 비용 0.
  3. New로 만든 자식을 claim된 부모에 넣는 것 — 위 §4 첫 항목. 정적 자식이니 InstanceChildHandlerParent =를 하면 되고 새 결정은 없어 보이나, "매핑(이미 있음)"과 "생성(새로 붙임)"이 한 배열에 섞이는 것이 계약상 괜찮은지 확인 문항.
  4. debug 검사의 범위 — 이름 중복 / 부재 / 클래스 불일치 / 미매핑 부기 대상 자식 / 같은 quad의 이중 claim 중 어디까지. 권고: 전부(debug에선 싸다).
  5. 표면 이름Claim/Mount/Adopt, D.Mapper/D.Existing. Mount(root, parent)H-146에서 기각한 사유("부기 없는 대상에 quad 객체 주입")는 여기 반대로 적용된다 — claim은 부기를 세우는 행위. 권고 Claim.
  6. 마일스톤 — M5 이후(nativeFindChild가 프로바이더 표면). ROADMAP.md 백로그에 포인터만. [2026-08-28 /code-review, H-161]H-146 루트 예외를 폐기한 지금 M5에 승인된 루트 부착 경로가 없다 — (a) Claim을 M5 스코프로 당김 / (b) Claim 전까지 M5 한정 임시 예외 / (c) 루트 컨테이너용 얇은 표면. 사용자 확정 (a)("M5 스코프로 올라가도 될것으로 보임") — 헤더와 ROADMAP.md M5 체크박스에 반영. §5-7(다중 스크립트)은 여전히 미결.
  7. [2026-08-28 /code-review, H-161] 여러 스크립트/여러 quad가 같은 루트 컨테이너를 쓰는 경우 — 위 "이중 claim error / 다중 quad UB / 부기 대상 자식 전부 매핑"을 그대로 두면 Shop.client.luauInventory.client.luau가 각각 Claim(PlayerGui, …)하는 가장 흔한 사례가 막힌다. 이건 "전부 매핑" 계약이 루트 컨테이너(부기 대상이 아닌 PlayerGui·CoreGui류 — 자식 순서가 의미 없고 quad가 그 형제들을 관리하지 않는다)에는 안 맞는다는 신호다. 갈래: (a) Claim부기를 갖는 노드에만, 루트 컨테이너엔 "quad가 만든 자식 하나를 붙이는" 별개 표면(부기 없음, 여러 스크립트 공존, 이름은 §5-5와 같이) / (b) Claim에 "이 노드의 다른 자식은 관리하지 않는다"(부분 매핑) 모드 — 단 web처럼 물리 순서가 의미 있는 엔진에선 위험 / (c) 다중 claim을 허용하되 각 claim이 자기가 매핑한 자식만 소유(UB 대신 정의) — 부기 충돌 없음이 조건. 권고 없음 — (a)는 H-146에서 기각한 Mount(root, parent)의 재개방과 경계가 얇고, (b)(c)는 계약을 약화시킨다. 사용자 판단.
  8. 매핑된 정적 자식의 Parent 대입 — §2는 "부기만, .Parent =는 안 한다"인데 InstanceChildHandlerv.Parent = inst가 계약(dispatch-core-plan.md H-134). 같은 핸들러를 쓰면 이미 거기 있는 자식에 같은 값을 재대입(엔진 no-op)하는 것뿐이라 별도 핸들러가 필요 없어 보인다 — 확인 문항(권고: 같은 핸들러, 재대입 감수).

승격 뒤 /code-review high (2026-08-28)

감사 6라운드 수렴 뒤 돌린 리뷰가 10건을 냈다. 서술·라벨·stale 여섯은 반영, 새 메커니즘이 필요한 넷(gcconn/gchold 셋업 자리 / 이중 claim 레지스트리 / PlayerGui own-all vs ResetOnSpawn / 공유 Param 배열 파트)은 base/claim-plan.md §10과 question.md에 문항으로 — 사용자 결정 대기. 리뷰가 제안한 이름(nativeAdopt, FrameParam<C>)은 전부 가칭.