docs: M2 자율 구현 규약 신설 — round11 brief/발견 파일, EpochMap 순서 정정, Void 체크박스, HUMAN_TODO 2번 닫음

- qa-request/pre-implementation-handtrace-round11-brief.md: 세 갈래 분류 /
  단위 넷(공통 기반+H-97 mock 생명주기 → EpochMap → Source/State/Store →
  Observer/Effect → GateNode/Blocker+탑레벨) / 두 층 커밋 게이트 / 탐사자 지시
- 초안 규약의 순서 오류(EpochMap이 Effect 뒤) 정정 — ROADMAP "반응형 본체"가
  EpochMap을 State 본체보다 먼저로 못 박아 둠
- round11.md 골격(번호 H-165부터, §4 배치 표에 "옛 메커니즘 복원?" 열)
- conventions.md 작업 방식에 짧은 포인터 항목, ROADMAP M2 배너 + Void 체크박스
  + Relate.luau가 M1에 이미 있음 표기, HUMAN_TODO 2번 해소, README 색인,
  CLAUDE.md/project-context/todos 머리말 "M2 진행 중"

Co-authored-by: qwreey <me@qwreey.moe>
This commit is contained in:
qwreey 2026-08-28 17:51:30 +09:00
parent 51ffadcd8d
commit f94234aa7c
Signed by: qwreey
GPG key ID: D28DB79297A214BD
9 changed files with 211 additions and 6 deletions

File diff suppressed because one or more lines are too long

View file

@ -374,4 +374,16 @@ haiku, 일반 작업은 sonnet. 특히 소스코드를 많이 읽어야 하는
`upstream`(`github.com/qwreey/quad`, 사용자 본인 소유)에 PR이 merge될 때
GitHub 기여 그래프에 반영되게 하기 위함 — 관련 리모트 정책은 메모리
`git-remote-push-policy` 및 위 `SAFETY.md` 항목 참고.
- **⭐ [2026-08-28 신설] M2 자율 구현 규약 — 본문은
`qa-request/pre-implementation-handtrace-round11-brief.md`가 소스, 여기선
가리키기만.** 사용자 결정(2026-08-28, *"수정하고 너가 진행하자"*)으로 M2는
자율 구간으로 돈다. 요지 셋: (1) 발견은 **세 갈래** — 문서가 이미 답을 가진
`H-nnn`으로 기록하고 `base/`+코드를 같은 커밋에서 자율로 고침 / 새
필드·인자·이름·메커니즘·확정 역전은 코드에 넣지 말고 `round11.md` §4 표에
쌓아 배치 회신(코드엔 `-- TODO(H-nnn)` 마커만) / 짠 코드 상당 부분을 무효화할
규모면 즉시 중단·보고. (2) 단위 넷(공통 기반+mock 생명주기 → `EpochMap`
`Source/State/Store``Observer`/`Effect` → `GateNode`/`Blocker`+탑레벨)이
끝날 때마다 감사 루프 → `/code-review high` → 커밋 → 신선한 탐사자 → 사용자에게
"§4를 보라" 한 줄. (3) 커밋 게이트는 두 층 — 매 커밋 doc-check ERROR 0, 단위
끝 감사 루프. 이걸로 `HUMAN_TODO.md` 2번(자율 루프 설정 여부)은 닫혔다 —
세션 안 자율 구간으로 확정, cron/`/schedule`은 안 쓴다.

View file

@ -11,7 +11,9 @@ Roblox 엔진에서 동작하는 DOMless UI 렌더러 **quad**를 처음부터
길게 잡음.
**[2026-08-24 기준] M0(스파이크 검증)/M1(스캐폴딩) 완료, 다음은 M2(반응형
코어 — Source/State/Store)**(마일스톤이 넘어갈 때 루트 `CLAUDE.md` 머리말도
코어 — Source/State/Store)** — **⭐ [2026-08-28] M2 착수, 자율 구현 구간 진행
중**(규약 `qa-request/pre-implementation-handtrace-round11-brief.md`, 발견
`-round11.md`; 단위 넷 중 첫 단위 = 공통 기반 + `H-97` mock 생명주기)(마일스톤이 넘어갈 때 루트 `CLAUDE.md` 머리말도
같이 고칠 것 — 같은 상태를 두 곳이 서술하고 있음). **⚠️ [2026-08-24] M2와
M3의 번호·순서가 맞바뀌었다** — 열려 있던 마일스톤 순서 문제가 (a) 순서
교체로 닫힌 결과다(경위는 `archive/question-resolved.md`의 "마일스톤 경계"

View file

@ -0,0 +1,125 @@
# M2 자율 구현 규약 — 11라운드 지시서
> **이 파일이 무엇인가**: **[2026-08-28 신설]** M2(반응형 코어) 구현을 자율 구간으로
> 돌리기 위한 규약이자, 단위가 끝날 때마다 띄우는 **11라운드 탐사자**에게 그대로
> 주는 지시서다. 산출물은 `pre-implementation-handtrace-round11.md`(발견 원문 +
> §4 배치 문항지). 9·10라운드 지시서(`-round9-brief.md`/`-round10-brief.md`)와
> 같은 관례이되, **이번 라운드는 종이가 아니라 실제 코드가 감사 도구다**
> 10라운드 지시서가 *"이후로는 M2 구현 자체가 더 나은 감사 도구"*라고 예고한
> 그 자리.
>
> **왜 이 규약인가**: 사용자 결정(2026-08-28) — 별도 에이전트가 초안한
> 규약을 검토해 순서 오류 하나(`EpochMap`이 `Source/State` 뒤에 가 있던 것)와
> 소스 단일화 몇 건을 고친 뒤 채택. 사용자 원문: *"수정하고 너가 진행하자.
> epochmap 순서 하나 고치고 진행할 수 있겠니?"* 원칙은 10라운드와 같다 —
> *"인간을 기다리는거 엄청 비효율이라서 … batch 로 처리될 필요가 있는듯"*
> (`-round10-brief.md`). 발견을 하나씩 물으러 오지 말 것.
>
> `conventions.md`의 "작업 방식"에 짧은 항목이 있고 **본문은 이 파일이 소스**다.
---
## §1 범위와 순서
- **단위(unit)** 넷. 단위 하나가 끝날 때마다 §4 "관여 시점"으로 온다.
1. **공통 기반**`ROADMAP.md`의 "공통 기반 — 반응형보다 먼저" 절 전부:
`Brand.luau` / `Relate.luau`(M1에 이미 커밋됨 — 남은 건
`base/relate-plan.md` 대조 + 테스트) / `LifetimeHandle.luau` 인터페이스 /
`Ref.luau` 최소형(`H-128`) / `Void`(`H-162`). **여기에 `H-97`의 mock 생명주기
4종**(`bindLifetime`/`unbindLifetime`/`canBound`/`canExecute`의 mock 백엔드
구현)을 끼운다 — `ROADMAP.md`엔 M2 꼬리에 있지만 이게 없으면 두 번째 단위부터
"구현 + 테스트 짝" 원칙이 성립하지 않는다(전파 루프가 매 발화마다
`canExecute`를 부른다).
2. **`EpochMap``Source`/`State`/`Store`** — **`EpochMap.luau`가 State 본체보다
먼저다.** `ROADMAP.md` "반응형 본체" 절이 *"`Source.luau`/`State.luau`가 이걸
전제로 짜여야 하므로 `EpochMap.luau`(위 항목)가 State 본체보다 먼저 온다"*로
못 박아 뒀다(`State`가 `valueEpochMap`/`emitEpochMap`을 컴포지션). 초안
규약이 `EpochMap``Effect` 뒤에 뒀던 것이 이 규약이 고친 유일한 순서
오류다.
3. **`Observer``Effect`** — `Effect`는 Observer 뒤(의존).
4. **`GateNode``Blocker`** + `quad-types``Quad` 탑레벨 값 전부(`H-80`) +
**mock 대상 전파 루프 테스트**(`ROADMAP.md` M2 마지막 항목).
단위 안의 순서는 `ROADMAP.md` 체크박스 순서를 따른다.
- **각 모듈은 "`base/` 의사코드를 그대로 옮긴 구현 + 그 절의 계약을 검증하는
테스트"로 짝지어** 진행한다. 테스트는 **`./scripts/test.sh`로만** 돌린다 —
`luau` CLI가 심볼릭 링크를 못 타서 그냥 돌리면 거짓 클린이 난다
(`project-context.md`).
- **코드 배치와 테스트 파일 이름**은 첫 단위 계획(§6)이 정한다 — 이 규약이
아니라 그 계획이 소스.
## §2 세 갈래 — 발견은 이렇게 분류해서 처리한다
1. **자율로 고치고 넘어가는 것**: `base/` 의사코드를 옮기다 드러나는 오류(순서,
빠진 `end`, 이름 불일치, 문서 간 stale), 테스트 실패 중 **"문서가 이미 답을 갖고
있는 것"**.
`H-nnn` 번호를 매겨 `pre-implementation-handtrace-round11.md`에 기록하고
**`base/`와 코드를 같은 커밋에서** 고친다. 묻지 않는다. 번호는 **`H-165`부터**
(10라운드 후속이 `H-164`까지 썼다).
2. **모아서 올리는 것**: 새 필드·인자·이름·표면·메커니즘이 필요해지는 것, 확정을
뒤집어야 하는 것, "이 갈래들이 공유하는 전제"가 흔들리는 것.
**코드에 넣지 말고** `round11.md` §4 표에 **갈래 + 권고 + 권고 근거**로 쌓는다.
권고가 "옛 메커니즘 복원"이면 **그 표시를 단다** — 2026-08-28의 `Refresh` 복원
권고(`H-159`)가 `_rerunRequired`로 뒤집혔듯, 그런 자리는 사용자가 다른 모양을
갖고 있을 가능성이 높다.
막힌 부분은 코드에 **`-- TODO(H-nnn): 한 줄 요지`** 마커 + 문항 번호로 남기고
그 모듈의 나머지를 계속 진행한다. 마커 형식을 이 하나로 고정하는 이유:
`quad-doc-auditor`는 코드를 안 보므로 `grep -rn "TODO(H-" quad-base/src`
잔여를 전수 확인하는 유일한 수단이다.
3. **즉시 멈추고 사용자를 부르는 것**: 2번 중에서 **이미 짠 코드의 상당 부분을
무효화할 규모**의 전제 흔들림 — 그 위에 코드를 더 쌓으면 손해인 경우만. 멈추고
상황을 한 문단으로 보고한다(자율 구간이라 사용자가 즉답할 수 없으니, 보고 자체가
그 세션의 끝이다).
## §3 리뷰·감사 발견의 취급
- `/code-review``quad-doc-auditor`**"새 메커니즘"으로 분류한 발견은 반영하지
말고 2번으로 쌓는다.** 이 코퍼스의 반복 실패 모드(`token`, 전용 에러 문구,
`wasAlive`)가 정확히 "리뷰 제안을 승인된 것처럼 넣은 것"이었다
(`conventions.md`의 *"새 필드·인자·이름·메커니즘은 발견이지 결정이 아니다"*
항목이 소스).
- 반영 전에 (a) 그 책임의 현재 소유자와 (b) 그 모양이 과거에 기각된 적 있는지를
먼저 grep한다 — `base/`의 "검토 후 안 만들기로 한 것"류 목록과 `archive/`.
## §4 관여 시점
- **커밋 게이트는 두 층이다.**
- **매 커밋**: `python3 .claude/tools/doc-check.py` ERROR 0. 1번 갈래는 커밋
단위가 작아 단위 하나에 커밋이 여럿 생기는데, 그 중간 커밋도 이 게이트를 탄다.
- **단위 끝**: 감사 루프(`quad-doc-auditor` **한 턴에 하나**, diff 범위,
**`git stash` 금지**를 프롬프트에 직접 명시, 새 발견 0건까지) → doc-check
ERROR 0 → `/code-review high` → 커밋. 그 뒤 **신선한 컨텍스트의 fable 탐사자
하나**를 이 파일(§5)을 지시서로 띄워 실제 코드를 돌려보고 `round11.md`
발견을 이어 붙이게 한 다음, 사용자에게 **"`round11.md` §4를 보라"고 한
줄로** 알린다. 사용자는 §4 표만 읽고 갈래를 배치로 회신한다.
- 세션이 일단락될 때마다 `session/YYYY-MM-DD-NN-slug.md` 원문을 남기고,
`todos.md` 00번·`project-context.md`·`CLAUDE.md` 머리말을 **"M2 진행 중"**으로
갱신한다(`conventions.md`의 세션 원문 규율 그대로).
- 비용 참고: 단위당 감사 루프 + `/code-review high` + 탐사자 조합은 수십만 토큰이다.
그래서 단위를 넷으로 쪼갰다 — 관여 시점이 촘촘해지고 3번 갈래의 손실도 작아진다.
## §5 탐사자 지시 (단위 끝마다 띄우는 fable 탐사자에게)
당신은 Roblox 엔진용 DOMless UI 렌더러 **quad**의 M2 구현을 감사한다. 저장소
루트가 작업 디렉토리다. 당신은 신선한 컨텍스트에서 시작한다 — 앞선 세션의 가정을
물려받지 않는 것이 당신의 가치다. **`git stash`를 쓰지 말 것**(작업 트리 대조는
`git show HEAD:<경로>` / `git diff HEAD -- <경로>`).
1. 먼저 읽을 것: `CLAUDE.md``.claude/conventions.md`(특히 *"새 필드·인자·이름·
메커니즘은 발견이지 결정이 아니다"*와 *"하나의 무언가가 두 일을 하고 있지
않은지"*) → 이 파일 §1~§3 → `pre-implementation-handtrace-round11.md`(지금까지의
발견, 당신의 번호는 마지막 번호 다음부터).
2. 대상: 이번 단위의 커밋 범위(`git log`로 확인)에 들어온 `quad-base/src/`·
`quad-base/test/`와, 그 코드가 옮겨 적은 `base/` 절.
3. 할 일: (a) **코드를 실제로 돌린다**`./scripts/test.sh` 전체, 그리고 계약
절이 요구하는데 테스트가 없는 경로는 임시 스크립트로 직접 태운다(임시 파일은
`quad-base/test/`에 남기지 말고 발견 본문에 인라인). (b) 코드와 `base/` 절을
**한 줄씩 대조**한다 — 옮기다 바뀐 것, 문서에 없는 분기, 문서엔 있는데 코드에
없는 것. (c) `grep -rn "TODO(H-" quad-base/src`로 남은 마커를 전수 확인한다.
4. 산출물: `round11.md``H-nnn`으로 이어 붙인다. **§2의 세 갈래로 분류해서
적되, 1번 갈래도 직접 고치지 말고 발견으로만 남긴다**(수정은 메인 세션이
한다). 2번 갈래는 §4 표에 갈래 + 권고 + 권고 근거, "옛 메커니즘 복원" 표시.
5. 이상 없다고 확인한 자리도 §5 형식으로 적는다(다음 탐사자가 다시 파지 않게).
## §6 첫 단위(공통 기반) 작업 계획
사용자 확인 뒤 여기에 확정본을 적는다 — **[2026-08-28 기준] 확인 대기.**

View file

@ -0,0 +1,38 @@
# M2 구현 **11라운드** — 발견 원문 + 배치 문항지
> **이 파일이 무엇인가**: **[2026-08-28 신설]** M2 자율 구현 구간
> (`-round11-brief.md`가 규약)에서 나온 발견 전부. 앞 라운드들과 달리 **종이
> 트레이싱이 아니라 실제 코드를 옮기고 돌리다 나온 것**이다. 번호는 `H-165`부터
> (10라운드 후속이 `H-164`까지 썼다).
>
> **갈래 표기**(규약 §2): **①** 자율로 고침(같은 커밋에서 `base/`+코드) /
> **②** §4 표에 쌓아 배치 회신 대기 / **③** 즉시 중단·보고.
>
> **상태의 소스는 이 파일 자신** — 요약 표의 상태 열이 최신.
## 요약 표
| 번호 | 갈래 | 단위 | 심각도 | 한 줄 | 상태 |
|---|---|---|---|---|---|
| — | — | — | — | **[2026-08-28 기준] 아직 발견 없음** | — |
## 상세
(단위별로 `### \`H-nnn\` 🔴/🟡/🟢 — 제목` 절을 이어 붙인다. 각 절엔 (1) 어디서
(파일:줄 / `base/` 절), (2) 무엇이, (3) 문서가 이미 답을 갖고 있는가, (4) 어떻게
처리했는가(①이면 커밋 해시).)
## §4 ⭐ 사용자 결정이 필요한 것 (배치 회신용)
| 문항 | 무엇 | 선택지 | 권고 | 권고 근거 | 옛 메커니즘 복원? |
|---|---|---|---|---|---|
| — | **[2026-08-28 기준] 비어 있음** | — | — | — | — |
코드 쪽 잔여 마커: `grep -rn "TODO(H-" quad-base/src` — 이 표의 문항과 1:1이어야
한다.
## §5 이상 없다고 확인한 것
(탐사자가 실제로 돌려보고 계약대로였던 자리 — 다음 탐사자가 다시 파지 않게.)
## §6 남은 의심 / 못 본 것

View file

@ -5,7 +5,15 @@
(`.claude/question.md`, `luau-test/STATUS.md` 등).
00. **⭐⭐⭐ [2026-08-26] 8라운드까지 전부 처리 완료 — M2 착수 게이트가 0이다.**
00. **⭐⭐⭐ [2026-08-28] M2 착수 — 자율 구현 구간 진행 중.** 규약은
`qa-request/pre-implementation-handtrace-round11-brief.md`(세 갈래 분류 /
단위 넷 / 관여 시점), 발견과 배치 문항은 `-round11.md`(§4 표가 사용자가
읽을 유일한 자리). **진행 상태의 소스는 `ROADMAP.md` M2 체크박스**, 여기서
세지 않는다. 첫 단위 = 공통 기반(`Brand`/`Relate` 대조/`LifetimeHandle`
인터페이스/`Ref` 최소형/`Void`) + `H-97` mock 생명주기 4종.
아래는 착수 전(2026-08-26) 서술:
**[2026-08-26] 8라운드까지 전부 처리 완료 — M2 착수 게이트가 0이다.**
8라운드(`qa-request/pre-implementation-handtrace-round8.md`, 7라운드
반영분을 서로 겹쳐 재트레이싱 + 실측, 3개 패스, 발견 17건
`H-107`~`H-123`)의 결정 문항 Q1~Q10을 사용자와 대화형으로 처리해

View file

@ -2,7 +2,9 @@
Roblox 엔진용 DOMless UI 렌더러 **quad**를 처음부터 다시 짜는 프로젝트.
**[2026-08-24 기준] M0(스파이크 검증)/M1(스캐폴딩)까지 완료, 다음은
M2(반응형 코어 — Source/State/Store)**. **⚠️ [2026-08-24] M2와 M3의
M2(반응형 코어 — Source/State/Store)** — **⭐ [2026-08-28] M2 착수, 자율 구현
구간 진행 중**(규약은 `.claude/qa-request/pre-implementation-handtrace-round11-brief.md`,
발견·배치 문항은 `-round11.md`). **⚠️ [2026-08-24] M2와 M3의
번호·순서가 맞바뀌었다** — 예전엔 M2=디스패치, M3=반응형이었는데 의존이
한 방향(디스패치 → 반응형)이라 반응형을 먼저 짓기로 확정했다. 그래서
**2026-08-24 이전에 쓰인 `session/`·`archive/`·`qa-request/` 문서의

View file

@ -54,7 +54,13 @@ git.qwreey.moe에 제한된 계정 생성). 로컬 git 저장소는 이미 초
커밋까지 해뒀음(원격 없음) — 원격을 추가하고 싶으면 그 계정 정보를 알려줄 것,
그 전까지는 로컬 커밋만 계속 쌓아둠.
## 2. 자율 작업 루프/스케줄 설정
## 2. ~~자율 작업 루프/스케줄 설정~~ **[해소됨, 2026-08-28]**
**사용자가 M2를 세션 안 자율 구현 구간으로 확정**했다 — 규약은
`.claude/qa-request/pre-implementation-handtrace-round11-brief.md`, 요지는
`.claude/conventions.md`의 "M2 자율 구현 규약" 항목. cron/`/schedule`은 안 쓴다
(사용자 개입 지점은 단위가 끝날 때 `-round11.md` §4 표를 배치로 회신하는 것뿐).
아래는 해소 전 원문.
사용자가 잠들어 있는 동안에도 계획된 TODO를 이어서 진행하길 원한다는 요청이 있었음
(`req.md` 참고). 이건 세션을 넘어 지속되는 자동 실행이라 다음 중 하나를 사용자가

