quad/.claude/archive
qwreey 56f8269236
design: M2/M3 마일스톤 순서 교체 — 반응형 코어를 먼저, 디스패치를 그 위에
`question.md`에 열려 있던 마지막 항목(마일스톤 경계)을 사용자가
**(a) 순서 교체**로 닫았다 — 이제 **M2 = 반응형 코어(Source/State/Store),
M3 = 디스패치 엔진**이다. 결정과 기각된 선택지는
`archive/question-resolved.md`의 "마일스톤 경계" 절, 경위와 시행착오는
`session/2026-08-24-02-milestone-order-swap.md`.

## 왜 (a)인가

의존이 양방향처럼 보였지만 실제로는 한 방향이었다 — 디스패치→반응형은
*본체* 의존(`setLength`가 `State<number>`를, `setOffsetSource`가
`Source<number>`를 받고 `recompute`가 `offset:Set()`을 부름)이라 우회
불가고, 반대는 *등록 표면* 의존(핸들러 셋)이라 미루면 그만이다. 옛
순서로는 디스패치 마일스톤의 `mock 대상 테스트` 체크박스조차 State 없이
불가능했고, 반응형 코어는 순수 Lua라 `luau`만으로 단독 테스트가 된다.
(b) 분할은 기존 `M2` 참조 전부를 "M2a인가 M2b인가"로 만들어 오히려 비싸고,
(c) 유지는 "순서의 소스는 `ROADMAP.md`"라는 원칙을 스스로 무효화한다.

## 그냥 맞바꾸기로는 안 끝났다

- **`Brand`/`Relate`/`LifetimeHandle`(인터페이스)이 M2 앞머리
  `### 공통 기반` 절로** — 반응형이 이 셋을 먼저 요구한다(`Source`가
  `SourceBrand`+`EpochBrand`에 등록되고, State 전파 루프가 매 발화마다
  `canExecute`를 부르며, 그 판정이 `Relate` 위에 얹힌다). 셋 다 State-free
  이자 dispatch-free라 어느 쪽에도 안 걸린다.
- **2026-08-22에 디스패치로 앞당겼던 `EpochMap`/`GateNode`/`Blocker`가
  M2로 복귀** — 앞당길 이유 자체가 순서 교체로 사라졌다. "게이팅 먼저"는
  그대로 지켜진다(게이팅이 디스패치보다 먼저 지어진다).
- **Observer/Effect 동적 경로 가드 등록과 `ObserverEffectLeafHandler`는
  M3로** — 둘 다 "핸들러를 등록한다"뿐이라 본체와 잘라내기 쉽다. 이것이
  M2가 M3에 개념상 지던 유일한 의존이고, 미뤘으므로 빌드 순서엔 역방향
  간선이 없다.
- **`EpochMap`이 State 본체보다 앞으로**(감사 5라운드 발견) — State가
  `valueEpochMap`/`emitEpochMap` 둘을 컴포지션하므로 옛 배치로는
  `State.luau`를 못 짠다. 문서 자신이 *"아래 `Source.luau`/`State.luau`가
  이걸 전제로"*라 쓰면서 그 둘이 위에 있는 형태로 증거를 남기고 있었다.

## 대가 하나 — 게이트 둘이 "바로 다음"으로 올라왔다

`question.md` 낮은 우선순위에 있던 **중간 State GC 미검증**과
**`store:GetDynamic` 위치**가 원래 반응형(옛 M3)의 게이트였는데, 반응형이
M2가 되면서 착수 직전 항목이 됐다 — 최우선 절로 승격했다. 순수 *설계*
결정 대기는 여전히 0건이다(하나는 실측 미완, 하나는 표면 위치 선택).

## 번호 재부여의 경계

