From 89e078b387c3f4ddb59233539ef269246cca1768 Mon Sep 17 00:00:00 2001 From: qwreey-agent-selene Date: Mon, 31 Aug 2026 13:40:27 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20round11=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EA=B0=9C=EB=AA=85=20=E2=80=94=20m2-implementation-round11*=20+?= =?UTF-8?q?=20=EB=AA=85=EB=AA=85=20=EA=B7=9C=EC=95=BD=20=ED=99=95=EC=A0=95?= =?UTF-8?q?,=20M2=20=EC=A2=85=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - pre-implementation-handtrace-round11(.md/-brief.md) → m2-implementation-round11* (사용자: 구현 중 문서라 pre-implementation이 안 맞음), 인용처 22곳 일괄 치환 - 명명 규약(사용자 확정, README qa-request/ 행): mN-implementation-roundNN — 라운드 번호는 마일스톤을 가로질러 단순 증가("m3 진행 중 m2 하자로 돌아가는 경우도 있을 것"), 마일스톤 접두가 소속을 담음. round1~10 옛 이름은 실제로 구현 전 라운드라 유지 - CLAUDE.md/project-context.md 머리말: M0~M2 완료, 다음은 M3(디스패치 엔진); todos 00 종결 표기 — 다음 액션은 M3 착수 규약 문항(사용자와 정할 것) Co-authored-by: qwreey Claude-Session: https://claude.ai/code/session_01LF78pXeFGD1ZSVD3ifteYG --- .claude/README.md | 2 +- .claude/base/typing-limits.md | 2 +- .claude/conventions.md | 2 +- .claude/luau-test/README.md | 2 +- .claude/luau-test/STATUS.md | 4 ++-- .../26-type-apply-object-factory-overload.luau | 2 +- .claude/project-context.md | 13 ++++++------- ...rief.md => m2-implementation-round11-brief.md} | 6 +++--- ...ce-round11.md => m2-implementation-round11.md} | 0 .claude/session-summary.md | 9 ++++++--- .../session/2026-08-28-03-m2-unit1-common-base.md | 2 +- .../session/2026-08-31-01-unit2-code-review.md | 15 +++++++++++++-- .claude/todos.md | 15 ++++++++++----- CLAUDE.md | 14 +++++++------- HUMAN_TODO.md | 2 +- ROADMAP.md | 2 +- quad-base/src/Brand.luau | 2 +- 17 files changed, 56 insertions(+), 38 deletions(-) rename .claude/qa-request/{pre-implementation-handtrace-round11-brief.md => m2-implementation-round11-brief.md} (97%) rename .claude/qa-request/{pre-implementation-handtrace-round11.md => m2-implementation-round11.md} (100%) diff --git a/.claude/README.md b/.claude/README.md index 27de91e..cce9246 100644 --- a/.claude/README.md +++ b/.claude/README.md @@ -24,7 +24,7 @@ | `base/` | 결정 완료 + 프로젝트 전체에 걸치는 컨텍스트 — plan/done 개념 없음, 계속 참조되는 배경지식. **항상 읽어야 하는** 배경지식만 여기 둠(다른 문서를 이해하는 데 전제되는 것) | | `reference/` | **[2026-08-07 신설]** 결정 자체가 아니라 다른 문서가 근거로 인용하는 온디맨드 참고 자료(v1 스냅샷, 프레임워크 비교 리서치) — "완료" 개념 없는 건 `base/`와 같지만, 항상 읽을 필요는 없고 해당 문서가 인용될 때만 열어보면 됨. `quadnomicon` 소재 후보가 많음. **[2026-08-21 확장] 확정된 결정의 "왜 그렇게 정했나" 근거 기록도 여기 둔다** — `research/`(아직 상의 필요)도 `archive/`(뒤집혔거나 기각됨)도 아니고, `base/`가 근거로 인용하는 온디맨드 자료라는 이 폴더의 기준에 정확히 맞기 때문(`slot-attach-decomposition.md`/`epoch-brand-composition.md`가 그렇게 들어옴) | | `research/` | 아직 착수 전, 사용자와 스코프/설계를 더 상의해야 함 | -| `qa-request/` | 원래 용도는 "구현 완료(코드/에이전트 검증까지 끝남) + 사용자 본인의 실기기(Roblox Studio) QA만 남음". **[2026-08-18 확장]** 구현 전에도 **사용자 심사 라운드의 산출물**을 여기 둠 — `pre-implementation-qa-round1.md`(1라운드: `base/` 확정 문서 전체를 문항으로 재확인받아 **"아니오"가 나온 항목만** 모은 결함 목록 + 신규 요구사항(`N-n`) + 부수 오탈자. **같은 날 전부 `base/`에 반영 완료**라 지금은 "무엇이 왜 틀렸었나"의 근거 기록이고, 지금 유효한 설계는 항상 `base/`가 소스. 아직 안 닫힌 것은 `question.md` 최우선 절과 `.claude/todos.md` 00번이 소스), `pre-implementation-qa-round2.md`(2라운드: 확정 의사코드를 실제로 손으로 실행해보는 트레이싱 — **완료**, 발견된 크래시 `RC-1`(`recompute` 트리거 모델)도 같은 날 후속 세션에서 Blocker 게이팅 설계로 해결·반영까지 끝남, `archive/question-resolved.md`에 논의 요지 정리), `pre-implementation-qa-round3.md`(3라운드: `RC-1` 해법(Blocker 게이팅)이 실제로 `attachSlot`/`recompute`에 반영된 걸 손으로 트레이싱 — **완료**, `RC-3`/`RC-4`(`activateList`가 자기 Slot의 Blocker보다 먼저 실행되는 순서 문제)와 `bk.N` 수명주기 미정을 발견했다가 같은 세션에 사용자가 최초 분석 오류를 직접 정정하며 전부 해결·`base/` 반영까지 끝남, `archive/question-resolved.md`에 논의 요지 정리. `ROADMAP.md` M3가 M2의 `Blocker.luau`에 의존하게 된 마일스톤 순서 불일치는 각주로 반영 — **[2026-08-24]** 그때 열어뒀던 마일스톤 재편은 M2/M3 순서 교체로 닫혔다). `pre-implementation-qa-round4.md`(4라운드: 사용자 요청으로 **`base/` 확정 전체를 "예가 나와야 정상인 문항"으로 다시 뽑은 전수 문항지** — **[2026-08-21] 완료·종결**. 1~3라운드와 달리 이 파일은 **문항지 원본 그대로 남긴다** — 처리 결과 전량이 `-followup.md`에 쌓였으므로 "아니오만 남기는 재편"은 안 하기로 함(같은 정보가 두 곳에 갈라지는 걸 피함). 문항 수/문서별 분포는 그 파일 자신이 소스). `pre-implementation-qa-round4-response.md`(사용자 회신 원문 — 이 라운드는 회신을 **별도 파일**로 받았다, 1~3라운드와 다른 점), `pre-implementation-qa-round4-followup.md`(**[2026-08-20 시작, 2026-08-21 종결]** 그 회신 처리 결과 — A~H 8개 절이 4차에 걸쳐 시간순으로 쌓였고 **마지막 H절이 최신이자 소스**. B·C절의 재질문/판단 대기 항목은 F·G절을 거쳐 **H절에서 전량 닫혔다**(`Detach` 보존 주체, `KeyGone`, `Owned`, `attachSlot` 분해). **열린 질문 없음**. **[2026-08-21 정정]** 여기 적혀 있던 "5라운드 문항지는 만들지 않는다"는 뒤집혔다 — 같은 날 사용자 요청으로 5라운드를 만들었다), `pre-implementation-qa-round5.md`(**[2026-08-21 신설·처리 완료]** 5라운드: 4라운드에서 "예"로 넘어간 자리는 건너뛰고 **(1) 4라운드에 문항이 아예 없던 영역**(`project-setup-plan.md`/`quad-types-plan.md`, 그리고 **문서가 아니라 실제 커밋된 M1 코드**), **(2) 4라운드 회신 이후 새로 확정된 것**(`Detach`/`_detached`/`KeyGone`/`Owned`/`attachSlot` 분해 등), **(3) 큰 문서의 심화**(예: `debounce-throttle-plan.md`)만 묻는다. 문항 수는 그 문서 자신이 소스), `pre-implementation-qa-round5-response.md`(사용자 회신 원문 — 4라운드와 같이 별도 파일), `pre-implementation-qa-round5-followup.md`(**[2026-08-21]** 그 회신 처리 결과 — 즉시 반영분 / 재질문 / 사용자 판단 필요 / 새로 만든 문서 둘(`gate-plan.md`·`state-epoch-plan.md` — 같은 날 확정되며 `base/`로 승격)까지. **처리 결과의 소스는 이 파일**). `pre-implementation-handtrace-round6.md`(**[2026-08-22 신설]** 6라운드: 문항지가 아니라 **손 트레이싱**이다(2·3라운드와 같은 성격) — 사용자가 지목한 최근 확정 5개 영역(`Effect(fn, ...deps)`/`Gate`·`Blocker`/State 전파(`rawInvalid`·emit 지연)/Slot의 `native*`·offset·length·mount/`Brand`·`Epoch`·`EpochMap`)을 실제 값으로 돌려본 결과. 발견 번호는 `H-n`. **[2026-08-23] 2차 패스** — 1차가 안 본 영역(디스패치 코어 전체/라이프타임 유틸/Ref·Tag·Attribute·UI 숏핸드 핸들러/Slot의 `raw*` 계층). **[2026-08-23] 3차 패스** — 1·2차가 한 번도 안 연 문서 전체(Store/State/Source 코어, Modifier·컴포넌트 합성, 이벤트·라이프사이클·에러 격리, Tween·시간 게이트, 타입 계약과 실제 커밋된 M1 코드) + 통합 시나리오. **[2026-08-24] 4차 패스** — 문서 단위가 아니라 **축을 바꿔서**(핸들러 레지스트리 전수/두 대형 핸들러 문서 심층/`luau-test` 스파이크 실제 재실행/프리미티브 조합 매트릭스/`reference`·`archive`·로드맵 M2~M9/엔진·언어 사실 주장 전수 검증). 3·4차는 추론으로 끝내지 않고 로컬 `luau`/`luau-analyze`와 공식 문서로 **직접 재현·교차검증**했고, 그 부수로 기존 `H-2`의 크래시 주장이 틀렸음도 드러났다(3차 패스 머리의 정정 절). 발견 번호는 패스를 가로질러 이어서 매긴다. 발견 수/심각도 분포는 그 문서 자신이 소스. 각 패스의 "확인만 하고 문제 없었던 것" 절은 다시 트레이싱할 필요 없는 자리를 적어둔 것. **⭐ [2026-08-24] 전량 처리·반영 완료** — 그 문서는 이제 **발견 당시의 기록**이라 각 항목의 "갈래"는 선택 전 목록이니 그대로 믿지 말 것), `pre-implementation-handtrace-round6-followup.md`(**[2026-08-24 신설] 6라운드의 결정과 근거가 여기 소스다** — `H-1`~`H-54`를 사용자와 대화형으로 하나씩 결정한 기록이고, 반영 후 `/code-review high`가 잡은 7건(그중 셋이 이번 반영이 만든 회귀)도 D절에 있다. 진행 경위와 사용자 발언 원문은 `session/2026-08-24-01-handtrace-round6-resolution.md`). `pre-implementation-handtrace-round7.md`(**[2026-08-25 신설, 회신 대기]** 7라운드: 6라운드와 같은 손 트레이싱이되 범위가 **M2(반응형 코어)와 M2→M3 경계**다. 패스 6개가 각기 다른 각도를 쓴다 — 1차는 프리미티브 사이의 *호출 순서*를 시간축으로 겹쳐 보기, 2차는 문서가 "확인했다"고 적은 런타임/타입 주장을 실제로 `luau`/`luau-analyze`에 걸어보기, 3차는 **커밋된 M1 코드·툴체인을 이 저장소에서 그대로 돌려보기** + 1·2차가 뺐던 "M2를 *소비하는* 문서", 4차는 **M2 코어를 문서 그대로 옮긴 참조 구현을 돌려보기** + 아무 문서도 안 정한 **예외 경로**, 5차는 **확정된 M2 표면을 실제 Luau 타입으로 선언해 `luau-analyze`에 걸어보기**(확정 시그니처가 확정 관용구를 통과시키는가), 6차는 **그 참조 구현을 M2→M3 경계(Length/Offset 부기·Dispatch 체인)까지 이어 붙여 돌려보기** + **quad 자신이 던지기로 확정한 error 42곳의 계약 감사**. 발견 번호는 6라운드에서 이어서 `H-55`부터, 패스를 가로질러 연속으로 매긴다. 발견 수/심각도 분포는 그 문서 자신이 소스. 각 패스의 "문제가 없던 것" 부록은 다시 파지 않아도 되는 자리를 적어둔 것. **아직 아무것도 `base/`에 반영하지 않았다** — 판정은 사용자가 하고, 결정이 나면 6라운드처럼 `-followup.md`를 새로 만든다), `pre-implementation-handtrace-round7-verification.md`(**[2026-08-25 신설]** 그 52건이 **정말 유효한지만** 판정한 검증 패스 — 새 발견은 없다. ⚠️ **재실행이 아니라 대조로 판정했다**: 4·5·6차 패스가 쓴 전사물(`audit/handtrace-round7-reference-impl/spikes/`), `pre-implementation-handtrace-round7-followup.md`(**[2026-08-25 신설] 그 52건에 대한 사용자 결정과 `base/` 반영 결과 — 결정 단위 12묶음(🅐~🅜) 순서로 대화형 처리. **이 파일이 결정의 소스**이고 발견 원문은 앞의 두 파일. 무효/기각 7건(`H-73`~`H-77` 계열: `<>`가 값 호출부에서 동작함이 실측으로 드러나 Store 재설계로 이어짐, `RunInit` 누수는 성립 안 하는 사용법), 나머지는 전량 반영. **부수로 `question.md` 최우선 두 항목이 같이 닫혀 M2 착수 게이트가 0이 됐다**)과 `base/` 확정 의사코드를 줄 단위로 맞춰봤고(전사 오류로 생긴 발견은 **없었다**, 미신고 차이 3개는 전부 발견을 만들지 않는 방향), Luau 언어 동작·저장소 상태를 주장하는 것만 직접 재실행했다. 판정 분포와 항목별 근거는 그 문서 자신이 소스 — 여기서 세지 않는다. **결정 전에 반드시 읽을 것**: 부정 주장·개수 주장 몇 건이 정정됐고, 특히 **이미 사용자가 판단한 항목을 다시 묻게 되는 자리**가 하나 있다. 마지막 절의 **batch용 요약**이 유효 항목을 "한 결정으로 닫히는 묶음"으로 재편성해뒀으니 회신은 번호순이 아니라 그 묶음 단위로 하는 게 싸다), `pre-implementation-handtrace-round8.md`(**[2026-08-26 신설, 회신 대기]** 8라운드: 7라운드 반영으로 새로 쓰인 `base/` 서술을 **서로 겹쳐서** 재트레이싱한 것 — 개별 함수가 아니라 "반영된 결정들이 조합될 때 성립하는가"가 주제. 3패스에 걸쳐 `base/` 전 문서를 완독했고, 발견 번호는 `H-107`부터 이어 매김(발견 수·심각도 분포는 그 문서 자신이 소스), 실측 스파이크는 발견 항목에 인라인 전사. 사용자 결정 문항 Q1~Q10이 §4에 배치 회신용으로 정리돼 있다. 커밋 전 `/code-review`가 이 문서 자체의 결함 7건을 잡아 반영됐다(각 항목의 `[code-review 정정/추가]` 표시). **⭐ [2026-08-26] 전량 처리·반영 완료** — 그 문서는 이제 **발견 당시의 기록**이라 각 항목의 "갈래"는 선택 전 목록이니 그대로 믿지 말 것), `pre-implementation-handtrace-round8-followup.md`(**[2026-08-26 신설] 8라운드의 결정과 근거가 여기 소스다** — Q1~Q10을 사용자와 대화형으로 처리한 기록. **역전은 없고** 전부 "7라운드 확정이 `base/`에 내려앉을 때 생긴 누락·충돌"을 닫은 것. ⭐ 사용자가 **문항의 전제 자체를 정정한 것이 둘** 있다(Ref 콜백 ↔ Observer 콜백은 애초에 통합 대상이 아니다 / `H-118`은 소유권 문제가 아니라 문장이 틀린 것) — 결정만 읽지 말고 그 두 절을 볼 것), `pre-implementation-handtrace-round9-brief.md`(**[2026-08-26 신설]** 9라운드를 돌릴 감사자에게 주는 **지시서** — 발견 보고가 아니라 그 앞단이다. 이런 지시서를 저장하는 건 이번이 처음으로, 7·8라운드 것은 대화에만 있었고 저장되지 않았다(8라운드 본문이 인용하는 "감사 지시서 §2"가 코퍼스 어디에도 없는 이유). 스코프를 **커밋 `9dd8213` 하나의 델타**로 정의한 게 핵심 — 8라운드 결정 반영과 그 뒤 `/code-review high` 7패스 수정이 전부 그 커밋에 들어 있고 아무도 트레이싱한 적이 없다. 레인 셋(A: 그 델타의 상호 간섭 / C: `audit/handtrace-round7-reference-impl/`을 지금 계약으로 갱신해 실행 / B: 8라운드 §6이 남긴 M5+ 값 단위 트레이싱)과 우선순위 근거, `-round8-followup.md`가 적어둔 **반복 실패 모드 7개**를 사냥 목록으로 옮겨 실었다. 각도 문자(A~H)는 8라운드와 같은 걸 유지해 상호참조가 되게 했다), `pre-implementation-handtrace-round9.md`(**[2026-08-26]** 9라운드 발견 보고 — 레인 A(`9dd8213` 델타 상호 간섭)·C(참조 구현을 현재 계약으로 재전사해 `luau` 실행)·G(Luau 사실 재확인)·D(ROADMAP M2 시뮬레이션)·B(M5+ 값 단위, 첫 시도) — 발견 `H-124`~`H-141`, 🔴 둘(`recompute`의 `lengthList[i]` nil 읽기 / 재마운트 시 `_baseObserver` 미바인드 캐시 stale) 다 실측 재현. §4 배치 문항 Q1~Q10 + §5 이상 없음(⭐ `keyof<{}>` 빈 Store 실측으로 클린) + §6), `pre-implementation-handtrace-round9-followup.md`(**[2026-08-27] 9라운드 결정의 소스 — 전량 처리 완료** — Q1(`recompute` 되감기 판정을 읽기 앞으로) / Q2(`Offset`·`_baseObserver`를 Slot 생성자로, `materializeSlotTree` 순서, `_destroyed` 플래그) / Q3(`element → index`는 `bk.indexOfElement` 하나 — 사용자가 정한 적 없는 `token` 폐기, `H-137` 소멸, `H-141` 신설) / Q4(`EffectHandle` 네 진입점 의사코드) / Q5(M2에 `Ref` 최소형) / Q6(`WeakUnsubscribe` 관대) / Q7(폐기 블록 `archive/`) / Q8(`InstanceChildHandler` 부기) / **Q9(문항 전제가 틀림 — Tween 절 스케치 한 줄 복사 오류)** / Q10(`reconcile` 배치 Blocker) + `H-138`(숏핸드 우선순위) / `H-139`(`New`/`drive` 파이프라인 의사코드) / **`H-142`(props에 `Parent` 금지 — 순서 문제 소멸)** / **`H-143`~`H-146`**(`/code-review`가 낸 새 메커니즘 넷 — 전부 권고 (a), `H-144`는 사용자 요청으로 재구독 뒤 epoch·Blocker 상호작용을 재트레이싱한 기록 포함). 진행 표가 상태의 소스, 사용자 회신 원문 셋 인용; **[2026-08-28]** `H-143`~`H-146` 반영분의 감사 8라운드 표와 `/code-review high` 기록도 여기), `pre-implementation-handtrace-round10-brief.md`(**[2026-08-28 신설]** 10라운드 지시서 — 델타가 아니라 **광범위** 스코프(M2~M8, 레인 A 반응형 코어 전체 / C 참조 구현 갱신·실행 / B 디스패치·Slot / D 타입·M1 코드), 신선한 탐사자가 한 번에 문항지를 만들어 사용자가 배치로 결정하게 하는 것이 목적), `pre-implementation-handtrace-round10.md`(**[2026-08-28 신설, 회신 대기]** 10라운드 발견 보고 + §4 배치 문항지 — 씨앗은 `/code-review`가 낸 `H-147`~`H-149`(죽은 핸들에서 `Rerun` / `Parent` 거부 전용 문구는 새 메커니즘 / Observer `Subscribe` 위임과 `level 2`), 탐사자 발견은 `H-150`부터. 레인 C 실행 기록은 `audit/handtrace-round10-reference-impl/`. **[2026-08-28 탐사 완료]** 🔴 0 / 🟡 5 / 🟢 3, §4 문항 7건(기존 3 + `H-150` `Effect._blocker` 죽은 부품 / `H-151` 게이트 우회 계약 / `H-153` Store 예약 이름 런타임 가드 / `H-154` `InstanceChildHandler` dedup) — 전부 권고 (a). 레인 A·C 완료, B 부분, D `./scripts/test.sh` ALL PASS), `pre-implementation-handtrace-round10-followup.md`(**[2026-08-28] 10라운드 결정의 소스 — 전량 처리 완료.** 사용자가 *"하나하나 같이 보자"*라 대화형으로 처리. **문항의 전제를 뒤집은 것 둘**: `H-147`은 "죽은 핸들에서 `Rerun`"이 아니라 **`fn`/cleanup이 자기 구독을 바꿀 수 있다는 허용 자체가 모순**(→ (A) 금지, `H-143` 소멸, `rawRerun(force)`/`Rerun` 분리), `H-148`은 "문구"가 아니라 **루트 마운트 표면의 부재**(→ `Claim` + `D.Mapper`, `base/claim-plan.md`). 나머지: `H-149` Observer 진입점 인라인 / `H-150` `_blocker` 제거 / `H-151` `Refresh` 캐치업 폐기 — 게이트는 emit 경로만 미룬다 / `H-153` Store 예약 이름 가드 / `H-154` dedup. 새로 생긴 `H-158`(`:Block` 슈가)도 같은 날 확정 — 폐기, `state:Apply(blocker)`. **[2026-08-28 후속 3]** `Claim` 갈래 여덟 전량 확정 → `base/claim-plan.md`로 승격, 그 경위도 이 파일 끝 절). `pre-implementation-handtrace-round11-brief.md`(**[2026-08-28 신설]** **M2 자율 구현 규약**이자 단위 끝마다 띄우는 탐사자 지시서 — 세 갈래 분류(자율 수정 / §4 배치 / 즉시 중단), 단위 넷, 두 층 커밋 게이트, 첫 단위 계획은 §6), `pre-implementation-handtrace-round11.md`(**[2026-08-28 신설]** M2 구현 중 발견 원문 + §4 배치 문항지, 번호는 `H-165`부터 — 종이 트레이싱이 아니라 실제 코드를 옮기고 돌리다 나온 것). 다음 라운드가 필요해지면 라운드마다 파일을 새로 만들고 이름에 라운드 번호를 넣을 것(지시서도 같이 남길 것 — `-roundN-brief.md`) | +| `qa-request/` | 원래 용도는 "구현 완료(코드/에이전트 검증까지 끝남) + 사용자 본인의 실기기(Roblox Studio) QA만 남음". **[2026-08-18 확장]** 구현 전에도 **사용자 심사 라운드의 산출물**을 여기 둠 — `pre-implementation-qa-round1.md`(1라운드: `base/` 확정 문서 전체를 문항으로 재확인받아 **"아니오"가 나온 항목만** 모은 결함 목록 + 신규 요구사항(`N-n`) + 부수 오탈자. **같은 날 전부 `base/`에 반영 완료**라 지금은 "무엇이 왜 틀렸었나"의 근거 기록이고, 지금 유효한 설계는 항상 `base/`가 소스. 아직 안 닫힌 것은 `question.md` 최우선 절과 `.claude/todos.md` 00번이 소스), `pre-implementation-qa-round2.md`(2라운드: 확정 의사코드를 실제로 손으로 실행해보는 트레이싱 — **완료**, 발견된 크래시 `RC-1`(`recompute` 트리거 모델)도 같은 날 후속 세션에서 Blocker 게이팅 설계로 해결·반영까지 끝남, `archive/question-resolved.md`에 논의 요지 정리), `pre-implementation-qa-round3.md`(3라운드: `RC-1` 해법(Blocker 게이팅)이 실제로 `attachSlot`/`recompute`에 반영된 걸 손으로 트레이싱 — **완료**, `RC-3`/`RC-4`(`activateList`가 자기 Slot의 Blocker보다 먼저 실행되는 순서 문제)와 `bk.N` 수명주기 미정을 발견했다가 같은 세션에 사용자가 최초 분석 오류를 직접 정정하며 전부 해결·`base/` 반영까지 끝남, `archive/question-resolved.md`에 논의 요지 정리. `ROADMAP.md` M3가 M2의 `Blocker.luau`에 의존하게 된 마일스톤 순서 불일치는 각주로 반영 — **[2026-08-24]** 그때 열어뒀던 마일스톤 재편은 M2/M3 순서 교체로 닫혔다). `pre-implementation-qa-round4.md`(4라운드: 사용자 요청으로 **`base/` 확정 전체를 "예가 나와야 정상인 문항"으로 다시 뽑은 전수 문항지** — **[2026-08-21] 완료·종결**. 1~3라운드와 달리 이 파일은 **문항지 원본 그대로 남긴다** — 처리 결과 전량이 `-followup.md`에 쌓였으므로 "아니오만 남기는 재편"은 안 하기로 함(같은 정보가 두 곳에 갈라지는 걸 피함). 문항 수/문서별 분포는 그 파일 자신이 소스). `pre-implementation-qa-round4-response.md`(사용자 회신 원문 — 이 라운드는 회신을 **별도 파일**로 받았다, 1~3라운드와 다른 점), `pre-implementation-qa-round4-followup.md`(**[2026-08-20 시작, 2026-08-21 종결]** 그 회신 처리 결과 — A~H 8개 절이 4차에 걸쳐 시간순으로 쌓였고 **마지막 H절이 최신이자 소스**. B·C절의 재질문/판단 대기 항목은 F·G절을 거쳐 **H절에서 전량 닫혔다**(`Detach` 보존 주체, `KeyGone`, `Owned`, `attachSlot` 분해). **열린 질문 없음**. **[2026-08-21 정정]** 여기 적혀 있던 "5라운드 문항지는 만들지 않는다"는 뒤집혔다 — 같은 날 사용자 요청으로 5라운드를 만들었다), `pre-implementation-qa-round5.md`(**[2026-08-21 신설·처리 완료]** 5라운드: 4라운드에서 "예"로 넘어간 자리는 건너뛰고 **(1) 4라운드에 문항이 아예 없던 영역**(`project-setup-plan.md`/`quad-types-plan.md`, 그리고 **문서가 아니라 실제 커밋된 M1 코드**), **(2) 4라운드 회신 이후 새로 확정된 것**(`Detach`/`_detached`/`KeyGone`/`Owned`/`attachSlot` 분해 등), **(3) 큰 문서의 심화**(예: `debounce-throttle-plan.md`)만 묻는다. 문항 수는 그 문서 자신이 소스), `pre-implementation-qa-round5-response.md`(사용자 회신 원문 — 4라운드와 같이 별도 파일), `pre-implementation-qa-round5-followup.md`(**[2026-08-21]** 그 회신 처리 결과 — 즉시 반영분 / 재질문 / 사용자 판단 필요 / 새로 만든 문서 둘(`gate-plan.md`·`state-epoch-plan.md` — 같은 날 확정되며 `base/`로 승격)까지. **처리 결과의 소스는 이 파일**). `pre-implementation-handtrace-round6.md`(**[2026-08-22 신설]** 6라운드: 문항지가 아니라 **손 트레이싱**이다(2·3라운드와 같은 성격) — 사용자가 지목한 최근 확정 5개 영역(`Effect(fn, ...deps)`/`Gate`·`Blocker`/State 전파(`rawInvalid`·emit 지연)/Slot의 `native*`·offset·length·mount/`Brand`·`Epoch`·`EpochMap`)을 실제 값으로 돌려본 결과. 발견 번호는 `H-n`. **[2026-08-23] 2차 패스** — 1차가 안 본 영역(디스패치 코어 전체/라이프타임 유틸/Ref·Tag·Attribute·UI 숏핸드 핸들러/Slot의 `raw*` 계층). **[2026-08-23] 3차 패스** — 1·2차가 한 번도 안 연 문서 전체(Store/State/Source 코어, Modifier·컴포넌트 합성, 이벤트·라이프사이클·에러 격리, Tween·시간 게이트, 타입 계약과 실제 커밋된 M1 코드) + 통합 시나리오. **[2026-08-24] 4차 패스** — 문서 단위가 아니라 **축을 바꿔서**(핸들러 레지스트리 전수/두 대형 핸들러 문서 심층/`luau-test` 스파이크 실제 재실행/프리미티브 조합 매트릭스/`reference`·`archive`·로드맵 M2~M9/엔진·언어 사실 주장 전수 검증). 3·4차는 추론으로 끝내지 않고 로컬 `luau`/`luau-analyze`와 공식 문서로 **직접 재현·교차검증**했고, 그 부수로 기존 `H-2`의 크래시 주장이 틀렸음도 드러났다(3차 패스 머리의 정정 절). 발견 번호는 패스를 가로질러 이어서 매긴다. 발견 수/심각도 분포는 그 문서 자신이 소스. 각 패스의 "확인만 하고 문제 없었던 것" 절은 다시 트레이싱할 필요 없는 자리를 적어둔 것. **⭐ [2026-08-24] 전량 처리·반영 완료** — 그 문서는 이제 **발견 당시의 기록**이라 각 항목의 "갈래"는 선택 전 목록이니 그대로 믿지 말 것), `pre-implementation-handtrace-round6-followup.md`(**[2026-08-24 신설] 6라운드의 결정과 근거가 여기 소스다** — `H-1`~`H-54`를 사용자와 대화형으로 하나씩 결정한 기록이고, 반영 후 `/code-review high`가 잡은 7건(그중 셋이 이번 반영이 만든 회귀)도 D절에 있다. 진행 경위와 사용자 발언 원문은 `session/2026-08-24-01-handtrace-round6-resolution.md`). `pre-implementation-handtrace-round7.md`(**[2026-08-25 신설, 회신 대기]** 7라운드: 6라운드와 같은 손 트레이싱이되 범위가 **M2(반응형 코어)와 M2→M3 경계**다. 패스 6개가 각기 다른 각도를 쓴다 — 1차는 프리미티브 사이의 *호출 순서*를 시간축으로 겹쳐 보기, 2차는 문서가 "확인했다"고 적은 런타임/타입 주장을 실제로 `luau`/`luau-analyze`에 걸어보기, 3차는 **커밋된 M1 코드·툴체인을 이 저장소에서 그대로 돌려보기** + 1·2차가 뺐던 "M2를 *소비하는* 문서", 4차는 **M2 코어를 문서 그대로 옮긴 참조 구현을 돌려보기** + 아무 문서도 안 정한 **예외 경로**, 5차는 **확정된 M2 표면을 실제 Luau 타입으로 선언해 `luau-analyze`에 걸어보기**(확정 시그니처가 확정 관용구를 통과시키는가), 6차는 **그 참조 구현을 M2→M3 경계(Length/Offset 부기·Dispatch 체인)까지 이어 붙여 돌려보기** + **quad 자신이 던지기로 확정한 error 42곳의 계약 감사**. 발견 번호는 6라운드에서 이어서 `H-55`부터, 패스를 가로질러 연속으로 매긴다. 발견 수/심각도 분포는 그 문서 자신이 소스. 각 패스의 "문제가 없던 것" 부록은 다시 파지 않아도 되는 자리를 적어둔 것. **아직 아무것도 `base/`에 반영하지 않았다** — 판정은 사용자가 하고, 결정이 나면 6라운드처럼 `-followup.md`를 새로 만든다), `pre-implementation-handtrace-round7-verification.md`(**[2026-08-25 신설]** 그 52건이 **정말 유효한지만** 판정한 검증 패스 — 새 발견은 없다. ⚠️ **재실행이 아니라 대조로 판정했다**: 4·5·6차 패스가 쓴 전사물(`audit/handtrace-round7-reference-impl/spikes/`), `pre-implementation-handtrace-round7-followup.md`(**[2026-08-25 신설] 그 52건에 대한 사용자 결정과 `base/` 반영 결과 — 결정 단위 12묶음(🅐~🅜) 순서로 대화형 처리. **이 파일이 결정의 소스**이고 발견 원문은 앞의 두 파일. 무효/기각 7건(`H-73`~`H-77` 계열: `<>`가 값 호출부에서 동작함이 실측으로 드러나 Store 재설계로 이어짐, `RunInit` 누수는 성립 안 하는 사용법), 나머지는 전량 반영. **부수로 `question.md` 최우선 두 항목이 같이 닫혀 M2 착수 게이트가 0이 됐다**)과 `base/` 확정 의사코드를 줄 단위로 맞춰봤고(전사 오류로 생긴 발견은 **없었다**, 미신고 차이 3개는 전부 발견을 만들지 않는 방향), Luau 언어 동작·저장소 상태를 주장하는 것만 직접 재실행했다. 판정 분포와 항목별 근거는 그 문서 자신이 소스 — 여기서 세지 않는다. **결정 전에 반드시 읽을 것**: 부정 주장·개수 주장 몇 건이 정정됐고, 특히 **이미 사용자가 판단한 항목을 다시 묻게 되는 자리**가 하나 있다. 마지막 절의 **batch용 요약**이 유효 항목을 "한 결정으로 닫히는 묶음"으로 재편성해뒀으니 회신은 번호순이 아니라 그 묶음 단위로 하는 게 싸다), `pre-implementation-handtrace-round8.md`(**[2026-08-26 신설, 회신 대기]** 8라운드: 7라운드 반영으로 새로 쓰인 `base/` 서술을 **서로 겹쳐서** 재트레이싱한 것 — 개별 함수가 아니라 "반영된 결정들이 조합될 때 성립하는가"가 주제. 3패스에 걸쳐 `base/` 전 문서를 완독했고, 발견 번호는 `H-107`부터 이어 매김(발견 수·심각도 분포는 그 문서 자신이 소스), 실측 스파이크는 발견 항목에 인라인 전사. 사용자 결정 문항 Q1~Q10이 §4에 배치 회신용으로 정리돼 있다. 커밋 전 `/code-review`가 이 문서 자체의 결함 7건을 잡아 반영됐다(각 항목의 `[code-review 정정/추가]` 표시). **⭐ [2026-08-26] 전량 처리·반영 완료** — 그 문서는 이제 **발견 당시의 기록**이라 각 항목의 "갈래"는 선택 전 목록이니 그대로 믿지 말 것), `pre-implementation-handtrace-round8-followup.md`(**[2026-08-26 신설] 8라운드의 결정과 근거가 여기 소스다** — Q1~Q10을 사용자와 대화형으로 처리한 기록. **역전은 없고** 전부 "7라운드 확정이 `base/`에 내려앉을 때 생긴 누락·충돌"을 닫은 것. ⭐ 사용자가 **문항의 전제 자체를 정정한 것이 둘** 있다(Ref 콜백 ↔ Observer 콜백은 애초에 통합 대상이 아니다 / `H-118`은 소유권 문제가 아니라 문장이 틀린 것) — 결정만 읽지 말고 그 두 절을 볼 것), `pre-implementation-handtrace-round9-brief.md`(**[2026-08-26 신설]** 9라운드를 돌릴 감사자에게 주는 **지시서** — 발견 보고가 아니라 그 앞단이다. 이런 지시서를 저장하는 건 이번이 처음으로, 7·8라운드 것은 대화에만 있었고 저장되지 않았다(8라운드 본문이 인용하는 "감사 지시서 §2"가 코퍼스 어디에도 없는 이유). 스코프를 **커밋 `9dd8213` 하나의 델타**로 정의한 게 핵심 — 8라운드 결정 반영과 그 뒤 `/code-review high` 7패스 수정이 전부 그 커밋에 들어 있고 아무도 트레이싱한 적이 없다. 레인 셋(A: 그 델타의 상호 간섭 / C: `audit/handtrace-round7-reference-impl/`을 지금 계약으로 갱신해 실행 / B: 8라운드 §6이 남긴 M5+ 값 단위 트레이싱)과 우선순위 근거, `-round8-followup.md`가 적어둔 **반복 실패 모드 7개**를 사냥 목록으로 옮겨 실었다. 각도 문자(A~H)는 8라운드와 같은 걸 유지해 상호참조가 되게 했다), `pre-implementation-handtrace-round9.md`(**[2026-08-26]** 9라운드 발견 보고 — 레인 A(`9dd8213` 델타 상호 간섭)·C(참조 구현을 현재 계약으로 재전사해 `luau` 실행)·G(Luau 사실 재확인)·D(ROADMAP M2 시뮬레이션)·B(M5+ 값 단위, 첫 시도) — 발견 `H-124`~`H-141`, 🔴 둘(`recompute`의 `lengthList[i]` nil 읽기 / 재마운트 시 `_baseObserver` 미바인드 캐시 stale) 다 실측 재현. §4 배치 문항 Q1~Q10 + §5 이상 없음(⭐ `keyof<{}>` 빈 Store 실측으로 클린) + §6), `pre-implementation-handtrace-round9-followup.md`(**[2026-08-27] 9라운드 결정의 소스 — 전량 처리 완료** — Q1(`recompute` 되감기 판정을 읽기 앞으로) / Q2(`Offset`·`_baseObserver`를 Slot 생성자로, `materializeSlotTree` 순서, `_destroyed` 플래그) / Q3(`element → index`는 `bk.indexOfElement` 하나 — 사용자가 정한 적 없는 `token` 폐기, `H-137` 소멸, `H-141` 신설) / Q4(`EffectHandle` 네 진입점 의사코드) / Q5(M2에 `Ref` 최소형) / Q6(`WeakUnsubscribe` 관대) / Q7(폐기 블록 `archive/`) / Q8(`InstanceChildHandler` 부기) / **Q9(문항 전제가 틀림 — Tween 절 스케치 한 줄 복사 오류)** / Q10(`reconcile` 배치 Blocker) + `H-138`(숏핸드 우선순위) / `H-139`(`New`/`drive` 파이프라인 의사코드) / **`H-142`(props에 `Parent` 금지 — 순서 문제 소멸)** / **`H-143`~`H-146`**(`/code-review`가 낸 새 메커니즘 넷 — 전부 권고 (a), `H-144`는 사용자 요청으로 재구독 뒤 epoch·Blocker 상호작용을 재트레이싱한 기록 포함). 진행 표가 상태의 소스, 사용자 회신 원문 셋 인용; **[2026-08-28]** `H-143`~`H-146` 반영분의 감사 8라운드 표와 `/code-review high` 기록도 여기), `pre-implementation-handtrace-round10-brief.md`(**[2026-08-28 신설]** 10라운드 지시서 — 델타가 아니라 **광범위** 스코프(M2~M8, 레인 A 반응형 코어 전체 / C 참조 구현 갱신·실행 / B 디스패치·Slot / D 타입·M1 코드), 신선한 탐사자가 한 번에 문항지를 만들어 사용자가 배치로 결정하게 하는 것이 목적), `pre-implementation-handtrace-round10.md`(**[2026-08-28 신설, 회신 대기]** 10라운드 발견 보고 + §4 배치 문항지 — 씨앗은 `/code-review`가 낸 `H-147`~`H-149`(죽은 핸들에서 `Rerun` / `Parent` 거부 전용 문구는 새 메커니즘 / Observer `Subscribe` 위임과 `level 2`), 탐사자 발견은 `H-150`부터. 레인 C 실행 기록은 `audit/handtrace-round10-reference-impl/`. **[2026-08-28 탐사 완료]** 🔴 0 / 🟡 5 / 🟢 3, §4 문항 7건(기존 3 + `H-150` `Effect._blocker` 죽은 부품 / `H-151` 게이트 우회 계약 / `H-153` Store 예약 이름 런타임 가드 / `H-154` `InstanceChildHandler` dedup) — 전부 권고 (a). 레인 A·C 완료, B 부분, D `./scripts/test.sh` ALL PASS), `pre-implementation-handtrace-round10-followup.md`(**[2026-08-28] 10라운드 결정의 소스 — 전량 처리 완료.** 사용자가 *"하나하나 같이 보자"*라 대화형으로 처리. **문항의 전제를 뒤집은 것 둘**: `H-147`은 "죽은 핸들에서 `Rerun`"이 아니라 **`fn`/cleanup이 자기 구독을 바꿀 수 있다는 허용 자체가 모순**(→ (A) 금지, `H-143` 소멸, `rawRerun(force)`/`Rerun` 분리), `H-148`은 "문구"가 아니라 **루트 마운트 표면의 부재**(→ `Claim` + `D.Mapper`, `base/claim-plan.md`). 나머지: `H-149` Observer 진입점 인라인 / `H-150` `_blocker` 제거 / `H-151` `Refresh` 캐치업 폐기 — 게이트는 emit 경로만 미룬다 / `H-153` Store 예약 이름 가드 / `H-154` dedup. 새로 생긴 `H-158`(`:Block` 슈가)도 같은 날 확정 — 폐기, `state:Apply(blocker)`. **[2026-08-28 후속 3]** `Claim` 갈래 여덟 전량 확정 → `base/claim-plan.md`로 승격, 그 경위도 이 파일 끝 절). `m2-implementation-round11-brief.md`(**[2026-08-28 신설]** **M2 자율 구현 규약**이자 단위 끝마다 띄우는 탐사자 지시서 — 세 갈래 분류(자율 수정 / §4 배치 / 즉시 중단), 단위 넷, 두 층 커밋 게이트, 첫 단위 계획은 §6), `m2-implementation-round11.md`(**[2026-08-28 신설]** M2 구현 중 발견 원문 + §4 배치 문항지, 번호는 `H-165`부터 — 종이 트레이싱이 아니라 실제 코드를 옮기고 돌리다 나온 것. **[2026-08-31 개명]** 원래 `pre-implementation-handtrace-round11*`이었으나 구현 **중** 문서라 이름이 틀려 사용자 지시로 개명 — brief도 같이). **⭐ [2026-08-31 명명 규약, 사용자 확정]** 구현 라운드 파일은 **`mN-implementation-roundNN`** — 라운드 번호는 마일스톤을 가로질러 **단순 증가**하고(다음 라운드는 어느 마일스톤이든 round12), 마일스톤 접두가 어느 마일스톤의 라운드인지 담는다. 근거: *"m3 을 진행하다 m2 에 하자가 있음을 확인하면 다시 m2 로 올라가 round 가 진행되다 돌아오는 경우도 있을것 … 접두가 둘 다 있는게 정보를 온전히 담아줘"* — 번호만으로는 순서가, 접두만으로는 소속이 안 담긴다. 지시서도 같이 남길 것(`-roundNN-brief.md`). round1~10의 옛 이름(`pre-implementation-*`)은 그대로 둔다 — 실제로 구현 전 라운드였으니 이름이 맞다 | | `archive/` | 완료 + 사용자가 실사용/실기기로 직접 검증까지 마침 (구현 대상). **[2026-08-06 확장]** 완전히 뒤집힌 설계 결정을 원문+역전 이유+diff와 함께 보존하는 용도로도 사용(제목 `[역전됨]` — 한 번 확정했다가 뒤집힌 것) — 더 이상 능동적으로 참고 안 해도 되지만(토큰 낭비 방지 위해 `base/`/`research/`에서 뺌) `quadnomicon` 소재로는 나중에 쓸 수 있음. **[2026-08-07 확장]** 후보였다가 채택 안 된 것(확정한 적 없이 검토 후 기각)도 같은 방식으로 보존, 제목은 구분을 위해 `[기각됨]` — `[역전됨]`과 의미가 다르므로 혼동하지 말 것. **[2026-08-07 세 번째 확장]** 설계 반전/기각과 별개로, 에이전트가 문서 작성 중 스스로 낸 개념 혼동을 정정한 이력은 `[에이전트 실수]` 태그로 `agent-mistake.md` 하나에 모음(`.claude/session-summary.md`/`session/` 로그와의 중복 방지) | | `feedback/` | 실사용 피드백을 정리한 긴 로그 — **[2026-08-19 기준] 폴더 자체가 아직 없음**(M0/M1 스캐폴딩만으론 안 생기고 실제로 렌더링해보고 쓰는 단계부터, 첫 피드백이 생길 때 만들면 됨). `qa-request/`는 **[2026-08-18] 더 이상 비어 있지 않음**(구현 전 QA 1라운드 산출물이 들어감) — 여긴 아직 폴더도 없음 | | `luau-test/` | **[2026-08-09 신설]** `base/` 확정 사항 중 "추론만으로 확정하고 실제 Luau로 부딪혀본 적 없는 것"(M0 스파이크 대상)을 `luau`/`luau-analyze`/`luau-lsp`/Roblox Studio로 사용자가 직접 돌려볼 독립 실행 스크립트 모음. **[2026-08-13 여섯 번째 세션, 첫 실측]** `luau`/`luau-analyze` 바이너리가 생겨 처음으로 실제 실행 — **런타임 12개 전원 통과**, 타입 쪽에서 `:Compute(fn)` lazy 핸들 계약이 Luau 추론과 충돌하는 게 드러남(당시 `question.md` 0-Y). **[2026-08-13 열세 번째 세션]** 그 0-Y가 해소되며 `review-required/`가 **비었음** — 계약은 유지 확정, 남은 건 Luau 자체 한계라 `base/typing-limits.md`가 담당. **`STATUS.md`가 상태의 소스**(pass / 사람 결정 필요 / 스파이크 깨짐 / 미실행 분류 — 사람이 먼저 볼 것만 위에), `luau-test/README.md`는 각 파일의 검증 의도·배경, 실행 결과 상세는 `audit/luau-test-first-run-2026-08-13.md` | diff --git a/.claude/base/typing-limits.md b/.claude/base/typing-limits.md index 9fbaa43..4f9543d 100644 --- a/.claude/base/typing-limits.md +++ b/.claude/base/typing-limits.md @@ -173,7 +173,7 @@ export type State = StateData & { 유니온 하나(`((State) -> U) | { __apply: … -> U }`)로 두면 `Blocker`처럼 필드가 더 있는 객체가 제네릭 `U` 자리에서 너비 서브타이핑을 못 받아 `state:Apply(blocker)`가 strict에서 막힌다(인덱서 `[string]: any`로 열어도 같다 — `luau-test/done/26-*`). - 객체 쪽 반환이 `any`라 결과는 명시 주석(①과 같은 관례). `qa-request/pre-implementation-handtrace-round11.md` `H-179`. + 객체 쪽 반환이 `any`라 결과는 명시 주석(①과 같은 관례). `qa-request/m2-implementation-round11.md` `H-179`. - **캐비엇**: 콜백이 받는 `s`는 `StateData`라 `Compute`/`With`가 없습니다. 콜백 안에서 다시 `s:Compute(...)`를 부르는 자리 (`:Apply`의 factory가 대표적)는 이 방식으로 못 풀고 diff --git a/.claude/conventions.md b/.claude/conventions.md index e225195..aaf4482 100644 --- a/.claude/conventions.md +++ b/.claude/conventions.md @@ -379,7 +379,7 @@ haiku, 일반 작업은 sonnet. 특히 소스코드를 많이 읽어야 하는 GitHub 기여 그래프에 반영되게 하기 위함 — 관련 리모트 정책은 메모리 `git-remote-push-policy` 및 위 `SAFETY.md` 항목 참고. - **⭐ [2026-08-28 신설] M2 자율 구현 규약 — 본문은 - `qa-request/pre-implementation-handtrace-round11-brief.md`가 소스, 여기선 + `qa-request/m2-implementation-round11-brief.md`가 소스, 여기선 가리키기만.** 사용자 결정(2026-08-28, *"수정하고 너가 진행하자"*)으로 M2는 자율 구간으로 돈다. 요지 셋: (1) 발견은 **세 갈래** — 문서가 이미 답을 가진 건 `H-nnn`으로 기록하고 `base/`+코드를 같은 커밋에서 자율로 고침 / 새 diff --git a/.claude/luau-test/README.md b/.claude/luau-test/README.md index 550bbd8..e12fa6a 100644 --- a/.claude/luau-test/README.md +++ b/.claude/luau-test/README.md @@ -96,7 +96,7 @@ ROADMAP 항목 근거인지, 어떻게 실행하는지, 실행 후 뭘 확인해 | `21-type-store-undeclared-key-rejected.luau` (타입체크 전용) | **[2026-08-19 신규]** `Store<{field: T}>`로 선언 안 된 이름에 dot-access하면 `type function`이 합성한 결과 타입(`ProcessStoreType`, `16`과 동일)에 그 프로퍼티가 없어 타입 시간에 거부되는지 — `store-plan.md`가 "아마 그럴 것"으로만 적어뒀던 걸 M0에서 실측. 통과: 미선언 키 접근 2건이 정확히 `TypeError`로 걸림 | `store-plan.md` "Store = Source들의 이름 붙은 모음" 절의 "[확인 요구, 2026-08-18 구현 전 QA]" 항목, `todos.md` 00번 **⚠️ [2026-08-25 이동, `rewrite-required/`]** `16`의 `ProcessStoreType`을 재사용하므로 같이 낡았다. **검증 대상(미선언 키는 타입 에러)은 그대로 유효**하고 새 모양에서도 성립함이 확인됐다(`store.nope` 거부) — 새 `Store` 선언으로 바꿔 쓰기만 하면 된다 | | `22-runtime-ref-preref-postref-brand.luau` | **[2026-08-19 신규]** 구 `13`의 런타임(B) 절반을 분리한 것 — `isPreRef`/`isPostRef`가 같은 층위의 배타적 형제(둘 다 `isRef`엔 `true`, 서로에겐 `false`)인지, Leaf 핸들러 흉내(`isRef(v) and not isPreRef(v) and not isPostRef(v)`)가 Ref/PreRef/PostRef 셋을 정확히 갈라내는지. **[2026-08-21] `rewrite-required/`로 이동** — 파일이 직접 구현해 쓰는 `Brand.set`/`Brand.get`이 인스턴스 브랜드 재작성으로 역전된 옛 API가 됐다(검증 대상 자체는 그대로 유효, 상태와 재작성 지침은 `STATUS.md`가 소스) | `ref-plan.md`의 "`PostRef`" 절, `brand-plan.md`의 "⭐ 구현 — 인스턴스 브랜드" 절 | | `23-type-quadtypes-checkversion-addplugin.luau` (타입체크 전용) | **[2026-08-19 신규, 같은 날 후속으로 재작성]** 실제 `quad-types`/`quad-base`/`type-version-check`를 `require`해서 `CheckedQuad`(글롭/캐럿 버전 패턴 체크, `type-version-check` 위에 얹힘)이 `AddPlugin` 체이닝과 맞물려 동작하는지 — 양성(버전 일치 + 2단 체이닝 + 이전 확장 필드 보존), 음성(버전 불일치 → 강제 참조 시점에 정확히 `TypeError`). `type function`을 거친 값은 패스스루라도 이후 제네릭 self 체이닝이 깨진다는 걸 이 스파이크가 재작성 과정에서 직접 발견. 재작성 과정에서 `export type function`(cross-package 필수)과 2개 이상 명시 제네릭 인스턴스화의 이중 꺾쇠(`Foo<>`) 요구도 추가로 실측 확인 | `quad-types-plan.md`, `typing-limits.md` §6 | -| `26-type-apply-object-factory-overload.luau` (타입체크 전용) | `state:Apply(factory)`의 파라미터 타입 — 함수 팩토리와 `__apply` 객체 팩토리를 한 시그니처로 받을 때 유니온/오버로드/인덱서 중 어느 표기가 strict에서 `state:Apply(blocker)`(필드가 더 있는 객체)를 통과시키는지 | `qa-request/pre-implementation-handtrace-round11.md` `H-179`(M2 단위 4 실측) | +| `26-type-apply-object-factory-overload.luau` (타입체크 전용) | `state:Apply(factory)`의 파라미터 타입 — 함수 팩토리와 `__apply` 객체 팩토리를 한 시그니처로 받을 때 유니온/오버로드/인덱서 중 어느 표기가 strict에서 `state:Apply(blocker)`(필드가 더 있는 객체)를 통과시키는지 | `qa-request/m2-implementation-round11.md` `H-179`(M2 단위 4 실측) | ## 공통 유틸리티 diff --git a/.claude/luau-test/STATUS.md b/.claude/luau-test/STATUS.md index 822f8b2..e0a270f 100644 --- a/.claude/luau-test/STATUS.md +++ b/.claude/luau-test/STATUS.md @@ -181,9 +181,9 @@ | 파일 | 확인된 것 | |---|---| -| `26-type-apply-object-factory-overload.luau` (타입체크 전용) | ✅ **[2026-08-29 M2 단위 4]** `state:Apply(factory)`의 파라미터 타입은 **교집합 오버로드**(함수 팩토리 제네릭 `U` / `__apply` 객체 `any` 반환) — 유니온 하나는 필드가 더 있는 객체(`Blocker`)를 못 받는다. 기대 진단 2건(음성 대조군)만 — 근거: `qa-request/pre-implementation-handtrace-round11.md` `H-179`, `quad-types/src/init.luau` `State.Apply` | +| `26-type-apply-object-factory-overload.luau` (타입체크 전용) | ✅ **[2026-08-29 M2 단위 4]** `state:Apply(factory)`의 파라미터 타입은 **교집합 오버로드**(함수 팩토리 제네릭 `U` / `__apply` 객체 `any` 반환) — 유니온 하나는 필드가 더 있는 객체(`Blocker`)를 못 받는다. 기대 진단 2건(음성 대조군)만 — 근거: `qa-request/m2-implementation-round11.md` `H-179`, `quad-types/src/init.luau` `State.Apply` | | `05-store-state-diamond-propagation.luau` | **[2026-08-29 폐기 → `done/`로 이동, 재작성 안 함]** M2 단위 2·3의 `quad-base/test/spec.state.luau` 3번(다이아몬드에서 두 번째 도착이 규칙 3으로 접힘, 조인 1회 계산)·`spec.effect.luau` 3번(Effect도 1회)이 실제 구현에서 같은 것을 고정한다 — 이 스파이크가 물으려던 "변경당 1회"의 답. 아래는 폐기 전 상태: 2026-08-19 재작성분은 그 시점 모델 기준 ✅ 통과였음 — 근거: **[2026-08-21] 모델이 또 바뀌었다** — 소스 에포크 비교 채택(`base/state-epoch-plan.md`)으로 다이아몬드에서 **두 번째 통지가 접힌다**. 그래서 이 스파이크의 핵심 assert("`:Get()`을 안 부르는 Observer가 변경당 경로 수(2)만큼 운다")가 **정반대**가 됐다 — 이제 **변경당 1회**여야 한다. **살릴 것**: `invalid` 기반 dedup이면 두 번째 변경부터 침묵하는 것을 잡는 음성 대조군(그 금지는 지금도 유효). **새로 넣을 것**: DFS 도중 `Get()`이 섞인 값을 캐시하던 glitch가 에포크로 사라지는지(그 문서 §1의 시나리오) | -| `15-type-compute-trailing-deps-typepack.luau` | **[2026-08-28 폐기 → `done/`로 이동, 재작성 안 함]** M2 단위 2가 실제 `quad-types` 선언에서 타입팩 형태를 실측해 기각했다(`qa-request/pre-implementation-handtrace-round11.md` `H-176`: strict에서 콜백 dep 추론이 깨져 정상 호출까지 막힘 → deps 자리 `...any`). 이 스파이크가 물으려던 (B)의 답이 나왔으므로 파일은 역사로만 `done/`에 남긴다. 아래는 폐기 전 상태: **파싱 실패**(SyntaxError) — 근거: 음성 대조군의 타입 표기가 `TypeError`가 아니라 `SyntaxError`로 걸려 **파일 전체가 아무것도 검증 못 함** — 대조군을 별도 파일/블록으로 격리 | +| `15-type-compute-trailing-deps-typepack.luau` | **[2026-08-28 폐기 → `done/`로 이동, 재작성 안 함]** M2 단위 2가 실제 `quad-types` 선언에서 타입팩 형태를 실측해 기각했다(`qa-request/m2-implementation-round11.md` `H-176`: strict에서 콜백 dep 추론이 깨져 정상 호출까지 막힘 → deps 자리 `...any`). 이 스파이크가 물으려던 (B)의 답이 나왔으므로 파일은 역사로만 `done/`에 남긴다. 아래는 폐기 전 상태: **파싱 실패**(SyntaxError) — 근거: 음성 대조군의 타입 표기가 `TypeError`가 아니라 `SyntaxError`로 걸려 **파일 전체가 아무것도 검증 못 함** — 대조군을 별도 파일/블록으로 격리 | | `02-none-sentinel-vs-nil-holes` | `nil` 소진 시 `#t` 50→49로 무너짐 / `None`은 항상 50. 반대로 **당시의** Ref 콜백 배열은 `None` 쓰면 죽은 슬롯 1000개 잔존 — **두 배열의 규칙이 서로 반대여야 함**이 정량 확인. **[2026-08-24]** 그 대비의 한쪽(Ref 콜백)은 6라운드 `H-7`로 **해시맵 셋**이 되어 사라졌지만, 이 스파이크가 실제로 확인한 것(**일반 Lua 테이블에서 `nil` 구멍과 `None` 채움의 거동 차이**)은 그대로 유효하다 — `sourceList`/`flattened`처럼 순서가 중요한 배열이 여전히 그 결론 위에 선다 | | `03-recursive-store-bind-dispatch` | StoreBind 재귀 재-dispatch, `None`→`nil` 흐름, 무한재귀 없이 종료 | | `06-component-boundary-nil-hole-props` | `or None` 없으면 앞쪽 nil-hole로 슬롯 소실, 관용구 쓰면 항상 보존 | diff --git a/.claude/luau-test/done/26-type-apply-object-factory-overload.luau b/.claude/luau-test/done/26-type-apply-object-factory-overload.luau index a211405..b9579b0 100644 --- a/.claude/luau-test/done/26-type-apply-object-factory-overload.luau +++ b/.claude/luau-test/done/26-type-apply-object-factory-overload.luau @@ -2,7 +2,7 @@ -- [2026-08-29 M2 단위 4] `state:Apply(factory)`의 파라미터 타입 표기 실측 — 결론: 교집합 오버로드(N/O). -- 유니온 하나(`((State) -> U) | { __apply: ... -> U }`)는 `Blocker`처럼 필드가 더 있는 객체를 제네릭 U 자리에서 -- 받지 못한다(너비 서브타이핑 실패, 인덱서 `[string]: any`로도 안 됨). 원문 스파이크 4개 중 통과한 마지막 것. --- 소스: `qa-request/pre-implementation-handtrace-round11.md` `H-179`. 기대: 진단 2건(마지막 두 줄 음성 대조군)만. +-- 소스: `qa-request/m2-implementation-round11.md` `H-179`. 기대: 진단 2건(마지막 두 줄 음성 대조군)만. export type StateData = { Get: (self: StateData) -> T } -- N: 교집합 오버로드 — 함수 팩토리는 제네릭 U, 객체 팩토리는 비제네릭 any 반환 export type StateN = StateData & { diff --git a/.claude/project-context.md b/.claude/project-context.md index ec90ae1..3f1c400 100644 --- a/.claude/project-context.md +++ b/.claude/project-context.md @@ -10,13 +10,12 @@ Roblox 엔진에서 동작하는 DOMless UI 렌더러 **quad**를 처음부터 지속 가능성 — 빠른 이터레이션보다 정확성/설계 정합성이 우선. 작업 기간은 길게 잡음. -**[2026-08-24 기준] M0(스파이크 검증)/M1(스캐폴딩) 완료, 다음은 M2(반응형 -코어 — Source/State/Store)** — **⭐ [2026-08-28] M2 착수, 자율 구현 구간 진행 -중**(규약 `qa-request/pre-implementation-handtrace-round11-brief.md`, 발견 -`-round11.md`; **[2026-08-29]** 단위 넷 전부 구현 완료·단위 3·4 끝 절차 완료, -**[2026-08-31]** 단위 2 `/code-review`·§4 배치 회신 **전량 종결**(열린 문항 0· -코드 마커 0) — 남은 마무리는 `.claude/todos.md` 00번이 소스)(마일스톤이 -넘어갈 때 루트 `CLAUDE.md` 머리말도 +**⭐ [2026-08-31 기준] M0(스파이크 검증)/M1(스캐폴딩)/M2(반응형 코어 — +Source/State/Store) 완료, 다음은 M3(디스패치 엔진)** — M2는 자율 구현 +구간(규약 `qa-request/m2-implementation-round11-brief.md`, 발견 `-round11.md`) +으로 2026-08-28 착수~08-31 종결(단위 넷 구현·감사·리뷰·탐사 완료, §4 문항· +코드 마커 0). **M3 착수 전 새 자율 규약 문항은 사용자와 정할 것** — +`.claude/todos.md` 00번이 소스(마일스톤이 넘어갈 때 루트 `CLAUDE.md` 머리말도 같이 고칠 것 — 같은 상태를 두 곳이 서술하고 있음). **⚠️ [2026-08-24] M2와 M3의 번호·순서가 맞바뀌었다** — 열려 있던 마일스톤 순서 문제가 (a) 순서 교체로 닫힌 결과다(경위는 `archive/question-resolved.md`의 "마일스톤 경계" diff --git a/.claude/qa-request/pre-implementation-handtrace-round11-brief.md b/.claude/qa-request/m2-implementation-round11-brief.md similarity index 97% rename from .claude/qa-request/pre-implementation-handtrace-round11-brief.md rename to .claude/qa-request/m2-implementation-round11-brief.md index 59035e2..e21f1ed 100644 --- a/.claude/qa-request/pre-implementation-handtrace-round11-brief.md +++ b/.claude/qa-request/m2-implementation-round11-brief.md @@ -2,7 +2,7 @@ > **이 파일이 무엇인가**: **[2026-08-28 신설]** M2(반응형 코어) 구현을 자율 구간으로 > 돌리기 위한 규약이자, 단위가 끝날 때마다 띄우는 **11라운드 탐사자**에게 그대로 -> 주는 지시서다. 산출물은 `pre-implementation-handtrace-round11.md`(발견 원문 + +> 주는 지시서다. 산출물은 `m2-implementation-round11.md`(발견 원문 + > §4 배치 문항지). 9·10라운드 지시서(`-round9-brief.md`/`-round10-brief.md`)와 > 같은 관례이되, **이번 라운드는 종이가 아니라 실제 코드가 감사 도구다** — > 10라운드 지시서가 *"이후로는 M2 구현 자체가 더 나은 감사 도구"*라고 예고한 @@ -52,7 +52,7 @@ 1. **자율로 고치고 넘어가는 것**: `base/` 의사코드를 옮기다 드러나는 오류(순서, 빠진 `end`, 이름 불일치, 문서 간 stale), 테스트 실패 중 **"문서가 이미 답을 갖고 있는 것"**. - → `H-nnn` 번호를 매겨 `pre-implementation-handtrace-round11.md`에 기록하고 + → `H-nnn` 번호를 매겨 `m2-implementation-round11.md`에 기록하고 **`base/`와 코드를 같은 커밋에서** 고친다. 묻지 않는다. 번호는 **`H-165`부터** (10라운드 후속이 `H-164`까지 썼다). 2. **모아서 올리는 것**: 새 필드·인자·이름·표면·메커니즘이 필요해지는 것, 확정을 @@ -106,7 +106,7 @@ 1. 먼저 읽을 것: `CLAUDE.md` → `.claude/conventions.md`(특히 *"새 필드·인자·이름· 메커니즘은 발견이지 결정이 아니다"*와 *"하나의 무언가가 두 일을 하고 있지 - 않은지"*) → 이 파일 §1~§3 → `pre-implementation-handtrace-round11.md`(지금까지의 + 않은지"*) → 이 파일 §1~§3 → `m2-implementation-round11.md`(지금까지의 발견, 당신의 번호는 마지막 번호 다음부터). 2. 대상: 이번 단위의 커밋 범위(`git log`로 확인)에 들어온 `quad-base/src/`· `quad-base/test/`와, 그 코드가 옮겨 적은 `base/` 절. diff --git a/.claude/qa-request/pre-implementation-handtrace-round11.md b/.claude/qa-request/m2-implementation-round11.md similarity index 100% rename from .claude/qa-request/pre-implementation-handtrace-round11.md rename to .claude/qa-request/m2-implementation-round11.md diff --git a/.claude/session-summary.md b/.claude/session-summary.md index 851021c..ec2656e 100644 --- a/.claude/session-summary.md +++ b/.claude/session-summary.md @@ -2017,7 +2017,7 @@ Q4(`EffectHandle` 네 진입점 의사코드 — Observer 것 재사용, `Unsubs `FrameParam` 원소 타입 파라미터. - **`session/2026-08-28-03-m2-unit1-common-base.md`** — **M2 착수.** 다른 에이전트가 초안한 자율 구현 규약을 검토해 순서 오류 하나(`EpochMap`이 `Effect` 뒤 → State 본체 - 앞)와 소스 단일화를 고쳐 채택(`qa-request/pre-implementation-handtrace-round11-brief.md`, + 앞)와 소스 단일화를 고쳐 채택(`qa-request/m2-implementation-round11-brief.md`, 세 갈래 분류 / 단위 넷 / 두 층 커밋 게이트, `HUMAN_TODO.md` 2번 닫힘). 첫 단위(공통 기반)를 사용자 확인(*"진행하면 될것 같아"*) 뒤 구현 — `Void`/`Brand`(인스턴스 15 + `is*` 11 한 잎 파일)/`LifetimeHandle`(`InitLifetimeHandle` 에러 스텁)/`Ref` 최소형/ @@ -2056,5 +2056,8 @@ Q4(`EffectHandle` 네 진입점 의사코드 — Observer 것 재사용, `Unsubs 그 §4 회신 2 블록), 보류 하나(`H-205`). **같은 날 회신 3으로 §4 전량 종결** — `H-186` UB 문서화 / `H-198` 사용자 안(스탬프를 fn 직전 + `Get` 재시작 루프 — 계약 강화: 모든 `Get`이 최신 수렴값 반환, 무한 케이스 UB) / `H-205` level 3 / 코드 검토 - `H-208`(`table.clone` 스냅샷)·`H-209`(generalized iteration 전환). 열린 문항 0·마커 0, - 남은 마무리는 round11 파일명 변경과 M2 종료 보고. + `H-208`(`table.clone` 스냅샷)·`H-209`(generalized iteration 전환). 열린 문항 0·마커 0. + **같은 날 파일 개명·M2 종결** — `m2-implementation-round11*`로(명명 규약 + `mN-implementation-roundNN`, 라운드 번호는 마일스톤 가로질러 단순 증가 — + `README.md` `qa-request/` 행이 소스), 툴링 픽스 둘(`H-210` rojo 트리 / + `H-211` Relate 타입)도 이 세션. 다음 액션은 M3 착수 규약 문항. diff --git a/.claude/session/2026-08-28-03-m2-unit1-common-base.md b/.claude/session/2026-08-28-03-m2-unit1-common-base.md index a85efd8..95770f2 100644 --- a/.claude/session/2026-08-28-03-m2-unit1-common-base.md +++ b/.claude/session/2026-08-28-03-m2-unit1-common-base.md @@ -24,7 +24,7 @@ - `scripts/test.sh`: `spec.*` 수집 + `luau-analyze quad-base/src + spec + mock`. - spec 5개(brand/relate/lifetime/ref/void). -## 발견 (`qa-request/pre-implementation-handtrace-round11.md`) +## 발견 (`qa-request/m2-implementation-round11.md`) - `H-165` ① pesde shim은 생성 시점 export 타입만 안다 → `pesde install` 재실행, `project-setup-plan.md`에 둘째 함정으로 기록. diff --git a/.claude/session/2026-08-31-01-unit2-code-review.md b/.claude/session/2026-08-31-01-unit2-code-review.md index c1b126c..3453c04 100644 --- a/.claude/session/2026-08-31-01-unit2-code-review.md +++ b/.claude/session/2026-08-31-01-unit2-code-review.md @@ -7,7 +7,7 @@ 지시했다. §4 문항 여섯(`H-182`~`H-187`)의 회신은 이 세션 시작 시점에 아직 없음. 부수 결정 하나 — 사용자: *"이건 pre-implementation 은 아닌듯 하네, 이름은 나중에 -바꾸자"*. `pre-implementation-handtrace-round11*.md`는 구현 **중** 발견 문서라 이름이 +바꾸자"*. `m2-implementation-round11*.md`는 구현 **중** 발견 문서라 이름이 안 맞는다는 것. **이름 변경은 §4 회신 처리 뒤로 미룸**(문항지·brief와 인용처를 한꺼번에 옮겨야 해서) — 아직 안 했고, 잊지 말 것. @@ -24,7 +24,7 @@ notification 시점에 파인더 4개가 미완인 채 멈춤. 이번엔 opus 정확성 8건 전부 실제 코드에 재현 스크립트로 확인. 효율 배치는 리뷰 스스로 "관측된 병목에만 구조" 원칙 위반으로 기각, 약한 정리 항목들은 심각도 미달 기각. 발견 상세와 -처리의 소스는 `qa-request/pre-implementation-handtrace-round11.md`(요약 표 +처리의 소스는 `qa-request/m2-implementation-round11.md`(요약 표 `H-198`~`H-207`, 상세 절 "단위 2 — `/code-review high`") — 여기선 갈래만: - **① 여섯**(같은 커밋에서 반영): `H-199`(nil dep 조용한 탈락 — `collectDeps` + error), @@ -115,3 +115,14 @@ notification 시점에 파인더 4개가 미완인 채 멈춤. 이번엔 opus - 회신 3 감사 1라운드(확실 1·의심 1) 반영: `state-epoch-plan.md` H-85 절의 옛 계약 문장("다음 Get이 반드시 재계산")을 H-198 재시작 루프로 정정, `todos.md` 00의 H-번호 나열을 소스 포인터로 축소(머리말 규칙). + +## 같은 날 후속 4 — round11 파일 개명과 명명 규약, M2 종결 + +사용자 선택 (2): `pre-implementation-handtrace-round11*` → **`m2-implementation-round11*`**. +**명명 규약 확정**: `mN-implementation-roundNN` — 라운드 번호는 마일스톤을 가로질러 +**단순 증가**, 마일스톤 접두가 소속을 담는다. 사용자 근거: *"m3 을 진행하다 m2 에 +하자가 있음을 확인하면 다시 m2 로 올라가 round 가 진행되다 돌아오는 경우도 있을것 … +접두가 둘 다 있는게 정보를 온전히 담아줘"* — 규약 본문은 `README.md` `qa-request/` 행. +`git mv` + 전 코퍼스 치환 22곳(잔존 0), round1~10의 `pre-implementation-*` 옛 이름은 +실제로 구현 전 라운드라 그대로. CLAUDE.md/project-context.md 머리말을 "M0~M2 완료, +다음은 M3"로, todos 00을 종결로. **M2 종결** — 다음 액션은 M3 착수 규약 문항. diff --git a/.claude/todos.md b/.claude/todos.md index 505c799..e524bda 100644 --- a/.claude/todos.md +++ b/.claude/todos.md @@ -5,8 +5,8 @@ (`.claude/question.md`, `luau-test/STATUS.md` 등). -00. **⭐⭐⭐ [2026-08-28] M2 착수 — 자율 구현 구간 진행 중.** 규약은 - `qa-request/pre-implementation-handtrace-round11-brief.md`(세 갈래 분류 / +00. **⭐⭐⭐ [2026-08-28 착수 → 2026-08-31 종결] M2 자율 구현 구간 — 완료.** 규약은 + `qa-request/m2-implementation-round11-brief.md`(세 갈래 분류 / 단위 넷 / 관여 시점), 발견과 배치 문항은 `-round11.md`(§4 표가 사용자가 읽을 유일한 자리). **진행 상태의 소스는 `ROADMAP.md` M2 체크박스**, 여기서 세지 않는다. **[2026-08-29 새벽 기준]** 단위 1·2 완료(단위 2 감사 6라운드 수렴), @@ -18,9 +18,14 @@ 회신 블록들이 소스 — 여기서 세지 않는다), **§4 열린 문항 0·코드 마커 0** — 진행 원문은 `session/2026-08-28-03-m2-unit1-common-base.md` 마지막 절과 - `session/2026-08-31-01-unit2-code-review.md`. 남은 할 일: - `pre-implementation-handtrace-round11*` 파일명 변경(사용자 2026-08-31 — 구현 중 - 문서라 pre-implementation이 안 맞음; 새 이름은 사용자와 정할 것)과 M2 종료 보고. + `session/2026-08-31-01-unit2-code-review.md`. **[2026-08-31] 파일명 변경까지 + 완료** — 옛 `pre-implementation-handtrace-round11*`을 `m2-implementation-round11*`로 + 개명(구현 중 문서라 옛 이름이 안 맞았음; 명명 규약 `mN-implementation-roundNN`은 + `.claude/README.md` `qa-request/` 행이 소스 — 라운드 번호는 마일스톤을 가로질러 + 단순 증가). M2 종료 보고도 전달 — **M2 종결.** + **다음 액션: M3(디스패치 엔진) 착수 — 자율 구현 규약을 M2처럼 쓸지, 단위를 + 어떻게 자를지 등 새 규약 문항을 만들어 사용자와 정할 것**(2026-08-29 + 체크포인트의 "M3은 새 규약 문항" 그대로). 아래는 착수 전(2026-08-26) 서술: **[2026-08-26] 8라운드까지 전부 처리 완료 — M2 착수 게이트가 0이다.** diff --git a/CLAUDE.md b/CLAUDE.md index 4c19547..8f4df19 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,13 +1,13 @@ # CLAUDE.md Roblox 엔진용 DOMless UI 렌더러 **quad**를 처음부터 다시 짜는 프로젝트. -**[2026-08-24 기준] M0(스파이크 검증)/M1(스캐폴딩)까지 완료, 다음은 -M2(반응형 코어 — Source/State/Store)** — **⭐ [2026-08-28] M2 착수, 자율 구현 -구간 진행 중**(규약은 `.claude/qa-request/pre-implementation-handtrace-round11-brief.md`, -발견·배치 문항은 `-round11.md`; **[2026-08-29]** 단위 넷 전부 구현 완료 — `ROADMAP.md` M2 -체크박스 전부 `[x]`, 단위 3·4 끝 절차 완료; **[2026-08-31]** 단위 2 `/code-review`와 -§4 배치 회신 **전량 종결**(열린 문항 0·코드 마커 0) — 남은 마무리(파일명 변경, -M2 종료 보고)는 `.claude/todos.md` 00번이 소스). **⚠️ [2026-08-24] M2와 M3의 +**⭐ [2026-08-31 기준] M0(스파이크 검증)/M1(스캐폴딩)/M2(반응형 코어 — +Source/State/Store)까지 완료, 다음은 M3(디스패치 엔진)** — M2는 자율 구현 +구간(규약 `.claude/qa-request/m2-implementation-round11-brief.md`, 발견·배치 +문항 `-round11.md`)으로 돌아 2026-08-28 착수~08-31 종결: 단위 넷 구현·감사· +리뷰·탐사 완료, `ROADMAP.md` M2 체크박스 전부 `[x]`, §4 문항·코드 마커 0. +**M3 착수 전에 새 자율 규약 문항을 사용자와 정할 것**(`.claude/todos.md` +00번이 소스). **⚠️ [2026-08-24] M2와 M3의 번호·순서가 맞바뀌었다** — 예전엔 M2=디스패치, M3=반응형이었는데 의존이 한 방향(디스패치 → 반응형)이라 반응형을 먼저 짓기로 확정했다. 그래서 **2026-08-24 이전에 쓰인 `session/`·`archive/`·`qa-request/` 문서의 diff --git a/HUMAN_TODO.md b/HUMAN_TODO.md index 82a2901..d135d9b 100644 --- a/HUMAN_TODO.md +++ b/HUMAN_TODO.md @@ -57,7 +57,7 @@ git.qwreey.moe에 제한된 계정 생성). 로컬 git 저장소는 이미 초 ## 2. ~~자율 작업 루프/스케줄 설정~~ **[해소됨, 2026-08-28]** **사용자가 M2를 세션 안 자율 구현 구간으로 확정**했다 — 규약은 -`.claude/qa-request/pre-implementation-handtrace-round11-brief.md`, 요지는 +`.claude/qa-request/m2-implementation-round11-brief.md`, 요지는 `.claude/conventions.md`의 "M2 자율 구현 규약" 항목. cron/`/schedule`은 안 쓴다 (사용자 개입 지점은 단위가 끝날 때 `-round11.md` §4 표를 배치로 회신하는 것뿐). 아래는 해소 전 원문. diff --git a/ROADMAP.md b/ROADMAP.md index df6b1b6..036325b 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -262,7 +262,7 @@ Luau 코드로 부딪혀본 적 없는 세 가지**를 던지는 코드로 검 > 지켜집니다. > > **⭐ [2026-08-28 착수] M2는 자율 구현 구간으로 돕니다** — 규약(세 갈래 분류, -> 단위 넷, 관여 시점)은 `.claude/qa-request/pre-implementation-handtrace-round11-brief.md`가 +> 단위 넷, 관여 시점)은 `.claude/qa-request/m2-implementation-round11-brief.md`가 > 소스, 발견은 `-round11.md`. 단위 순서는 이 문서의 체크박스 순서 그대로이되 > **`H-97`의 mock 생명주기 4종은 첫 단위(공통 기반)로 당겨** 짠다 — 그게 없으면 > 두 번째 단위부터 전파 루프 테스트가 안 돈다. diff --git a/quad-base/src/Brand.luau b/quad-base/src/Brand.luau index c716d0f..a85ef42 100644 --- a/quad-base/src/Brand.luau +++ b/quad-base/src/Brand.luau @@ -10,7 +10,7 @@ `archive/brand-shared-registry-reversed.md`). Every brand instance lives in this leaf file (M2 first-unit plan, - `qa-request/pre-implementation-handtrace-round11-brief.md` §6): `EpochBrand` + `qa-request/m2-implementation-round11-brief.md` §6): `EpochBrand` is shared by `Source`/`Ref`/`GateNode`, so keeping the instances per type module would force a circular require. Each *type* still registers only into its own brand at its own construction sites; subtype relations are