설계 검증 라운드(2026-08-04) 결과 반영
2026-08-03 확정 사항 전체를 AskUserQuestion으로 하나씩 재검증. 대부분 그대로 확인됐으나 State 프리미티브 존재 여부(있어야 함으로 정정), Pipe copy-on-write 후보(폐기, state(state) 조합으로 대체), Slot retract 시 동작(폐기로 확정) 등 실제 정정이 발생 — Store/State/Source 온톨로지가 다음 세션 최우선 열린 설계 스레드로 새로 부상. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
0c9b8584ee
commit
0dbbc3d0b1
9 changed files with 294 additions and 63 deletions
|
|
@ -28,13 +28,13 @@
|
||||||
| `quad-v1-architecture.md` | v1(`initreq/quad`) 내부 동작 스냅샷 — "이 문제를 안 반복하려면"의 기준선 |
|
| `quad-v1-architecture.md` | v1(`initreq/quad`) 내부 동작 스냅샷 — "이 문제를 안 반복하려면"의 기준선 |
|
||||||
| `comparison-fusion-vide.md` | Fusion/Vide 아키텍처 비교 리서치 — 설계 결정 근거 자료 |
|
| `comparison-fusion-vide.md` | Fusion/Vide 아키텍처 비교 리서치 — 설계 결정 근거 자료 |
|
||||||
| `lifecycle-pattern.md` | rbvm의 `Connected`+GC 관용구를 quad-v2가 채택하는 방식 |
|
| `lifecycle-pattern.md` | rbvm의 `Connected`+GC 관용구를 quad-v2가 채택하는 방식 |
|
||||||
| `store-semantics.md` | Store는 부작용 허용이 기본, 별도 State 프리미티브는 안 만듦 |
|
| `store-semantics.md` | Store는 부작용 허용이 기본. State는 Store 위의 조합 가능한 캐시 레이어로 실제로 필요함(2026-08-04 정정) — Store/State/Source 온톨로지는 `research/bind-system-plan.md`에서 진행 중 |
|
||||||
|
|
||||||
## `research/` — 아직 착수 전, 상의 필요
|
## `research/` — 아직 착수 전, 상의 필요
|
||||||
|
|
||||||
| 문서 | 내용 | 우선순위 |
|
| 문서 | 내용 | 우선순위 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `bind-system-plan.md` | pluggable key/value 핸들러 레지스트리 — `process`/`retract` 디스패치 모델, Ref, quad2-try 리서치 결과. 핵심은 확정, 세부 시그니처만 남음 | 최상 — 다른 모든 설계가 이 위에서 조립됨 |
|
| `bind-system-plan.md` | pluggable key/value 핸들러 레지스트리 — `process`/`retract` 디스패치 모델(확정), Ref(확정), quad2-try 리서치 결과. **Store/State/Source 온톨로지는 2026-08-04에 새로 열린 미해결 설계 스레드**(다음 세션 최우선) | 최상 — 다른 모든 설계가 이 위에서 조립됨 |
|
||||||
| `module-lifecycle-plan.md` | 프로바이더 패턴, bind/store 구현 책임 분리 — 확정됨 | 최상 — 확정, 구현 착수 시 API 세부만 조정 |
|
| `module-lifecycle-plan.md` | 프로바이더 패턴, bind/store 구현 책임 분리 — 확정됨 | 최상 — 확정, 구현 착수 시 API 세부만 조정 |
|
||||||
| `slot-plan.md` | 뮤터블 자식 배열, 엄격한 단일 마운트 소유권, 재마운트 시 throw | 상 — bind-system 확정 후 |
|
| `slot-plan.md` | 뮤터블 자식 배열, 엄격한 단일 마운트 소유권, 재마운트 시 throw | 상 — bind-system 확정 후 |
|
||||||
| `tween-plan.md` | 트윈을 Store 밖 특수 bind key로 처리, 기본 오버라이드는 Cancel | 중 — 세부 옵션만 남음 |
|
| `tween-plan.md` | 트윈을 Store 밖 특수 bind key로 처리, 기본 오버라이드는 Cancel | 중 — 세부 옵션만 남음 |
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,9 @@ quad는 이제 "스크립트"가 아니라 **라이브러리**다. DOMless Roblo
|
||||||
별개 라이브러리로 존재해야 함(v1 `lang.lua`의 전역 스코프 버그 등은
|
별개 라이브러리로 존재해야 함(v1 `lang.lua`의 전역 스코프 버그 등은
|
||||||
`base/quad-v1-architecture.md` 참고 — 애초에 반면교사).
|
`base/quad-v1-architecture.md` 참고 — 애초에 반면교사).
|
||||||
11. **커스텀 Signal 클래스 미구현.** 콜백 정도로 이벤트 바인드 뒤에 함수를
|
11. **커스텀 Signal 클래스 미구현.** 콜백 정도로 이벤트 바인드 뒤에 함수를
|
||||||
넣는 것만으로 충분하다고 판단(단, `base/lifecycle-pattern.md`의 rbvm 리서치
|
넣는 것만으로 충분하다고 판단. (이전 초안엔 "rbvm의 Signal이 재사용
|
||||||
결과 rbvm의 커스텀 Signal이 실제로는 재사용 가능해 보여서 상충 — 열린 질문으로
|
가능해 보여 상충한다"는 메모가 있었으나 2026-08-04 검증 라운드에서 최종
|
||||||
`.claude/question.md`에 있음).
|
확정으로 재확인 — 더 이상 열린 질문 아님.)
|
||||||
12. **멀티 타겟(pluggable 백엔드) — 특히 GTK 지원까지 염두.** Roblox 전용 렌더
|
12. **멀티 타겟(pluggable 백엔드) — 특히 GTK 지원까지 염두.** Roblox 전용 렌더
|
||||||
기술(react.lua, Fusion)은 결국 외부 개발자 유인이 없어 발전이 더딜 거라는
|
기술(react.lua, Fusion)은 결국 외부 개발자 유인이 없어 발전이 더딜 거라는
|
||||||
문제의식. 결과적으로 `plug/roblox`, `plug/base` 정도로 나뉠 전망 — base가
|
문제의식. 결과적으로 `plug/roblox`, `plug/base` 정도로 나뉠 전망 — base가
|
||||||
|
|
@ -75,3 +75,11 @@ quad는 이제 "스크립트"가 아니라 **라이브러리**다. DOMless Roblo
|
||||||
바인드 시스템 디스패치, Slot 설계 세부, Tween 플러깅, 모듈 라이프사이클/누가
|
바인드 시스템 디스패치, Slot 설계 세부, Tween 플러깅, 모듈 라이프사이클/누가
|
||||||
Store를 구현하는가, 순수함수 범위, 이미 생성된 인스턴스에 대한 바인드 —
|
Store를 구현하는가, 순수함수 범위, 이미 생성된 인스턴스에 대한 바인드 —
|
||||||
`.claude/research/` 각 문서 참고, 전체 색인은 `.claude/README.md`.
|
`.claude/research/` 각 문서 참고, 전체 색인은 `.claude/README.md`.
|
||||||
|
|
||||||
|
**가장 시급한 미정 사항(2026-08-04부터, 다음 세션 최우선)**: Store/State/
|
||||||
|
Source 온톨로지 — Store는 source(실제 값이 존재하는 단일 지점) 집합체이고,
|
||||||
|
`store "key"`처럼 접근할 때마다 그 source를 감싸는 새 State(자기 고유
|
||||||
|
value 없는 조합 가능한 캐시)를 반환한다는 모델까지는 나왔으나, `:Compute`
|
||||||
|
캐싱/무효화 전략, Luau 타입 시스템에서 커링 호출의 타입 추론 문제 등 세부는
|
||||||
|
전부 열려있음. `research/bind-system-plan.md`의 "Store/State/Source
|
||||||
|
온톨로지" 절, `.claude/question.md`의 "최우선 새 열린 질문" 절 참고.
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,39 @@ GC에 묶이지 않음 — v1이 여기저기서 `PropertyChangedSignal`에 연
|
||||||
저장소), 다른 하나는 "언제까지 실행되어도 되는지"(생명 바인드 + canExecute)를
|
저장소), 다른 하나는 "언제까지 실행되어도 되는지"(생명 바인드 + canExecute)를
|
||||||
다룸. 둘 다 base가 제공하는 범용 유틸로 확정.
|
다룸. 둘 다 base가 제공하는 범용 유틸로 확정.
|
||||||
|
|
||||||
|
## 2026-08-04 검증 라운드에서 보강된 내용
|
||||||
|
|
||||||
|
**`Connected` 체크는 rbvm 패턴을 그대로 베끼는 게 아니라 base가 인터페이스로만
|
||||||
|
내보내는 것.** Roblox는 `RBXScriptConnection`에 이미 `Connected`가 존재하고
|
||||||
|
Destroy 시 모든 커넥션을 즉시 끊어주지만, 다른 엔진에서도 라이프사이클을
|
||||||
|
확인할 수 있어야 하므로 base는 "이 바인드가 아직 유효한가"를 묻는 람다/인터페이스만
|
||||||
|
정의하고, quad-roblox가 그 구현을 Roblox의 실제 `Connected`로 채워넣는다(구현
|
||||||
|
주입 방식은 아래 "base 유틸은 인터페이스, 구현은 백엔드 팩토리" 절 참고). 이게
|
||||||
|
필요한 이유: rbvm처럼 GC 트릭으로 라이프사이클을 연결하면 GC가 즉발이 아니라서
|
||||||
|
중간에 죽은 참조가 남아있을 수 있고, 그 시점에 store에 새 값이 들어오면 죽은
|
||||||
|
대상에 처리를 시도하다 터질 수 있음 — 그래서 처리 직전에 유효성을 확인.
|
||||||
|
|
||||||
|
**`Destroying` 훅은 생각보다 덜 중요할 수 있음.** rbvm의 GC-네이티브 무효화
|
||||||
|
방식(자료구조를 직접 건드리지 않고 네이티브 GC에 후처리를 위임)이 성능상
|
||||||
|
유리해서, `Destroying` 훅에 명시적으로 의존하는 경로는 실제로는 거의 필요
|
||||||
|
없을 가능성이 큼 — 확정된 방향(Destroying 하나로 통일)은 유지하되, 실제
|
||||||
|
구현에서 이 훅을 쓰는 지점이 예상보다 적을 수 있다는 점을 열어둘 것.
|
||||||
|
|
||||||
|
**즉시(eager) 정리 예외 두 가지(작고 유계한 포인터, 네임스페이스 dispose)는
|
||||||
|
quad에는 거의 해당 안 될 가능성이 큼.** rbvm은 이미 존재하는 real DOM 위에
|
||||||
|
가상 계층을 얹는 구조라 "가상 계층이 필요 없어지면 지운다"는 문제가 있지만,
|
||||||
|
quad는 자신이 만든 instance를 항상 끝까지 들고 있어서 이런 종류의 즉시 정리
|
||||||
|
자체가 필요 없을 가능성이 높음 — 실제 구현 단계에서 필요성이 확인되면 그때
|
||||||
|
추가.
|
||||||
|
|
||||||
|
**retract는 Destroy 시점에 필요 없는 이유가 엔진 레벨에서 한 번 더 보강됨.**
|
||||||
|
Roblox 엔진 자체가 Destroy 시 Tag/Attribute/실행 중인 Tween을 전부 알아서
|
||||||
|
정리해준다 — 라이브러리가 따로 처리할 필요가 없음. Roblox 이외의 엔진에서
|
||||||
|
이런 정리가 필요하다면 그건 그 엔진의 `quad-X` 서브패키지가 책임질 문제(base
|
||||||
|
관심사 아님). 사용자가 커스텀 Destroy-time 처리가 필요하면 `[Event
|
||||||
|
"Destroying"]`을 직접 바인드해서 처리하면 되는 구조라, 라이브러리가 강제로
|
||||||
|
제공할 필요도 없음.
|
||||||
|
|
||||||
## 이름: `cleanup` → `retract`
|
## 이름: `cleanup` → `retract`
|
||||||
|
|
||||||
"cleanup"이라는 이름은 부적절하다는 사용자 피드백(완전 소멸 정리로 오인되기
|
"cleanup"이라는 이름은 부적절하다는 사용자 피드백(완전 소멸 정리로 오인되기
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
# Store 의미론 — 부작용 허용, State 프리미티브 없음
|
# Store 의미론 — 부작용 허용, State는 Store 위의 조합 가능한 캐시 레이어
|
||||||
|
|
||||||
**상태**: base — 확정된 설계 결정 두 가지. 원본: `.claude/initreq/raw-userinput.md`
|
**상태**: base — 부작용 허용/Store 문법 부분은 확정. State/Source 온톨로지는
|
||||||
|
2026-08-04 검증 라운드에서 새로 열린 진행 중인 설계 스레드(`research/
|
||||||
|
bind-system-plan.md` 참고). 원본: `.claude/initreq/raw-userinput.md`
|
||||||
"store는 부작용을 허용함" / "state는 어떻게 구현하는가" 절.
|
"store는 부작용을 허용함" / "state는 어떻게 구현하는가" 절.
|
||||||
|
|
||||||
## Store는 부작용을 허용하는 게 기본 디자인
|
## Store는 부작용을 허용하는 게 기본 디자인
|
||||||
|
|
@ -14,16 +16,53 @@
|
||||||
"당연히 부작용"이라는 뜻 — 문서화 시 이 경계를 분명히 할 것 (`research/
|
"당연히 부작용"이라는 뜻 — 문서화 시 이 경계를 분명히 할 것 (`research/
|
||||||
purity-and-effects-plan.md`와 연결됨).
|
purity-and-effects-plan.md`와 연결됨).
|
||||||
|
|
||||||
## 별도 `State` 프리미티브는 만들지 않는다 (기본값)
|
**보강(2026-08-04 검증 라운드): 부작용은 심각도가 다른 두 갈래로 나뉜다.**
|
||||||
|
|
||||||
클래스 자신이 필요한 state가 있으면 그냥 클래스 안에서 `Store`를 만들면 됨 —
|
1. **국소적 부작용** — 입력으로 받았거나 자신이 만들어 소유한 대상에 대한
|
||||||
Store는 부분집합으로 쪼개 전달하는 것도 충분히 가능하다고 보기 때문에, 굳이
|
부작용(예: 렌더 리턴 아래에서 옵저빙해서 자기 slot을 갱신). 이건 편의성이
|
||||||
"단일 값 저장용" State를 별도로 만들 필요성을 못 느낌. 나누고 싶으면 사용자가
|
커서 적극 환영하는 영역.
|
||||||
알아서 나누면 됨(사용자 자유).
|
2. **경계를 넘는 부작용** — globalStore처럼 컴포넌트 바깥의 전역 상태를
|
||||||
|
다루는 경우. 게임 UI 특성상(스킬/주변 환경에 영향받는 UI 등) 완전히
|
||||||
|
막을 수는 없지만, 라이브러리로 재사용하려는 컴포넌트가 이런 부작용을
|
||||||
|
가지면 이식성이 떨어짐(`research/purity-and-effects-plan.md`와 연결).
|
||||||
|
|
||||||
**단서**: 구현하다가 실제로 State가 있는 게 더 편해지는 지점이 나오면 그때
|
**미해결 열린 질문**: state를 옵저빙해서 나온 결과로 slot에 `clear`/`add` 같은
|
||||||
추가할 수 있음 — 지금은 "필요성이 확인 안 됐다"는 판단이지 "절대 안 만든다"는
|
연산을 할 때, 그 시점에 대상 slot이 이미 죽어있으면 어떻게 되는가 — state가
|
||||||
확정이 아님. 구현 라운드에서 이 판단이 바뀌면 이 문서를 갱신할 것.
|
생성되는 지점과 slot이 적용되는 지점이 서로 다른 스코프라, "state 변경이
|
||||||
|
발생했을 때 그 slot이 아직 살아있는지"를 어떻게 연관지어 확인할지 아직 명확한
|
||||||
|
설계가 없음(`isInit=false`일 때는 허용, `isInit=true`이고 생존 확인 함수가
|
||||||
|
거짓이면 불허 정도의 방향은 있으나 미완성). 사용자 본인도 "더 리서치가 필요"
|
||||||
|
하다고 명시적으로 표시 — `research/bind-system-plan.md`의 "Store/State/Source
|
||||||
|
온톨로지" 스레드와 함께 다룰 것.
|
||||||
|
|
||||||
|
## 정정(2026-08-04 검증 라운드): `State` 프리미티브는 실제로 필요하다
|
||||||
|
|
||||||
|
**이전 버전의 이 절("State 프리미티브는 만들지 않는다")은 틀렸음 — 사용자가
|
||||||
|
검증 라운드에서 직접 정정.** 정확한 모델:
|
||||||
|
|
||||||
|
- **Store는 "source 집합체"이자 state를 만들어주는 존재.** 실제 값이 존재하고
|
||||||
|
변경될 수 있는 단일 지점은 source(v1의 "값의 근원"에 해당) — store는 이런
|
||||||
|
source들의 모음.
|
||||||
|
- **State는 source(또는 다른 state)를 받아 캐싱만 하는 존재, 자기 고유의
|
||||||
|
독립적 value 개념이 없다.** 단일 값에 대한 state 생성은 store가 자동으로
|
||||||
|
해주지만, 그 결과를 다시 분기하고 싶으면(하나의 파생 스트림에서 여러
|
||||||
|
소비자가 각자 다른 추가 compute를 얹고 싶은 경우) `state(state)`처럼 기존
|
||||||
|
state의 결과를 받아 새 state를 만드는 조합이 필요.
|
||||||
|
- **store에서 state를 얻는 연산(예: `store "key"`)은 항상 새 state 인스턴스를
|
||||||
|
반환한다** — state 자체가 캐시되어 재사용되는 게 아니라, source만 store에
|
||||||
|
귀속된 유일한 실체이고 그 위의 state는 매번 새로 생성됨.
|
||||||
|
- 이건 quad2-try(폐기된 이전 시도)의 `Pipe` copy-on-write 절충안을 대체하는
|
||||||
|
방향으로 좁혀짐 — 별도 `Pipe` 타입을 만들어 소유권/버전 가드를 넣는 대신
|
||||||
|
State 자체가 "파이핑 결합체"이고 `state(state)`로 분기하면 될 걸로 보임
|
||||||
|
(`Pipe` 후보는 사실상 폐기 쪽으로 기움). 상세는 `research/bind-system-plan.md`의
|
||||||
|
"Store/State/Source 온톨로지" 절 참고 — **아직 완전히 결론난 설계는 아니고,
|
||||||
|
구현 단계에서 더 다뤄야 할 진행 중인 스레드.**
|
||||||
|
|
||||||
|
미해결로 남은 것: `:Compute`의 캐싱/무효화 전략(값이 바뀌었는데 듣는 소비자가
|
||||||
|
없으면 연산을 미루는 dirty-flag 방식 등), Luau 타입 시스템에서 `store "key"`
|
||||||
|
같은 커링 호출이 오버로드 함수 타입으로 `state<T>`를 정확히 추론하기 어려운
|
||||||
|
문제(문자열 리터럴이 as-const로 좁혀지지 않는 문제) — 둘 다 열린 채로
|
||||||
|
`research/bind-system-plan.md`에서 계속 다룰 것.
|
||||||
|
|
||||||
## Store 값 설정 문법 — v1 인체공학 유지 (확정)
|
## Store 값 설정 문법 — v1 인체공학 유지 (확정)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,45 @@
|
||||||
있음. 사용자가 Lua/Roblox 엔진에 대해 깊이 아는 사람이라는 전제로, 우선순위
|
있음. 사용자가 Lua/Roblox 엔진에 대해 깊이 아는 사람이라는 전제로, 우선순위
|
||||||
높은 것부터 정렬.
|
높은 것부터 정렬.
|
||||||
|
|
||||||
|
## 2026-08-04 검증 라운드 완료
|
||||||
|
|
||||||
|
아래 "확정됨" 절 전체(architecture.md 14개 항목, lifecycle-pattern.md,
|
||||||
|
store-semantics.md, bind-system-plan.md, module-lifecycle-plan.md,
|
||||||
|
slot-plan.md, tween-plan.md)를 `AskUserQuestion`으로 하나씩 예/아니오 재검증
|
||||||
|
완료 — 대부분 그대로 확인됐지만, 아래는 검증 과정에서 실제로 문서가 수정된
|
||||||
|
항목:
|
||||||
|
|
||||||
|
- **`State` 프리미티브는 "안 만든다"가 아니라 실제로 필요함** — 정정 완료,
|
||||||
|
`base/store-semantics.md` 참고. **이 결과로 Store/State/Source 온톨로지
|
||||||
|
전체가 새로운 열린 설계 스레드로 떠올랐음** — 아래 "최우선 새 열린 질문"
|
||||||
|
참고.
|
||||||
|
- Slot의 `retract` 동작이 "부모 위임" 잠정안에서 "폐기(옮기지 않음)"로 확정
|
||||||
|
— `research/slot-plan.md`.
|
||||||
|
- quad2-try의 `Pipe` copy-on-write 후보는 사실상 폐기, `state(state)` 조합
|
||||||
|
모델로 대체 — `research/bind-system-plan.md`.
|
||||||
|
- `Connected` 체크/GC 위임/`Destroying` 훅 관련 뉘앙스 보강(엔진별 인터페이스
|
||||||
|
주입, quad는 rbvm보다 즉시정리 필요성이 낮음) — `base/lifecycle-pattern.md`.
|
||||||
|
- base 유틸(per-instance 저장소, 생명 바인드)은 인터페이스만, 실제 구현은
|
||||||
|
`RobloxFactory(BaseModule)`류 백엔드 팩토리가 주입 — `research/
|
||||||
|
bind-system-plan.md`.
|
||||||
|
|
||||||
|
## 최우선 새 열린 질문 (검증 라운드에서 새로 터져나옴)
|
||||||
|
|
||||||
|
- **Store/State/Source 온톨로지 전체** — store는 source 집합체, state는
|
||||||
|
source를 감싸는 조합 가능한 캐시(자기 고유 value 없음), `state(state)`로
|
||||||
|
분기. `:Compute`의 캐싱/무효화 전략(dirty-flag 등), `emit` 필요 여부, Luau
|
||||||
|
타입 시스템에서 `store "key"` 커링 호출의 `state<T>` 추론 문제까지 전부
|
||||||
|
미정 — 다음 세션 최우선 논의 대상. → `research/bind-system-plan.md`의
|
||||||
|
"Store/State/Source 온톨로지" 절.
|
||||||
|
- **부작용이 slot 생존 여부와 어떻게 연관되는가** — state 옵저빙 결과로
|
||||||
|
slot을 조작할 때, 그 시점에 대상 slot이 죽어있으면 어떻게 처리할지 사용자도
|
||||||
|
아직 명확한 답이 없다고 명시. → `base/store-semantics.md`.
|
||||||
|
- **인스턴스 생성/이벤트 네이밍 인체공학** — `Quad "Frame"` 문자열 방식 vs
|
||||||
|
`DI.Frame` 필드 접근 방식(자동완성/타입추론 트레이드오프). → `research/
|
||||||
|
bind-system-plan.md`.
|
||||||
|
- `RobloxFactory` 같은 백엔드 팩토리를 같은 base에 중복 호출했을 때의 가드
|
||||||
|
동작, 모듈 스코핑(`New()`)과의 관계. → `research/bind-system-plan.md`.
|
||||||
|
|
||||||
## 확정됨 (2026-08-03 질의응답 라운드, 더 이상 열려있지 않음)
|
## 확정됨 (2026-08-03 질의응답 라운드, 더 이상 열려있지 않음)
|
||||||
|
|
||||||
- **Store 책임 분리**: base가 `LifetimeHandle` 추상화 + store-bind의 재실행
|
- **Store 책임 분리**: base가 `LifetimeHandle` 추상화 + store-bind의 재실행
|
||||||
|
|
@ -50,8 +89,11 @@
|
||||||
- **OOP 상속/`--&` 커스텀 파서/Slot 스텁은 확인대로 죽은 접근** — 절대 반복
|
- **OOP 상속/`--&` 커스텀 파서/Slot 스텁은 확인대로 죽은 접근** — 절대 반복
|
||||||
금지, Slot은 from-scratch 설계 그대로 진행(재조사 불필요).
|
금지, Slot은 from-scratch 설계 그대로 진행(재조사 불필요).
|
||||||
- **mutate-vs-`fromState` 긴장 관계**: quad2-try의 `Pipe` copy-on-write
|
- **mutate-vs-`fromState` 긴장 관계**: quad2-try의 `Pipe` copy-on-write
|
||||||
절충안(유일한 tip일 때만 뮤테이션, 아니면 복사)이 유력 후보로 좁혀짐 — 단
|
절충안(유일한 tip일 때만 뮤테이션, 아니면 복사)이 한때 유력 후보였으나
|
||||||
소유권/버전 가드를 제대로 설계해야 함(원본은 가드 없이 방치돼 있었음).
|
**2026-08-04 검증 라운드에서 사실상 폐기로 재평가됨** — 별도 `Pipe` 타입
|
||||||
|
대신 State 자체가 파이핑 결합체이고 `state(state)`로 분기하는 쪽이 더
|
||||||
|
간단하다는 판단(위 "최우선 새 열린 질문"의 Store/State/Source 온톨로지
|
||||||
|
절로 흡수됨).
|
||||||
- **`Depend(...)` 액션, `:With` 네이밍**은 이전 시도에서도 지향했던 것과 일치
|
- **`Depend(...)` 액션, `:With` 네이밍**은 이전 시도에서도 지향했던 것과 일치
|
||||||
— 그대로 채택. → `research/bind-system-plan.md`
|
— 그대로 채택. → `research/bind-system-plan.md`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,13 @@ src/schema/union.luau:48-68`) — 에러 메시지는 즉시 문자열로 만들
|
||||||
그 인스턴스에 적용하도록 돕는 역할에 가깝다. 그래서 핸들러가 "나중에 생길
|
그 인스턴스에 적용하도록 돕는 역할에 가깝다. 그래서 핸들러가 "나중에 생길
|
||||||
대상"을 비동기로 기다릴 필요 자체가 없음(아래 Ref 절 참고 — Ref는 다른 이유로
|
대상"을 비동기로 기다릴 필요 자체가 없음(아래 Ref 절 참고 — Ref는 다른 이유로
|
||||||
존재).
|
존재).
|
||||||
|
- **보강(2026-08-04)**: `inst`가 항상 살아있는 엔진 객체(Roblox Instance)일
|
||||||
|
필요는 없음 — 특정 백엔드에서 실제 엔진 객체 생성/바인딩 비용이 비싸면
|
||||||
|
(예: 웹 DOM) 중간 표현으로 평범한 테이블을 만들고 나중에 그 테이블을
|
||||||
|
렌더링하는 것도 가능. 이건 core(base)가 신경 쓸 일이 아니라 각 최종
|
||||||
|
엔드포인트 백엔드(`quad-roblox`/`quad-web` 등)가 알아서 결정할 문제 —
|
||||||
|
base 인터페이스는 "무언가를 inst로 받아 process/retract한다"는 계약만
|
||||||
|
지키면 됨, 그 inst의 실체가 뭔지는 백엔드 재량.
|
||||||
- `process(inst, k, v)` — 우선순위 순으로 등록된 핸들러를 스캔, `isHandlable(k,v)`를
|
- `process(inst, k, v)` — 우선순위 순으로 등록된 핸들러를 스캔, `isHandlable(k,v)`를
|
||||||
만족하는 최상위 핸들러가 실제 처리를 담당.
|
만족하는 최상위 핸들러가 실제 처리를 담당.
|
||||||
- 예시: Tween의 store-bind 핸들러는 **`k`는 무엇이든 받고 `v`가 Store인 경우를
|
- 예시: Tween의 store-bind 핸들러는 **`k`는 무엇이든 받고 `v`가 Store인 경우를
|
||||||
|
|
@ -181,6 +188,52 @@ read ...`처럼, State끼리 자유롭게 합성/파이핑 가능한 것이 최
|
||||||
같은 축의 문제 — 옵션 2가 그 원칙과 더 잘 맞아 보이지만, 실현 가능성 자체가
|
같은 축의 문제 — 옵션 2가 그 원칙과 더 잘 맞아 보이지만, 실현 가능성 자체가
|
||||||
아직 검증 안 됨.
|
아직 검증 안 됨.
|
||||||
|
|
||||||
|
## Store/State/Source 온톨로지 — 진행 중인 설계 스레드 (2026-08-04 검증 라운드에서 새로 열림)
|
||||||
|
|
||||||
|
**이 절은 아직 결론난 설계가 아니다** — 검증 라운드 중 사용자가 실시간으로
|
||||||
|
설계를 전개하며 나온 내용을 그대로 기록. 다음 세션에서 이어서 다룰 것.
|
||||||
|
`base/store-semantics.md`의 "State 프리미티브는 실제로 필요하다" 정정과
|
||||||
|
직결됨.
|
||||||
|
|
||||||
|
**핵심 온톨로지**:
|
||||||
|
- **Source** — 실제 값이 존재하고 변경될 수 있는 단일 지점(v1의 "값의 근원").
|
||||||
|
- **Store** — source들의 집합체. `store.a`/`store "a"`처럼 키로 접근하면
|
||||||
|
그 source를 감싼 **새 State**를 매번 만들어 반환(state가 store에 캐시되어
|
||||||
|
재사용되는 게 아님 — source만 store에 귀속된 유일한 실체).
|
||||||
|
- **State** — source(또는 다른 state)의 결과를 캐싱만 하는 존재, 자기 고유의
|
||||||
|
독립적 value 개념이 없음. `state(state)`로 기존 state의 결과를 받아 새
|
||||||
|
state를 만들어 분기 가능 — 이게 사실상 Unix 파이프 영감의 "State끼리
|
||||||
|
합성 가능"이라는 원래 목표를 구현하는 방식.
|
||||||
|
- `:With(...)`/`:Compute(fn)`은 실제로는 state 위의 연산 —
|
||||||
|
`store "key1":With(store "key2"):Compute(function(key1) return key1 +
|
||||||
|
store.key2.value end)`처럼, with한 값을 fn이 클로저로 직접 읽는 모양.
|
||||||
|
|
||||||
|
**미해결 세부 사항**:
|
||||||
|
- **`:Compute` 캐싱/무효화 전략** — 매번 새로 계산할지, 캐싱해두고 무효화
|
||||||
|
플래그로 관리할지 미정. 후보: 값이 바뀌었는데 듣는 소비자가 없으면 연산은
|
||||||
|
미루고 `invalid=true`만 세워두고, 필요해질 때(듣는 사람이 생기거나 값을
|
||||||
|
읽을 때) 실제로 연산하고 `true`→캐싱 후 `false`로 되돌리는 dirty-flag 방식.
|
||||||
|
"store가 state를 **만드느냐** 아니면 **저장하느냐**"의 문제와 직결 —
|
||||||
|
사용자 판단은 "만든다" 쪽(저장한다고 하면 한 곳에서 `:Compute`를 붙이면
|
||||||
|
다른 소비자도 전부 그 compute된 값을 읽게 되어버리는 오염 문제 발생).
|
||||||
|
- **`emit` 필요 여부** — store가 값 변경 시 관련된 모든 state에 emit해야
|
||||||
|
하는 구조가 맞는지 확신은 없지만, 그 외의 방법이 안 보인다는 게 사용자
|
||||||
|
현재 판단. `state(from) / state() -> (state, setState)` 같은 팩토리
|
||||||
|
모양도 후보로 언급됨(React의 `useState`류 페어 반환과 유사).
|
||||||
|
- **Luau 타입 시스템 제약** — `store "key"` 같은 커링 호출로 `state<T>`의
|
||||||
|
`T`를 정확히 추론하려면 오버로드 함수 타입(`(("a") -> number) | (("b")
|
||||||
|
-> boolean)`)이 필요한데, Luau는 문자열 리터럴 인자를 자동으로 `as const`
|
||||||
|
취급하지 않아서 타입이 좁혀지지 않는 문제가 있음. `store.states.a`처럼
|
||||||
|
필드 접근으로 우회하거나, `store.a`가 바로 state를 반환하고
|
||||||
|
`state.value = x`로 설정 가능하게 하는 대안도 검토됐으나, 후자는 "다른
|
||||||
|
source로부터 파생된 state에 value를 직접 설정하면 안 된다"는 문제와
|
||||||
|
충돌(store가 실제 값을 담는 유일한 주체여야 함). `state<Mapped>`(compute
|
||||||
|
결과)가 제대로 바인딩 안 됐을 때 생기는 타입 문제는 일단 UB로 두기로 함.
|
||||||
|
- **`Pipe`(quad2-try 후보)는 사실상 폐기 쪽으로 기움** — 별도 `Pipe` 타입에
|
||||||
|
소유권/버전 가드를 넣어 재설계하는 대신, State 자체를 파이핑 결합체로
|
||||||
|
보고 `state(state)`로 분기하는 쪽이 엔지니어링상 더 쉬워 보인다는 게
|
||||||
|
사용자의 최신 판단(2026-08-03 라운드의 "Pipe COW가 유력 후보"보다 우선함).
|
||||||
|
|
||||||
## quad2-try 리서치 결과 (완료) — 이전 시도에서 뭘 가져오고 뭘 버릴지
|
## quad2-try 리서치 결과 (완료) — 이전 시도에서 뭘 가져오고 뭘 버릴지
|
||||||
|
|
||||||
`.claude/initreq/quad2-try/out/quad-core`에 정확히 이 문제(Unix 파이프 영감의
|
`.claude/initreq/quad2-try/out/quad-core`에 정확히 이 문제(Unix 파이프 영감의
|
||||||
|
|
@ -235,9 +288,11 @@ State/스트림)를 다뤘던 이전 시도가 있었음. 조사 결과 요약:
|
||||||
이번 라운드에서 다시 요청한 것과 정확히 일치** — 우연이 아니라 원래
|
이번 라운드에서 다시 요청한 것과 정확히 일치** — 우연이 아니라 원래
|
||||||
지향점이었던 것으로 보임, `:With` 이름 채택에 힘을 실어줌.
|
지향점이었던 것으로 보임, `:With` 이름 채택에 힘을 실어줌.
|
||||||
|
|
||||||
**종합**: 이 프로토타입은 사실상 죽은 시도가 맞음(확인됨) — 다만 Pipe의
|
**종합**: 이 프로토타입은 사실상 죽은 시도가 맞음(확인됨) — `Depend`/`:With`
|
||||||
copy-on-write 절충안과 `Depend`/`:With` 네이밍은 quad-v2 설계에 그대로
|
네이밍은 quad-v2 설계에 그대로 살려볼 가치가 있는 아이디어로 남지만, **Pipe의
|
||||||
살려볼 가치가 있는 아이디어로 남김.
|
copy-on-write 절충안은 2026-08-04 검증 라운드에서 사실상 폐기 쪽으로 재평가됨**
|
||||||
|
(위 "Store/State/Source 온톨로지" 절 참고 — State 자체가 파이핑 결합체이고
|
||||||
|
`state(state)`로 분기하는 쪽이 더 간단하다는 사용자의 최신 판단).
|
||||||
|
|
||||||
## 확정된 것 (더 이상 열린 질문 아님)
|
## 확정된 것 (더 이상 열린 질문 아님)
|
||||||
|
|
||||||
|
|
@ -249,15 +304,39 @@ copy-on-write 절충안과 `Depend`/`:With` 네이밍은 quad-v2 설계에 그
|
||||||
- **Ref**: 도입 확정(위 절 참고), 용도는 "id 기반 조회 대체"가 아니라 "외부
|
- **Ref**: 도입 확정(위 절 참고), 용도는 "id 기반 조회 대체"가 아니라 "외부
|
||||||
관리 instance를 점진적으로 다루기 위한 직접 참조 획득".
|
관리 instance를 점진적으로 다루기 위한 직접 참조 획득".
|
||||||
|
|
||||||
|
## base 유틸은 인터페이스, 실제 구현은 백엔드 팩토리가 주입 (2026-08-04 보강)
|
||||||
|
|
||||||
|
`base/lifecycle-pattern.md`가 말하는 "범용 유틸"(per-instance 상태 저장소,
|
||||||
|
생명 바인드 유틸)은 base가 직접 구현하는 게 아니라 **인터페이스만 정의** —
|
||||||
|
`inst`는 base 입장에선 `any`일 수 있음(다른 엔진일 수도 있으므로). 실제
|
||||||
|
구현은 `RobloxFactory(BaseModule)` 같은 팩토리 함수가 `BaseModule`을
|
||||||
|
뮤테이션해서 그 안에 실 구현체(`canExecute` 등)를 채워넣는 방식 — 사용자는
|
||||||
|
`quad-base`/`quad-roblox`를 각각 import해서 `const quad =
|
||||||
|
RobloxFactory(QuadBase)` 세 줄 정도로 직접 조립하면 됨(별도 번들 `quad`
|
||||||
|
패키지로 재수출할 필요 없음, 필요하면 만들어도 됨).
|
||||||
|
|
||||||
|
**열린 질문**: `RobloxFactory`를 같은 `BaseModule`에 여러 번 호출하면 어떻게
|
||||||
|
되어야 하는가 — 이미 초기화됐으면 무시(rbvm의 `InitNamespace`류 가드와
|
||||||
|
유사하되, "라이브러리마다 수동 init" 패턴과는 다름)하는 쪽으로 기울어짐.
|
||||||
|
서로 다른 두 곳에서 같은 `base`를 require해서 `RobloxFactory`와
|
||||||
|
`AnotherFactory`(가상의 예)를 각각 실행하는 경우처럼 충돌 가능성이 있는
|
||||||
|
시나리오가 향후 모듈 스코핑(`New()`, `base/architecture.md` 13번) 논의를
|
||||||
|
다시 촉발할 수 있음 — 지금은 열어만 둠.
|
||||||
|
|
||||||
|
## 인스턴스 생성 / 이벤트 네이밍 인체공학 (2026-08-04 검증 라운드에서 새로 나온 열린 질문)
|
||||||
|
|
||||||
|
`Quad "Frame"`처럼 문자열로 인스턴스 종류를 지정하는 방식은 타입 추론이
|
||||||
|
어려움(위 온톨로지 절의 Luau 오버로드 문제와 같은 원인). PA님 DI 스타일은
|
||||||
|
`DI.Frame`/`DI.TextLabel`처럼 필드 접근으로 만들어서 자동완성이 자연스럽게
|
||||||
|
됨 — 목록에 없는 타입은 `DI.New<<Frame>> "Frame"`류로 폴백. 이벤트도
|
||||||
|
`Event ""` 대신 `On...`류 이름으로 필드 접근하면 타입/자동완성이 쉬워질 수
|
||||||
|
있음. 아직 방향 결정 안 됨 — 다음 세션에서 다룰 것.
|
||||||
|
|
||||||
## 남은 열린 질문 (`.claude/question.md`에도 취합)
|
## 남은 열린 질문 (`.claude/question.md`에도 취합)
|
||||||
|
|
||||||
- **`:Compute`가 `with`한 값을 정확히 어떻게 읽는가** — 클로저로 원본 store/
|
- **`:Compute`가 `with`한 값을 정확히 어떻게 읽는가** — 클로저로 직접 캡처하는
|
||||||
register를 직접 캡처하는 것인지, `:Compute`가 특수한 접근자를 몸체 함수에
|
방향은 확정(위 온톨로지 절), 캐싱/무효화 전략(dirty-flag 등)과 `emit` 필요
|
||||||
넘겨주는 것인지 구체 시그니처 미정.
|
여부는 아직 미정.
|
||||||
- **mutate-in-place vs `fromState` 긴장 관계** — quad2-try의 copy-on-write
|
|
||||||
절충안(위 절)이 유력한 후보로 좁혀짐. 실제 구현 시 "내가 유일한 tip인가"
|
|
||||||
판단에 제대로 된 소유권/버전 가드를 설계하는 게 핵심 과제 — 원본처럼
|
|
||||||
가드 없이 가면 안 됨.
|
|
||||||
- **`CreatedRef`(가칭)의 정확한 함수/옵션 이름** — children 배열에 아이템으로
|
- **`CreatedRef`(가칭)의 정확한 함수/옵션 이름** — children 배열에 아이템으로
|
||||||
넣는다는 방향과 생성/마운트 두 시점 모두 지원한다는 것은 확정, 정확한 API
|
넣는다는 방향과 생성/마운트 두 시점 모두 지원한다는 것은 확정, 정확한 API
|
||||||
이름만 남음.
|
이름만 남음.
|
||||||
|
|
@ -269,3 +348,5 @@ copy-on-write 절충안과 `Depend`/`:With` 네이밍은 quad-v2 설계에 그
|
||||||
라이프타임도 감싸게 될 텐데, 이중 해제(double-dispose) 방지가 필요한지 확인.
|
라이프타임도 감싸게 될 텐데, 이중 해제(double-dispose) 방지가 필요한지 확인.
|
||||||
단, `base/lifecycle-pattern.md`의 "destroy 시점엔 아무것도 안 함" 원칙상 이중
|
단, `base/lifecycle-pattern.md`의 "destroy 시점엔 아무것도 안 함" 원칙상 이중
|
||||||
해제 자체가 걱정할 필요 없는 개념일 수도 있음 — 재검토 필요.
|
해제 자체가 걱정할 필요 없는 개념일 수도 있음 — 재검토 필요.
|
||||||
|
- `RobloxFactory` 중복 호출/충돌 시나리오, 인스턴스 생성·이벤트 네이밍
|
||||||
|
인체공학 — 위 두 절 참고, 둘 다 새로 열린 질문.
|
||||||
|
|
|
||||||
|
|
@ -84,3 +84,13 @@ bind-system-plan.md`의 "확정된 디스패치 모델" 절이 바로 이 base
|
||||||
노출할지 정도(설계 방향 자체는 더 이상 열려있지 않음).
|
노출할지 정도(설계 방향 자체는 더 이상 열려있지 않음).
|
||||||
- 넘버 바인드/프로바이더 인터페이스의 정확한 함수 시그니처(base가 요구하는
|
- 넘버 바인드/프로바이더 인터페이스의 정확한 함수 시그니처(base가 요구하는
|
||||||
provider 인터페이스 계약)는 아직 미정 — 구현 착수 시 함께 확정.
|
provider 인터페이스 계약)는 아직 미정 — 구현 착수 시 함께 확정.
|
||||||
|
- **네이밍 미정(2026-08-04 보강)**: "프로바이더"라고 불러온 개념을 정확히
|
||||||
|
뭐라고 부를지("provider" vs "processor" vs 그냥 "plug") 아직 안 정함 —
|
||||||
|
실제로는 `isHandlable`로 받을지 말지 결정하고 우선순위대로 스캔되는
|
||||||
|
pluggable 참가자라는 점은 확정, 이름만 미정.
|
||||||
|
- base 유틸(per-instance 상태 저장소, 생명 바인드 유틸)이 인터페이스만 두고
|
||||||
|
실제 구현은 백엔드 팩토리(`RobloxFactory(BaseModule)`류)가 뮤테이션으로
|
||||||
|
주입한다는 패턴이 확정됨 — 상세는 `research/bind-system-plan.md`의 "base
|
||||||
|
유틸은 인터페이스, 실제 구현은 백엔드 팩토리가 주입" 절 참고. 이 패턴을
|
||||||
|
중복 호출했을 때의 가드 동작(멱등 처리)과 모듈 스코핑(`New()`)의 관계는
|
||||||
|
여전히 열려있음.
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,13 @@ Slot 핸들러 자신이 감시 중인 값(배열/스토어)이 바뀔 때 child
|
||||||
Destroy 시점엔 `retract`가 호출되지 않는다는 원칙(`base/lifecycle-pattern.md`)도
|
Destroy 시점엔 `retract`가 호출되지 않는다는 원칙(`base/lifecycle-pattern.md`)도
|
||||||
동일하게 적용.
|
동일하게 적용.
|
||||||
|
|
||||||
|
**확정(2026-08-04 검증 라운드): retract되는 slot은 옮겨지지 않고 그냥 폐기된다.**
|
||||||
|
Slot은 바인딩되는 순간 그 안의 요소를 전부 own해버리는 데이터형 — 새 slot
|
||||||
|
상태로 교체될 때 이전 slot의 내용을 다른 곳으로 옮기는 경로는 없음, 그냥
|
||||||
|
버림. React의 portal(`<></>`)류로 나중에 옮길 수 있게 하는 것도 검토됐으나
|
||||||
|
**이번 마일스톤에서는 오버엔지니어링으로 판단, 하지 않음** — 필요성이 명확해지면
|
||||||
|
그때 별도로 다시 논의.
|
||||||
|
|
||||||
## 자식으로 넘기는 클래스 스토어
|
## 자식으로 넘기는 클래스 스토어
|
||||||
|
|
||||||
자식에게 내려주는 클래스 스토어는 부모 쪽에서 미리 만들어서 내려보내는 게
|
자식에게 내려주는 클래스 스토어는 부모 쪽에서 미리 만들어서 내려보내는 게
|
||||||
|
|
@ -75,7 +82,6 @@ Destroy 시점엔 `retract`가 호출되지 않는다는 원칙(`base/lifecycle-
|
||||||
|
|
||||||
## 열린 질문 (`.claude/question.md`에도 취합)
|
## 열린 질문 (`.claude/question.md`에도 취합)
|
||||||
|
|
||||||
- 재마운트 에러 처리는 확정(throw). 남은 건 Slot 안 요소가 `retract`될 때
|
- 재마운트 에러 처리(throw), retract 시 폐기(옮기지 않음) 둘 다 확정. 남은 건
|
||||||
"부모가 정리 후 재`process`"가 정말 항상 올바른 기본 동작인지, 아니면 slot
|
실제 구현 단계에서 이 "폐기" 동작이 실사용에서 불편하지 않은지 재검증하는
|
||||||
자체가 일부 자기 정리를 해야 하는 케이스가 있는지 — 구현하면서 실제 사례로
|
정도 — 설계 방향 자체는 더 이상 열려있지 않음.
|
||||||
재검증 필요.
|
|
||||||
|
|
|
||||||
76
CLAUDE.md
76
CLAUDE.md
|
|
@ -20,15 +20,21 @@ Roblox 엔진에서 동작하는 DOMless UI 렌더러 **quad**를 처음부터
|
||||||
길게 잡음.
|
길게 잡음.
|
||||||
|
|
||||||
**지금은 설계/계획 단계이고 구현은 아직 시작 전** — 저장소 루트에 실제 소스
|
**지금은 설계/계획 단계이고 구현은 아직 시작 전** — 저장소 루트에 실제 소스
|
||||||
코드(`src/` 등)가 없음. 2026-08-03 여러 질의응답 라운드를 거쳐 핵심 아키텍처
|
코드(`src/` 등)가 없음. 2026-08-03에 확정됐던 핵심 아키텍처 결정들(Store
|
||||||
결정 대부분이 확정됨(Store 책임 분리, `process`/`retract` 디스패치 모델,
|
책임 분리, `process`/`retract` 디스패치 모델, Signal 미채택, Ref 역할, Store
|
||||||
Signal 미채택, Ref 역할, Store 문법 인체공학, 트윈 기본 오버라이드, Slot
|
문법 인체공학, 트윈 기본 오버라이드, Slot 재마운트 에러 처리, 순수성→이식성
|
||||||
재마운트 에러 처리, 순수성→이식성 재정의) — `.claude/question.md`의 "확정됨"
|
재정의 등)은 2026-08-04에 `AskUserQuestion`으로 하나씩 재검증까지 마쳐서
|
||||||
절 참고. 이전에 시도했다 폐기한 v2 재작성 시도(`.claude/initreq/quad2-try`)도
|
확정 상태 — `.claude/question.md`의 "확정됨" 절 참고. 이전에 시도했다 폐기한
|
||||||
리서치 완료 — OOP 상속/커스텀 파서/Slot 스텁은 확인된 죽은 접근이라 반복 금지,
|
v2 재작성 시도(`.claude/initreq/quad2-try`)도 리서치 완료 — OOP 상속/커스텀
|
||||||
`Pipe`의 copy-on-write 절충안은 살려볼 후보. 남은 건 세부 함수 시그니처
|
파서/Slot 스텁은 확인된 죽은 접근이라 반복 금지, `Pipe`의 copy-on-write
|
||||||
(`:Compute`가 의존값을 읽는 방법, `CreatedRef`/`Store.Combine`류 정확한 이름)
|
절충안은 한때 살려볼 후보였으나 **2026-08-04에 사실상 폐기로 재평가**됨(State
|
||||||
정도 — `.claude/question.md`의 "착수하면서 확인" 절 참고.
|
자체가 `state(state)`로 분기하는 쪽으로 대체).
|
||||||
|
|
||||||
|
**지금 유일하게 결론 안 난 핵심 설계 이슈는 Store/State/Source 온톨로지**
|
||||||
|
— 검증 라운드 중 "State 프리미티브는 안 만든다"던 기존 결정이 틀렸다는 게
|
||||||
|
드러나며 새로 열림. `.claude/research/bind-system-plan.md`의 "Store/State/
|
||||||
|
Source 온톨로지" 절, `.claude/question.md`의 "최우선 새 열린 질문" 절 참고 —
|
||||||
|
아래 "지금 할 일" 1번이 다음 세션이 여기서부터 시작해야 함을 명시.
|
||||||
|
|
||||||
## 계획 문서 구조
|
## 계획 문서 구조
|
||||||
|
|
||||||
|
|
@ -74,35 +80,41 @@ Signal 미채택, Ref 역할, Store 문법 인체공학, 트윈 기본 오버라
|
||||||
|
|
||||||
## 지금 할 일 (우선순위순)
|
## 지금 할 일 (우선순위순)
|
||||||
|
|
||||||
1. **[다음 세션 최우선] 확정된 설계 검증 라운드.** 2026-08-03에 여러 라운드에
|
1. **[다음 세션 최우선] Store/State/Source 온톨로지 설계.** 2026-08-04 검증
|
||||||
걸쳐 확정한 아키텍처 결정들(`.claude/question.md`의 "확정됨" 절 전체 —
|
라운드 중 "State 프리미티브는 안 만든다"는 이전 결정이 틀렸다는 게
|
||||||
Store 책임 분리, `process`/`retract` 모델, Ref 역할, Store 문법, `:With`/
|
밝혀지면서 새로 터져나온 핵심 설계 이슈 — Store=source 집합체, State=
|
||||||
`:Compute`, 트윈 기본값, Slot 에러 처리, 순수성→이식성 재정의 등)을 **사용자가
|
source를 감싸는 조합 가능한 캐시(`state(state)`로 분기), `:Compute`
|
||||||
명시적으로 요청한 방식으로 재검증할 것**: 각 결정을 작게 쪼개서 예/아니오로
|
캐싱/무효화 전략, Luau 타입 시스템에서 커링 호출의 `state<T>` 추론 문제
|
||||||
답할 수 있는 질문으로 만들어 `AskUserQuestion`으로 하나씩 확인. 목적은 이
|
등이 전부 미정. `.claude/research/bind-system-plan.md`의 "Store/State/
|
||||||
설계 라운드에서 내가(에이전트가) 잘못 이해했거나 성급히 확정한 부분을
|
Source 온톨로지" 절에 지금까지 나온 내용이 정리되어 있음 — 이어서 설계를
|
||||||
찾아내 프로젝트 전반의 기틀과 정확성을 높이는 것 — 이미 답변받은 걸 다시
|
구체화할 것. `.claude/question.md`의 "최우선 새 열린 질문" 절도 함께 참고.
|
||||||
묻는 게 아니라, "정말 이렇게 이해한 게 맞는지"를 세분화해서 다시 짚는 것.
|
2. 위 온톨로지가 어느 정도 정리되면 `research/bind-system-plan.md`/
|
||||||
`.claude/base/`, `.claude/research/` 각 문서를 훑으며 검증 질문 목록을 먼저
|
|
||||||
만들고, 한 번에 다 던지지 말고 문서/주제 단위로 나눠서 진행할 것.
|
|
||||||
2. 검증 라운드가 끝나면 `research/bind-system-plan.md`/
|
|
||||||
`research/module-lifecycle-plan.md`를 `base/`로 승격하고,
|
`research/module-lifecycle-plan.md`를 `base/`로 승격하고,
|
||||||
`base/architecture.md`에 "구현 착수" 섹션을 추가해 실제 소스 트리 구조
|
`base/architecture.md`에 "구현 착수" 섹션을 추가해 실제 소스 트리 구조
|
||||||
(어느 서브패키지가 뭘 갖는지)를 확정 — 이 시점부터 `qa-request/`/`archive/`
|
(어느 서브패키지가 뭘 갖는지)를 확정 — 이 시점부터 `qa-request/`/`archive/`
|
||||||
폴더가 실제로 쓰이기 시작함.
|
폴더가 실제로 쓰이기 시작함.
|
||||||
3. 남은 세부 시그니처(dependency 값 읽는 방법, `CreatedRef`/`Store.Combine`류
|
3. 남은 세부 시그니처(`CreatedRef` 정확한 이름, 인스턴스 생성/이벤트 네이밍
|
||||||
정확한 이름)는 검증 라운드 중 자연스럽게 같이 확정 가능.
|
인체공학, `RobloxFactory`류 팩토리 중복 호출 가드)는 온톨로지 설계와
|
||||||
4. `research/purity-and-effects-plan.md`, `research/existing-instance-bind-plan.md`는
|
자연스럽게 같이 확정 가능.
|
||||||
|
4. `research/purity-and-effects-plan.md`(특히 "state 옵저빙 결과로 slot을
|
||||||
|
조작할 때 생존 여부 확인" 열린 질문), `research/existing-instance-bind-plan.md`는
|
||||||
급하지 않음 — 스코프 논의만 필요, 구현 착수를 막지 않음.
|
급하지 않음 — 스코프 논의만 필요, 구현 착수를 막지 않음.
|
||||||
5. 자율 작업 루프/스케줄 설정 여부는 사용자 결정 대기 중
|
5. 자율 작업 루프/스케줄 설정 여부는 사용자 결정 대기 중
|
||||||
(`HUMAN_TODO.md` 2번 항목).
|
(`HUMAN_TODO.md` 2번 항목).
|
||||||
|
|
||||||
## 인수인계 메모 (2026-08-03 세션 종료 시점)
|
## 인수인계 메모 (2026-08-04 세션 종료 시점)
|
||||||
|
|
||||||
이 세션에서 `.claude/` 전체 스캐폴드 + 대부분의 핵심 아키텍처 결정을 완료함.
|
2026-08-03에 확정됐다고 표시된 결정 전체(architecture.md 14개 + lifecycle-
|
||||||
사용자가 다음 세션 시작 시 이렇게 요청함: "각 디자인 부분을 작게작게 질문으로
|
pattern/store-semantics/bind-system-plan/module-lifecycle-plan/slot-plan/
|
||||||
만들어서, 이게 맞나요? 예/아니오로 대답할 수 있는 걸 던져가며 검증해보자.
|
tween-plan)를 `AskUserQuestion`으로 하나씩 예/아니오 검증 완료 — 상세는
|
||||||
프로젝트의 전반적 기틀 잡힘과 정확성을 올리기를 할 것이라 해둬." — 위 "지금
|
`.claude/question.md`의 "2026-08-04 검증 라운드 완료" 절. 대부분 그대로
|
||||||
할 일" 1번이 이 요청을 그대로 반영한 것. 로컬 git 저장소는 이 세션에서 초기화
|
확인됐지만, 검증 과정에서 사용자가 실시간으로 설계를 더 전개하면서 **"State
|
||||||
+ 첫 커밋까지 해둠(원격 없음, `SAFETY.md` 참고 — 원격은 사용자가 제한 계정을
|
프리미티브는 안 만든다"는 기존 결정이 틀렸다는 게 밝혀짐** — Store/State/
|
||||||
마련해줘야 추가 가능).
|
Source 온톨로지 전체가 이번 세션에서 새로 열린 가장 중요한 설계 스레드로
|
||||||
|
떠올랐고, 아직 결론이 안 났음(위 "지금 할 일" 1번). 그 외 자잘한 정정들(Slot
|
||||||
|
retract=폐기 확정, Pipe COW 후보 폐기 등)은 각 문서에 바로 반영해둠 — 재조사
|
||||||
|
불필요.
|
||||||
|
|
||||||
|
이전 세션(2026-08-03) 종료 시점 메모: `.claude/` 전체 스캐폴드 + 대부분의
|
||||||
|
핵심 아키텍처 결정을 완료, 로컬 git 저장소 초기화+첫 커밋(원격 없음,
|
||||||
|
`SAFETY.md` 참고 — 원격은 사용자가 제한 계정을 마련해줘야 추가 가능).
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue