- 탐사자(신선한 컨텍스트, round12 brief §5): 코드-문서 한 줄 대조 1:1 확인, spec 미태움 경로 셋(H-223 메시지 내용/H-103 NOOP 잔존/매치 실패 후 재등록) 프로브 실측 전부 계약대로, TODO 마커 0 — 발견은 H-228(①, 🟢) 하나 - H-228: describeHandler가 name 부재 시 "?"를 찍던 것을 문서("없으면 priority만 보인다")에 맞춰 (priority N)만 — 순수 진단 문자열 - round12.md §5 이상 없음 확인 3건은 탐사자가 직접 기록(getHandler nil 반환 정본 정합 / Handler 타입 배치 방향 / table.sort 불안정성은 확정 범위 안) Co-authored-by: qwreey <me@qwreey.moe> Claude-Session: https://claude.ai/code/session_01LF78pXeFGD1ZSVD3ifteYG
168 lines
23 KiB
Markdown
168 lines
23 KiB
Markdown
# M3 구현 **12라운드** — 발견 원문 + 배치 문항지
|
||
|
||
> **이 파일이 무엇인가**: **[2026-08-31 신설]** M3 자율 구현 구간
|
||
> (`m3-implementation-round12-brief.md`가 규약, 같은 날 §0·§6 확정)에서 나온
|
||
> 발견 전부. 실제 코드를 옮기고 돌리다 나온 것이다. 번호는 **`H-212`부터**
|
||
> (11라운드가 `H-211`까지 썼다).
|
||
>
|
||
> **갈래 표기**(규약 §2): **①** 자율로 고침(같은 커밋에서 `base/`+코드) /
|
||
> **②** §4 표에 쌓아 배치 회신 대기 / **③** 즉시 중단·보고. M2 하자는
|
||
> 규약 §0 Q3 (a) — 경미하면 여기 ①, 설계 결정 규모면 그때
|
||
> `m2-implementation-round13`을 새로 연다.
|
||
>
|
||
> **상태의 소스는 이 파일 자신** — 요약 표의 상태 열이 최신.
|
||
|
||
## 요약 표
|
||
|
||
| 번호 | 갈래 | 단위 | 심각도 | 한 줄 | 상태 |
|
||
|---|---|---|---|---|---|
|
||
| `H-212` | ① | 1 | 🟢 | `dispatch-core-plan.md` "Dispatch 체인" 의사코드의 error 세 자리가 한국어·`level` 없음 — 그 절(2026-08-13)보다 늦게 확정된 `architecture.md` error 계약(영어, level 이분, 2026-08-25)이 미반영 | ✅ 반영(`dispatch-core-plan.md` 의사코드 영어+level, `H-212` 문단). **[감사 3라운드 확장]** 같은 문서의 Length/Offset 절 두 자리(`getOffsetAt` 한국어 혼용 / `recompute` 한국어·level 없음)와 주입 op 스텁·가로채기 예시 메시지도 같은 부류라 같이 정정 — 스텁의 `level` 숫자만은 구현 시점(M5/M10) 몫으로 남김(도착지까지의 프레임 수를 문서 시점에 못 셈) |
|
||
| `H-213` | ① | 1 | 🟢 | `HANDLER_PRIORITY_*` 상수의 실제 숫자값을 어느 문서도 안 정했다 — 문서가 정한 건 이름·순서(HIGH > NORMAL > LOW > FALLBACK)·열린 공간(± 오프셋)뿐 | ✅ 구현이 채움: 1000 / 0 / -1000 / -1000000 (밴드 간 ± 오프셋 여유, `Dispatch/init.luau` 주석) |
|
||
| `H-214` | **②** | 1 | 🟡 | `listHandlers`가 "이름/priority를 반환"이고 동률 경고·`quad-debug` 체인 덤프도 핸들러 이름을 원하는데, Handler 계약(3종)엔 `name` 필드가 없다 — 새 필드라 자율 반영 불가 | ✅ **(a) 사용자 확정**(2026-08-31 §4 회신) — 계약에 선택 필드 `name: string?`(진단 전용). `quad-types`·`Dispatch/init.luau`(동률 경고에 이름, `TODO` 마커 제거)·`dispatch-core-plan.md` "핸들러 계약" 절·`spec.dispatch` 11번 반영 |
|
||
| `H-215` | **②** | 1 | 🟢 | 스파이크 `04`(Dispatch 체인 retractFrom) 처분 — `spec.dispatch.luau`가 검증 대상 대부분을 실측했는데 재귀 재발행 경로는 로컬 wrapping 핸들러 근사라 실제 `StoreBind`(M4) 몫이 남는다. 폐기는 `01`처럼 사용자 승인 사안(감사 2라운드 발견) | ✅ **(a) 사용자 확정**(2026-08-31 §4 회신) — 폐기·`done/` 이동, 잔여 몫(실제 `StoreBind` 경유 재발행)은 ROADMAP M4 mock 테스트 항목에 명시. `STATUS.md`·`README.md`·ROADMAP 재검증 대기 절 `[x]` |
|
||
| `H-216` | ① | 1 | 🟢 | `slot-plan.md`의 옛 error 예시 11곳(감사 5라운드가 계수 정정 — 처음 12로 잘못 셌다)이 한국어·`level` 없음(대표: `Slot:Add` 범위 검증, 요소 타입 3종, `dispose` 둘) — `H-212`와 같은 부류로, 그 문서 자신이 별도 절에서 "level 2, 영어" 규칙을 알고 있으면서 예시가 안 따라온 자리. M3 단위 2~4·M6이 옮겨 적기 전에 정리(감사 4라운드 발견) | ✅ 반영(`slot-plan.md` — 사용자 입력 검증은 level 2, `releaseOwner` 소유권 추적 파손만 내부 불변식 level 1) |
|
||
| `H-217` | ① | 1 | 🟢 | 같은 부류 마지막 4곳 — `attribute-plan.md`(그룹 이중 배치)/`debounce-throttle-plan.md`(Leading·Trailing 둘 다 false)/`ref-plan.md`(`PreRef` 재사용 — 파이프라인 의사코드의 `"PreRef instance reused"`와 다른 문구로 갈라져 있던 것도 통일)/`source-state-plan.md`(`bindLifetime` 이중 바인드 — mock 실구현이 던지는 두 분기 메시지의 공통 접두를 딴 **근사**, 실분기는 그 절의 게이트 스케치 몫)가 한국어·`level` 없음(감사 5라운드 전수 스윕) | ✅ 반영 — 전부 영어+level 2. **base/ 코드 리터럴의 한국어 error는 이제 0**(잔여는 산문·옛 모델 인용·주석뿐) |
|
||
| `H-218` | **②** | 1 | 🟡 | (`/code-review high`) `chains` 리스트의 retractor 클로저가 `inst`를 캡처해 **weak 키를 버킷 값이 되참조** — `H-71`이 실측한 "100% 새는" 패턴이라, `dispatch-core-plan.md`의 *"자식을 버리면 결국 GC되지만"* 주장과 그 위에 선 `ui-shorthand-plan.md` `UI-11`의 GC 근거가 **거짓**. 반응형 숏핸드 자식을 파괴/재생성하는 사이클마다 구독·gchold가 누적. 구현은 확정 의사코드에 충실 — 처방(위임 자식 철거 시 `retractFrom` 의무화 여부)이 계약 변경 | 거짓 사실 주장 둘은 정정 완료(`dispatch-core-plan.md`·`ui-shorthand-plan.md`, `H-218` 대기 표시) — **의무화 여부는 §4 대기** |
|
||
| `H-219` | **②** | 1 | 🟡 | (`/code-review high`) 매치 실패 `error(…, 2)`의 도착지가 `drive` 경로(가장 흔한 사용자 경로)에선 사용자 코드가 아니라 quad 내부 프레임 — *"프레임 수가 아니라 도착지가 계약"* 위반. 단 `process`는 핸들러 재귀도 받는 공개 진입점이라 level 하나로 두 경로를 다 못 맞춤 — 증상 확정, 처방(재상승 등)은 새 메커니즘 | ⏳ §4 대기 |
|
||
| `H-220` | ① | 1 | 🟡 | (`/code-review high`) `BRAND_PROBES`가 상위 술어 `isRef`를 `isPreRef`/`isPostRef`보다 앞에 둬 둘이 도달 불능 — `brand-plan.md`의 술어 합성(`isRef` = PreRef∪PostRef∪RefBrand)이 소스라 specific-first가 답 | ✅ 반영 — 순서 재배열 + "손 복사 목록이라 새 브랜드 마일스톤마다 확장" 주석 |
|
||
| `H-221` | ① | 1 | 🟢 | (`/code-review high`) ROADMAP 우선순위 체크박스 주석이 `H-214`를 여전히 "§4 대기·임시 반환"으로 서술 — 같은 커밋에서 종결됐는데 배너가 부정하는 문장을 안 고친 자리 | ✅ 반영 — "(a) 확정으로 닫힘"으로 갱신 |
|
||
| `H-222` | **②** | 1 | 🟢 | (`/code-review high`) `H-212` 문단이 *"제공자 계약 위반 → 2"*라는 **계약 표에 없는 제3 분류**를 확정 서술처럼 `base/`에 넣었다 — 표는 "사용자 입력 검증(2)/내부 불변식(1)" 두 행뿐 | 문단은 "잠정 구현 선택" 표시로 완화 완료 — **표 확장 여부는 §4 대기** |
|
||
| `H-223` | ① | 1 | 🟢 | (`/code-review high`) retractor 생략 error가 위반 핸들러를 특정할 정보(방금 확정된 `name`·priority·k·index)를 하나도 안 실음 — `h.process` 프레임은 이미 반환돼 어떤 level로도 도달 불가라 메시지가 유일한 단서 | ✅ 반영 — `noRetractorMessage(h, k, index)`(코드+의사코드 동기), 동률 경고도 같은 `describeHandler` 사용 |
|
||
| `H-224` | ① | 1 | 🟢 | (`/code-review high`) `H-215`가 M4로 넘긴 잔여 몫 문구가 순서 단언만 요구해, 스파이크 `04`의 존재 이유였던 **효과 수준 검증**(retractor가 실제로 구독을 끊는다)을 떨어뜨림 | ✅ 반영 — ROADMAP M4 mock 항목에 효과 단언(옛 구독 0, stale Set 불전파) 보강 |
|
||
| `H-225` | ① | 1 | 🟢 | (`/code-review high`) 세션 파일이 감사 루프를 5라운드에서 멈춘 것처럼 서술(6라운드 수렴·리뷰 반영 미기재) | ✅ 반영 — 세션 파일·summary에 6라운드 수렴과 리뷰 결과까지 기록 |
|
||
| `H-226` | 기각 | 1 | 🟢 | (`/code-review high`) `process` (A)/(B) 꼬리 병합·(B) 이중 할당 제거·`retractFrom` 재조회 제거 리팩터 제안 | ❌ 반영 안 함 — 확정 의사코드와의 1:1 유지가 우선이고 실측 병목 아님("실제로 관측된 문제에만 구조"). 메시지 drift 우려는 `H-223`의 공용 `noRetractorMessage`로 소멸 |
|
||
| `H-227` | ① | 1 | 🟡 | (`/code-review high`) `local Dispatch = {} :: any`가 생산자 표면을 `quad-types` 선언과 대조 불능으로 만듦 — `H-25`가 막으려던 드리프트가 생산자 쪽에서 무검사 | ✅ 반영 — 로컬 함수 정의 후 `local Dispatch: Dispatch = { … }` 타입 주석 조립(analyze가 표면 검사) |
|
||
| `H-228` | ① | 1 | 🟢 | (탐사자) `describeHandler`가 `name` 부재 시 `"?"`를 이름 자리에 찍는다 — `dispatch-core-plan.md` "핸들러 계약" 절의 `H-214` 블록은 *"없으면 priority만 보인다"*. 실측: `handler priority tie between "?" (priority 5) and "?" (priority 5)` | ✅ 반영 — 코드를 문서에 맞춤: 이름 부재 시 `(priority N)`만 |
|
||
|
||
### `H-212` — base 의사코드 error가 error 계약 이전 표기로 남아 있었다 (①)
|
||
|
||
`process`의 retractor 생략 error 두 자리와 `retractFrom`의 배열 구멍 error가
|
||
한국어 메시지에 `level` 인자 없음 — `base/architecture.md`의 "error 계약 —
|
||
`level` 이분과 메시지 언어" 절(*"`base/`의 예시 메시지도 영어로 쓴다"*)이 그
|
||
의사코드보다 늦게 확정되며 반영이 안 된 자리다. 문서가 이미 답(영어 + level
|
||
이분)을 갖고 있어 ①: retractor 생략은 핸들러(제공자) 계약 위반이라 호출부를
|
||
가리키는 `2`, 배열 구멍은 내부 부기 파손이라 그 자리를 가리키는 `1`.
|
||
`base/`와 코드를 같은 커밋에서 맞췄다.
|
||
|
||
### `H-213` — 우선순위 밴드 상수의 리터럴 값 (①)
|
||
|
||
"우선순위 동률/매치 실패 처리" 절은 상수 **이름 넷**과 순서, "열린 숫자 공간
|
||
위의 편의 상수"(`HANDLER_PRIORITY_HIGH + 1`식 미세 조정)만 정하고 값은 안
|
||
정했다. 구현 선택: `HIGH = 1000` / `NORMAL = 0` / `LOW = -1000` /
|
||
`FALLBACK = -1000000`. 근거 — 밴드 사이 간격이 커서 ± 오프셋이 이웃 밴드를
|
||
침범하기 어렵고, `FALLBACK + 1`(base Fallback을 가로채는 관례 자리)이 `LOW`
|
||
보다 한참 아래에 남는다. 계약 의미(순서·밴드)는 값과 무관해 사용자 결정
|
||
대상이 아니라고 판단 — 다른 값을 원하면 §4 회신에 얹으면 된다.
|
||
|
||
### `H-214` — `listHandlers`/동률 경고가 원하는 핸들러 "이름"이 계약에 없다 (②)
|
||
|
||
`dispatch-core-plan.md` "우선순위 동률/매치 실패 처리" 절: *"`Dispatch.listHandlers()`는
|
||
현재 등록된 전체 핸들러(이름/priority)를 **반환**"*. **[감사 3라운드 정정]**
|
||
"체인 슬롯을 이름으로 바로 덤프" 서술도 **같은 문서**의 "부수 효과 —
|
||
quad-debug에 유리" 항목에 있다(처음엔 `research/debug-tooling-plan.md`로 잘못
|
||
적었었다 — 그 파일엔 그 구절이 없고, 대신 핸들러가 **선택적으로** 구현하는
|
||
`describe` 훅(가칭, 미정)이 이름 관련 전례로 있다). 그런데 핸들러
|
||
계약은 `isHandlable`/`priority`/`process` **3종으로 못 박혀** 있고(같은 문서
|
||
"핸들러 계약" 절: *"다음 3개를 제공하는"*), `name`을 붙이는 건 **새 필드**라
|
||
규약 §2의 ② 갈래다. 기각 이력 grep: Handler에 이름 필드를 검토·기각한 기록
|
||
없음(등록 엔티티 이름 논의(`TagFallbackHandler` 등)는 **변수명** 이야기지
|
||
계약 필드가 아님). 임시 구현: 등록된 핸들러 객체 배열(우선순위순 사본)을
|
||
그대로 반환 — 정의된 정보(priority, 함수들)는 다 담기고 새 개념이 없다.
|
||
동률 경고 print는 priority 값만 찍는다. 코드 마커 `TODO(H-214)` 1곳
|
||
(`Dispatch/init.luau`의 `listHandlers`).
|
||
|
||
**[2026-08-31 종결 — (a) 사용자 확정]** 계약에 선택 필드 `name: string?`
|
||
(진단 전용 — 동률 경고·`listHandlers`·나중의 `quad-debug` 덤프, 스캔·매치
|
||
무영향). 반영: `quad-types` `Handler` 타입 / `Dispatch/init.luau`(동률 경고에
|
||
양쪽 이름, 마커 제거) / `dispatch-core-plan.md` "핸들러 계약" 절 신설 항목 /
|
||
`spec.dispatch` 11번(이름 왕복·부재 시 nil). 코드 마커 0.
|
||
|
||
### `H-228` — 진단 라벨의 이름 부재 표기가 문서와 다르다 (①, 탐사자)
|
||
|
||
`Dispatch/init.luau`의 `describeHandler(h)`는 `` `"{h.name or "?"}" (priority {h.priority})` ``
|
||
— `name`이 없으면 `"?"`라는 자리표시자를 이름처럼 찍는다. 그런데
|
||
`dispatch-core-plan.md` "핸들러 계약" 절의 `H-214` 확정 블록은 **"없으면
|
||
priority만 보인다"** — 문서가 이미 답을 가진 자리라 ①이다(동률 경고와
|
||
`H-223`의 retractor 생략 메시지 양쪽이 이 라벨을 쓴다). 실측(무이름 동률
|
||
경고, 탐사자 프로브):
|
||
|
||
```
|
||
quad.Dispatch: handler priority tie between "?" (priority 5) and "?" (priority 5) — ties have no defined order; offset from a HANDLER_PRIORITY_* band
|
||
```
|
||
|
||
수정은 메인 세션 몫(탐사자는 round12.md만 편집) — 코드가 문서를 따라
|
||
이름 부분을 생략하든(`(priority 5)`만), 문서에 자리표시자 표기를 명시하든
|
||
어느 쪽이든 한 줄이다. 순수 진단 문자열이라 계약·부기 영향 없음.
|
||
|
||
## §4 배치 문항지 (사용자가 읽을 유일한 자리)
|
||
|
||
**⭐ [2026-08-31 회신 1]** 사용자: *"배치 문항은 중간확인 완료했어. 전부
|
||
권고안에 동의해. 나중에 천천히 반영해줘"* — `H-214`·`H-215` 둘 다 **권고 (a)
|
||
채택**, 같은 날 반영 완료(각 행 상태 참고). **그 뒤 `/code-review high`가
|
||
문항 셋(`H-218`/`H-219`/`H-222`)을 새로 올렸다 — 아래 표가 회신 대기.**
|
||
|
||
| 번호 | 무엇 | 선택지 | 권고 | 권고 근거 |
|
||
|---|---|---|---|---|
|
||
| `H-214` | `listHandlers`·동률 경고·(나중의) `quad-debug` 덤프가 쓸 핸들러 **이름** — Handler 계약(3종)엔 `name`이 없다 | (a) 계약에 **선택 필드 `name: string?`** 추가 — 있으면 경고·덤프·`listHandlers`가 쓰고 없으면 priority만 / (b) 이름 없이 감 — `listHandlers`는 핸들러 객체 배열만 반환(지금 임시 구현), "이름/priority" 서술을 문서에서 걷어냄 / (c) 다른 방식(별도 등록 인자 `addHandler(h, name)` 등) | **(a)** | `dispatch-core-plan.md` **두 자리**("우선순위 동률/매치 실패 처리"의 `listHandlers` 이름/priority + "부수 효과 — quad-debug에 유리"의 체인 슬롯 이름 덤프)가 이미 "이름"을 전제하고(**[감사 3라운드 정정]** 후자를 처음엔 `research/debug-tooling-plan.md`로 잘못 인용 — 거긴 대신 선택적 `describe` 훅(가칭)이 전례), 선택 필드면 기존 3종 계약을 안 깬다. **(b)를 고르면 두 자리 다 걷어야 한다.** (c)는 이름이 핸들러 자신이 아니라 레지스트리에 살게 돼 체인 슬롯 덤프(슬롯엔 handler 객체만 저장)가 역조회를 또 요구함 |
|
||
| `H-218` | **위임 자식 철거 시 `retractFrom(child, prop, 1)`을 계약으로 의무화할지** — chains의 retractor 클로저가 `inst`를 캡처해 자식을 버리는 것만으론 회수 안 됨(`H-71` 패턴, 거짓 GC 주장 둘은 이미 정정). 반응형 숏핸드(`UICorner = state`) 자식 파괴/재생성 사이클마다 구독·gchold 누적 | (a) **항상 의무화** — 위임 핸들러는 자식을 버릴 때 무조건 `retractFrom(child, prop, 1)`(정적 값이면 no-op retractor라 비용 ~0; **`UI-11`의 "필요하지 않다" 결론 일부 역전** — 옛 결정 역전 표시) / (b) 반응형 값이 걸린 자식만 의무(정적은 `UI-11` 유지 — 단 폐기 주체가 값의 반응형 여부를 추적해야) / (c) 다른 방식(chains 구조 변경 등 — 단 리스트 `SetWeak` 전환은 살아있는 체인을 잃는 오답) | **(a)** | 계약이 조건 없이 한 줄이라 어기기 어렵고, 정적 경로 비용이 사실상 0이라 `UI-11`의 실익 논거("불러봐야 하는 일이 없다")와 실충돌이 없다 — 그 논거는 "호출 금지"가 아니라 "요구 안 함"이었고, 새로 드러난 누수가 요구할 이유를 만들었다. (b)는 폐기 주체마다 반응형 추적 부기가 하나 더 생긴다 |
|
||
| `H-219` | 매치 실패 `error`의 **도착지** — `drive` 경로(리터럴 props의 미지원 값, 가장 흔한 사용자 실수)에서 level 2가 사용자 코드가 아니라 quad 내부 프레임을 가리킨다. `process`는 핸들러 재귀도 받는 공개 진입점이라 level 하나로 두 경로를 다 못 맞춤 | (a) **지금 유지 + 한계 명시** — 메시지가 key·typeof·브랜드·provider 안내로 자기설명적이라 위치 없이도 진단 가능. M5에서 `New` 파이프라인이 완성돼 drive 경유 프레임 수가 고정되면 재평가 / (b) `drive`가 매치 실패를 잡아 사용자 호출부 level로 재상승 — 단 `pcall` 금지 계약(예외 안전성)과 긴장, 새 메커니즘 / (c) 다른 방식 | **(a)** | (b)는 `pcall`을 안 쓰기로 한 전 자리 계약과 정면 충돌하고, 지금 잃는 건 위치 접두뿐 메시지 자체는 원인을 다 싣는다. 재평가 시점(M5)이 자연스럽게 온다 |
|
||
| `H-222` | 제공자(핸들러 작성자) 계약 위반 — retractor 생략·매치 실패류 — 의 **`level` 분류**가 `architecture.md` 계약 표(사용자 입력 2 / 내부 불변식 1)에 없다. 지금 코드는 잠정 2 | (a) **표에 세 번째 행 신설** — "제공자 계약 위반 = 2(그 계약을 어긴 호출 구조에 가장 가까운 프레임)" / (b) 표는 안 늘리고 잠정 2 유지(주석만) / (c) 내부 불변식으로 보고 1 | **(a)** | M3 단위 2~4·M5·M10의 provider-facing error 전부가 같은 분류를 반복해서 물을 자리라, 표에 한 줄 넣는 게 자리마다 잠정 표시를 다는 것보다 싸다. (c)는 "quad 자신의 버그"가 아니라 제공자의 버그라 표의 1행 정의와 안 맞다 |
|
||
| `H-215` | 스파이크 `04`(Dispatch 체인 retractFrom, `rewrite-required/`) 처분 — `spec.dispatch.luau`가 체인 깊이·레벨별 힌트·3-인자 `retractFrom`·`SetStrong` 음성 대조군을 이미 실측했으나, 재귀 재발행은 spec-로컬 wrapping 핸들러 **근사**다(실제 `StoreBind`는 M4) | (a) 지금 폐기(`01`처럼 `done/` 이동) — 잔여 몫(실제 `StoreBind` 경유 재발행 경로)은 **M4 StoreBind spec이 진다**고 그 단위 계획에 명시 / (b) M4까지 `rewrite-required/`에 유지(현 ROADMAP 문구 "M3 착수 시 같이 처리"를 "M4에서"로 정정) / (c) 지금 재작성 | **(a)** | 체인 메커니즘 자체는 `spec.dispatch.luau` 12절이 실제 구현에 대고 고정했고(스파이크는 격리 재현이라 오히려 약함), `05`/`15`/`01` 폐기와 같은 근거 구조다. 잔여 몫을 M4 spec 항목으로 옮겨 적으면 잊히지 않는다 |
|
||
|
||
## §5 이상 없음 확인 (탐사자·구현이 확인만 하고 문제 없었던 자리)
|
||
|
||
- **[2026-08-31, 단위 1 구현]** "Dispatch 체인" 절 의사코드를 한 줄씩 옮기며
|
||
대조 — (A)/(B) 분기, (A)의 소비 직후 `NOOP` 교체, (B)의 점유 마커 선행,
|
||
`chains:SetStrong`이 `h.process` 앞, retractor 생략 즉시 error 양쪽,
|
||
`retractFrom` 꼬리 역순·항상 소비·구멍 error, `H-103` 주석(pcall 안 감쌈)
|
||
전부 그대로 — 전사 차이는 `H-212`(error 표기)뿐. `spec.dispatch.luau`
|
||
1~12가 각 계약을 실측(같은 핸들러 두 슬롯 = `State<State<T>>` 유사 구조,
|
||
깊은 체인 (A) 연쇄에서 각 레벨이 자기 힌트를 받는 것 포함).
|
||
- **[2026-08-31]** `F-4-1`의 언어 동작(일반화 `for`가 배열 파트 전체를
|
||
해시보다 먼저, 배열 안은 index 순서) — `spec.drive.luau` 1번이 실측 통과.
|
||
스파이크 `01` 재작성은 이 spec이 상시 회귀로 대체(§6 계획, `STATUS.md`에
|
||
기록).
|
||
- **[2026-08-31]** 매치 실패 메시지의 "브랜드 출력"은 기각된 Brand 역조회
|
||
(`archive/brand-shared-registry-reversed.md`)를 재도입하지 않고 모듈 공개
|
||
술어(`is*`) 프로브로 구현 — 실패 경로에서만 돌고(지연 생성 규칙), 새 표면
|
||
없음.
|
||
- **[2026-08-31]** `H-165`(quad-types에 `export type` 추가 시 pesde shim
|
||
재생성 필요)를 예고대로 밟았고 `pesde install` 재실행으로 해소 —
|
||
`Handler`/`Dispatch`가 shim에 올라옴. 새 발견 아님(문서 그대로).
|
||
- **[2026-08-31, 단위 1 탐사자]** `./scripts/test.sh` 전체 exit 0
|
||
(`luau-analyze` 무출력 클린 포함), `grep -rn "TODO(H-"` 0건, 작업 트리
|
||
클린. `Dispatch/init.luau`를 "Dispatch 체인" 절 의사코드와 재차 한 줄
|
||
대조 — (A)/(B) 분기·`NOOP` 교체/점유 마커·`SetStrong` 선행·retractor 생략
|
||
error 양쪽·`retractFrom` 꼬리 역순/항상 소비/구멍 error(level 1) 전부
|
||
일치, 전사 차이는 `H-228`(진단 라벨 표기) 하나뿐.
|
||
- **[2026-08-31, 단위 1 탐사자] `getHandler`가 매치 실패에 error가 아니라
|
||
`nil`을 돌려주는 건 발견이 아니다** — brief §6 행은 error를 `getHandler`
|
||
괄호 안에 적었지만, 정본인 `dispatch-core-plan.md`의 "`Dispatch.process`/
|
||
`Handler.process` 이름 겹침" 항목이 `getHandler(inst,k,v): Handler?` =
|
||
순수 스캔/부작용 없음, error는 오케스트레이터(`process`)의 일로 이미
|
||
갈라뒀다. 코드·`quad-types`·spec 1번이 전부 정본 쪽이다.
|
||
- **[2026-08-31, 단위 1 탐사자] `Handler` 타입의 정의 위치(quad-types 소유,
|
||
`Dispatch/Handler.luau`는 재수출)는 §6 표기("quad-types … `Handler` 타입
|
||
재수출")와 방향이 반대로 읽히지만 구현 방향이 유일하게 가능한 쪽이다** — quad-types는
|
||
quad-base를 require할 수 없고(의존이 base → types 단방향) `Dispatch`
|
||
타입이 `Handler`를 참조하므로 정의는 types 쪽에만 살 수 있다. 잎 유지
|
||
계약("Dispatch를 되참조하지 않는다")은 그대로 성립.
|
||
- **[2026-08-31, 단위 1 탐사자] spec이 안 태우던 경로 셋을 프로브로 실측,
|
||
전부 계약대로** (스크립트는 스크래치, 남기지 않음): (1) `H-223` —
|
||
retractor 생략 메시지가 name·priority·k·index를 실제로 싣는다
|
||
(`handler "MyLeaf" (priority 7) returned no retractor at key SomeKey,
|
||
index 1`). (2) `H-103` — `h.process`가 던지면 `NOOP` 마커가 남고, 이후
|
||
`retractFrom`은 조용히 소비(에러 없음, 정리 0회)하며 그 뒤 재설치·철거는
|
||
정상(문서가 말한 "부기 무결성 비보장 + 크래시는 아님" 그대로). (3) 매치
|
||
실패 후 같은 `(inst,k)`에 핸들러를 등록하면 정상 동작 — 실패 경로가
|
||
chains에 빈 리스트 하나를 남기지만 의사코드도 같은 순서(list 확보가
|
||
getHandler보다 앞)라 전사 차이 아님.
|
||
- **[2026-08-31, 단위 1 탐사자]** `addHandler`의 `table.sort`는 불안정
|
||
정렬이라 **동률** 핸들러끼리의 스캔 순서가 등록이 추가될 때마다 뒤섞일
|
||
수 있는데, 이는 문서가 이미 확정한 "동률 tiebreak 규칙은 강제하지
|
||
않는다"(우선순위 동률/매치 실패 처리 절) 범위 안이다 — 가드·안정화
|
||
제안 안 함(관측된 문제 없음 원칙).
|
||
|
||
## §6 남은 의심 (발견은 아니지만 다음 라운드가 파볼 자리)
|
||
|
||
(아직 없음)
|