라이브 문서의 `M2`/`M3` 참조 248건은 전량 새 번호로 맞췄다(코퍼스의 참조가
거의 전부 "그 내용이 사는 마일스톤"을 가리켜 기계적 맞교환으로 의미가
보존됨). **`session/`·`archive/`·`qa-request/`는 히스토리라 소급 수정하지
않았다** — 그 문서들의 `M2`/`M3`는 옛 의미(M2=디스패치, M3=반응형)이고,
이 경고를 인덱스 다섯 곳에 박아뒀다.

일괄 치환에 `\bM([23])\b`를 썼다가 Python `\w`가 유니코드라 한글이 붙은
93건(`M2는`/`M2로`)이 안 바뀌는 실수를 냈고, `git show HEAD:<경로>`로
되돌린 뒤 ASCII 경계 lookaround로 재실행했다. 그 부수로 `Relate`/
`LifetimeHandle` 참조들은 구 M2 → 신 M2로 두 번 옮겨져 **번호가 우연히
보존**됐다는 것도 드러났다(치환하면 안 되는 자리 — 감사가 잡아 되돌렸다).

## 검증

`quad-doc-auditor` 루프가 라운드마다 각도를 바꿔 **7라운드에서 새 발견
0건으로 수렴**(10→8→1→1→2→2→0). 가장 값이 큰 건 5라운드(구현 순서
시뮬레이션)로, 위 `EpochMap` 배치 오류를 잡았고 **순서 교체의 전제 자체도
검증**했다(새 M2 전체를 디스패치 심볼로 훑어 "가드 등록 둘 말고는 없음").

**수렴 뒤 사용자가 돌린 `/code-review high`가 5건을 더 잡았고 전부 유효** —
넷이 *"라벨은 치환됐는데 그 라벨을 설명하던 산문이 안 고쳐진"* 종류였고,
그중 하나는 `research/` 안의 **히스토리 블록**이 치환을 맞아 원래 논거가
문장 그대로 거짓이 된 것이었다(소급 수정 제외 대상을 세 폴더로만 잡은 게
샜다). `conventions.md`의 *"`/code-review`는 감사자를 대체하지 않는다"*가
또 재확인됐다. `doc-check.py` ERROR 0.

Co-authored-by: qwreey <me@qwreey.moe>
Claude-Session: https://claude.ai/code/session_01Jjrec9xAS7TZstMx5gi3cm
2026-08-25 00:29:15 +09:00
..
agent-mistake.md refactor(base): bind-system-plan.md 1단계 분할 — Ref/PreRef·이벤트·Brand를 별도 문서로 2026-08-13 18:06:24 +09:00
always-propagate-no-dedup-superseded.md design: Epoch/EpochMap/Brand 전면 승격 + 해소 기록 flatten 2026-08-22 01:27:18 +09:00
batch-rejected.md docs: Blocker/Effect를 base/additional-primitives.md에서 별개 파일로 재분리 2026-08-07 14:45:57 +09:00
bindlifetime-slot-owner-reversed.md qa: 구현 전 QA 5라운드 — 문항지·회신·전량 반영 + 감사 2라운드 2026-08-21 18:19:58 +09:00
bookkeeping-before-physical-reversed.md design: native* 물리 조작 계층 확정 + C-7("부기가 물리보다 먼저") 역전 2026-08-21 20:07:21 +09:00
brand-shared-registry-reversed.md design: Epoch/EpochMap/Brand 전면 승격 + 해소 기록 flatten 2026-08-22 01:27:18 +09:00
canexecute-inst-arg-reversed.md docs: 코퍼스 전체 감사 + canBound/canExecute 재분리, Ref 0-W 해소 2026-08-14 11:03:24 +09:00
checkpoint-handler-pattern-reversed.md design(dispatch): 사각지대 손 트레이싱 라운드 + Dispatch 인덱스 기반 전면 재설계 2026-08-13 14:24:48 +09:00
context-rejected.md fix(base): 코퍼스 전체 stale 마커/모순 감사 및 무효화된 인라인 서사 archive 이전 2026-08-09 16:36:59 +09:00
debug-channel-replicatedstorage-rejected.md fix(base): 코퍼스 전체 stale 마커/모순 감사 및 무효화된 인라인 서사 archive 이전 2026-08-09 16:36:59 +09:00
dispatch-hintvalue-model-reversed.md docs(dispatch): 0-Z/0-A 확정 — Attribute 전용 키+이름 claim, 하강 diff 전면 반영 2026-08-13 23:53:15 +09:00
existing-instance-bind-rejected.md docs(base): bind/store/state 3단계 분할, UI 숏핸드 Tween 지원, existing-instance-bind 기각 2026-08-14 05:10:49 +09:00
invalidate-dedup-propagation-reversed.md docs: Debounce/Throttle 백로그 신설 + "emit은 항상 전파" base 역전 정정 2026-08-14 05:22:06 +09:00
keyed-collection-state-method-rejected.md fix(base): 코퍼스 전체 stale 마커/모순 감사 및 무효화된 인라인 서사 archive 이전 2026-08-09 16:36:59 +09:00
modifier-apply-mutable-rejected.md docs(base): 코퍼스 전체 정합성 감사 반영, 기각된 대안 archive 이관 2026-08-08 11:38:29 +09:00
observer-cleanup-contract-rejected.md fix(base): 코퍼스 전체 stale 마커/모순 감사 및 무효화된 인라인 서사 archive 이전 2026-08-09 16:36:59 +09:00
onchange-per-property-codegen-rejected.md decide(bind-system): OnChange 특수 키 신설 - GetPropertyChangedSignal 바인딩, 제네릭 없이 확정 2026-08-10 01:08:02 +09:00
preref-order-unguaranteed-withdrawn.md docs(base): PreRef/PostRef 계열 안 fire 순서 미보장안 철회 — 배열 index 순서 보장 유지 2026-08-14 05:54:05 +09:00
quad2-try-research-findings-rejected.md fix(base): 코퍼스 전체 stale 마커/모순 감사 및 무효화된 인라인 서사 archive 이전 2026-08-09 16:36:59 +09:00
question-resolved.md design: M2/M3 마일스톤 순서 교체 — 반응형 코어를 먼저, 디스패치를 그 위에 2026-08-25 00:29:15 +09:00
ref-phase-option-reversed.md refactor(base): bind-system-plan.md 1단계 분할 — Ref/PreRef·이벤트·Brand를 별도 문서로 2026-08-13 18:06:24 +09:00
retract-always-fires-reversed.md refactor(base): bind-system-plan.md 1단계 분할 — Ref/PreRef·이벤트·Brand를 별도 문서로 2026-08-13 18:06:24 +09:00
slot-discard-no-portal-reversed.md docs(audit): 7차 감사(직접 검증) — 실측 반영 누락 3건 + Slot 언마운트 미반영 6건 정정, 역전 서사 archive 이전 2026-08-13 17:44:26 +09:00
store-source-proxy-reversed.md docs(base): bind/store/state 3단계 분할, UI 숏핸드 Tween 지원, existing-instance-bind 기각 2026-08-14 05:10:49 +09:00
tag-attribute-load-time-registration-reversed.md qa: 구현 전 QA 1라운드 결과를 base/에 전량 반영 2026-08-18 19:39:03 +09:00
tag-hash-key-model-reversed.md decide(base): Tag를 array-part 값 객체로 재설계, Dispatch 체인+retractUnder로 retract 전파 확정 2026-08-08 03:23:44 +09:00
tween-special-bind-key-reversed.md decide(tween): confirm natural-completion bookkeeping is left as-is, promote to base/ 2026-08-12 12:19:49 +09:00
ui-shorthand-roundsize-dropped.md docs: .claude/ 코퍼스 정리 — reference/ 신설, 승격/기각 분리, 역전 이력 트리밍 2026-08-07 14:39:20 +09:00