quad/.claude/audit/handtrace-round10-reference-impl/spikes/d16_remount_variants.luau
qwreey d2d67c7aeb
qa: 10라운드 광범위 탐사 완료 — 발견 H-150~H-157 (🔴 0 / 🟡 5 / 🟢 3), §4 배치 문항 7건 회신 대기
- 신선한 탐사자(fable) 단일 컨텍스트, 지시서 -round10-brief.md §2 레인 A·C 완료, B 부분, D ALL PASS
- audit/handtrace-round10-reference-impl/: round7 참조 구현을 현재 계약으로 갱신·재실행
  (부수: round7/ref9 _recompute 첫 인자 오류 발견·정정)
- base/·인덱스 레이어는 미변경 — 결정은 사용자 배치 회신 뒤 -round10-followup.md로

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

40 lines
2.4 KiB
Text

--!nocheck
-- Q2 대조: 재마운트 처방 none / (a) / (c)
-- 트리: O = { a, b, S }, S = { C, plain }, C = { plain } (S의 베이스 2)
-- 유저 체인: `:List`의 updateFn이 만든 요소가 S.Offset을 구독해 LayoutOrder를 정하는 모양.
-- 요소 인스턴스는 언마운트를 넘어 살아남으므로(파괴 아님) 그 Observer도 살아 있다.
local q = require("./core9"); local D = require("./dispatch9")
local function run(fix)
D.remountFix = fix
local inst = q.newInst("inst1")
local elem = q.newInst("elem") -- updateFn이 만든 요소(살아남는다)
local C = D.newSlot("C", {{name="cx"}})
local S = D.newSlot("S", { C, {name="sx"} })
local O = D.newSlot("O", { {name="a"}, {name="b"}, S })
D.mountTop(inst, O)
-- 유저 LayoutOrder: index(=1) + S.Offset
local lo = { value = nil }
local userObs = S.Offset:Observer(function(target) lo.value = 1 + target:Get() end)
q.bindLifetime(elem, userObs)
print(("[%s] 1차: S.Offset=%d C.Offset=%d userLO=%s | bk(S) valid=%d setUpTo=%d cache[1]=%s")
:format(fix, S.Offset:Get(), C.Offset:Get(), tostring(lo.value),
D.getBookkeeping(S).offsetCacheValidUpTo, D.getBookkeeping(S).offsetSetUpTo,
tostring(D.getBookkeeping(S).offsetCache[1])))
D.rawRemove(O, 3) -- 언마운트(포탈로 떼어냄)
local inst2 = q.newInst("inst2")
local O2 = D.newSlot("O2", {})
D.mountTop(inst2, O2)
D.rawAdd(O2, S) -- 베이스 0에 재마운트
local bkS = D.getBookkeeping(S)
print(("[%s] 재마운트: S.Offset=%d (기대 0) C.Offset=%d (기대 0) userLO=%s (기대 1) | bk(S) valid=%d setUpTo=%d cache[1]=%s")
:format(fix, S.Offset:Get(), C.Offset:Get(), tostring(lo.value),
bkS.offsetCacheValidUpTo, bkS.offsetSetUpTo, tostring(bkS.offsetCache[1])))
local ok = (S.Offset:Get() == 0) and (C.Offset:Get() == 0) and (lo.value == 1)
print(("[%s] → %s"):format(fix, if ok then "✅ 전부 정합" else "❌ 어긋남"))
-- 재마운트 뒤 런타임 베이스 변경도 도는가(O2 앞에 요소를 하나 끼워 S를 민다)
D.rawAdd(O2, {name="z"}, 1)
print(("[%s] 앞에 z 삽입 후: S.Offset=%d (기대 1) C.Offset=%d (기대 1) userLO=%s (기대 2)")
:format(fix, S.Offset:Get(), C.Offset:Get(), tostring(lo.value)))
print("")
end
run("none"); run("a"); run("c"); run("ctor")