View file

@ -260,6 +260,12 @@ Luau 코드로 부딪혀본 적 없는 세 가지**를 던지는 코드로 검
> 디스패치로 옮겼던 **`EpochMap`/`GateNode`/`Blocker`는 되돌아왔습니다** —
> 앞당길 이유 자체가 순서 교체로 사라졌고, "게이팅 먼저"는 그대로
> 지켜집니다.
>
> **⭐ [2026-08-28 착수] M2는 자율 구현 구간으로 돕니다** — 규약(세 갈래 분류,
> 단위 넷, 관여 시점)은 `.claude/qa-request/pre-implementation-handtrace-round11-brief.md`
> 소스, 발견은 `-round11.md`. 단위 순서는 이 문서의 체크박스 순서 그대로이되
> **`H-97`의 mock 생명주기 4종은 첫 단위(공통 기반)로 당겨** 짠다 — 그게 없으면
> 두 번째 단위부터 전파 루프 테스트가 안 돈다.
### 공통 기반 — 반응형보다 먼저 (구 M2, 지금의 M3에서 이동)
@ -297,6 +303,8 @@ Luau 코드로 부딪혀본 적 없는 세 가지**를 던지는 코드로 검
분리로 처음 눈에 띈 잔재를 **[2026-08-24]** 정정한 것) —
`brand-plan.md``Brand` 절, 2026-08-07 여덟 번째 세션 신설)
- [ ] `Relate.luau`(전체가 quad-base, 순수 Lua — `base/relate-plan.md`) —
**[2026-08-28 확인] 파일은 M1 커밋 `205af32`에 이미 있다**(`RunInit`이
쓴다) — 이 체크박스의 남은 일은 `base/relate-plan.md` 대조와 테스트뿐.
`Relate()` 비싱글톤 생성자, `:SetWeak`/`:GetWeak`/`:SetStrong`/`:GetStrong`.
`inst`(첫 인자)는 항상 weak, `StrongMap`/`WeakMap` 서브테이블은 lazy
생성(첫 `Set` 호출 시에만), `WeakMap`은 공유 메타테이블(`{__mode="v"}`)
@ -355,6 +363,10 @@ Luau 코드로 부딪혀본 적 없는 세 가지**를 던지는 코드로 검
**[2026-08-27 `/code-review`]** 아래 `H-80` 탑레벨 목록의 규칙(*"이
마일스톤이 얹는 탑레벨 값 전부"*)대로 **`quad-types``Quad``Ref`
생성자 필드도 여기서** 추가한다 — M8의 `H-25` 체크박스는 이걸로 흡수.
- [ ] **[2026-08-28 `H-162`] `Void`** — 단일 no-op 함수 export. no-op 클로저를
돌려주는 자리는 새 클로저 대신 이것. 아래 `H-80` 탑레벨 목록에만 있고
여기 체크박스가 없어 "개수·목록은 소스 하나" 규약에 어긋나던 것을 M2
착수 규약 커밋에서 신설.
### 반응형 본체