From 9c0124ef08d122c167d06a93c712aa00c3ac3d70 Mon Sep 17 00:00:00 2001 From: DongHyeonka Date: Wed, 16 Sep 2026 19:11:46 +0900 Subject: [PATCH] docs: correct the IndexedDB kernel economics with measured numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사양은 커널을 470줄로 추정했으나 실제 구현은 1,132줄이다. 그래서 레포 순증감이 -223에서 약 +439로 뒤집힌다. 이 작업은 줄 수를 줄이지 않는다. 근거는 상태기계 4개가 1개가 되는 것 하나뿐이라는 점을 명시하고, 이행을 멈추면 쓰이지 않는 커널이 남아 최악이라는 점도 적는다. Co-Authored-By: Claude Opus 5 (1M context) --- .../2026-09-16-indexeddb-kernel-promotion.md | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/docs/superpowers/plans/2026-09-16-indexeddb-kernel-promotion.md b/docs/superpowers/plans/2026-09-16-indexeddb-kernel-promotion.md index 9d83282..31ceed7 100644 --- a/docs/superpowers/plans/2026-09-16-indexeddb-kernel-promotion.md +++ b/docs/superpowers/plans/2026-09-16-indexeddb-kernel-promotion.md @@ -23,14 +23,28 @@ ## 왜 이 작업을 하는가 — LOC로 정당화하지 않는다 -| | LOC | -|---|---:| -| 4벌에서 삭제 | ~974 | -| 4벌에 추가 (커널 호출부·콜백) | ~281 | -| 커널 신규 2파일 | +~470 | -| **레포 순증감** | **~−223** | +> **2026-09-16 갱신 — 사양의 추정이 빗나갔다.** 커널을 실제로 구현하니 +> 2파일 **1,132줄**(코드 751줄)이다. 사양 추정 470줄의 2.4배다. 사양 §3.1이 +> "470 LOC라 2분할한다"고 쓴 논거도 사실이 아니었다(2분할 자체는 테스트 셋업이 +> 갈린다는 별도 근거로 유지). 그래서 아래 표의 순증감이 뒤집힌다. -**절감은 작다.** 성과는 줄 수가 아니라 **트랜잭션 상태기계가 4개에서 1개가 되는 것**이다. 오늘 그 4개는 이미 서로 다른 답을 낸다: +| | 사양 추정 | 실제 | +|---|---:|---:| +| 4벌에서 삭제 | ~974 | (미측정, 이행 후 확정) | +| 4벌에 추가 (커널 호출부·콜백) | ~281 | (미측정) | +| 4벌 순감 | −693 | (미측정) | +| 커널 신규 2파일 | +470 | **+1,132** | +| 신규 커널 테스트 2파일 | (미기재) | **+1,602** | +| **레포 순증감 (소스만)** | **−223** | **약 +439** | + +**이 리팩토링은 줄 수를 줄이지 않는다. 늘린다.** 소스 약 +439줄, 테스트까지 하면 +약 +2,041줄이다. 사양은 "절감이 작다"고 썼지만 실제로는 절감이 아니라 증가다. **그래서 이 작업의 근거는 줄 수가 아니라 오로지 트랜잭션 상태기계가 4개에서 +1개가 되는 것 하나다.** 줄 수로 정당화하려는 시도는 이제 불가능하다. + +**그리고 이행을 멈추면 최악이다.** 커널만 넣고 사본을 안 옮기면 +1,132줄의 +쓰이지 않는 코드가 남는다. 이 레포가 이미 `abortable-operation.ts`로 겪고 있는 +병(커널은 있는데 24개 파일이 안 씀)을 하나 더 만드는 것이다. 되돌리려면 지금이 +가장 싸다 — 커널 커밋 하나를 revert하면 끝이고, 사본은 아직 안 건드렸다. 오늘 그 4개는 이미 서로 다른 답을 낸다: | 상황 | RT | MT | OP | CP | |---|---|---|---|---| @@ -57,17 +71,17 @@ - Produces: spec §3.2·§3.3의 전체 export 시그니처. Task 2~5가 이것만 쓴다. - Consumes: 기존 커널 `snapshotAbortTimers`(`platform/abortable-operation.ts`), `contracts/result.ts`의 `Result` -- [ ] **Step 1: 기존 커널 관례를 읽는다** +- [x] **Step 1: 기존 커널 관례를 읽는다** `src/adapters/platform/`의 5파일을 읽고 주석 스타일(왜 이 규칙이 있는지를 근거와 함께 적는 방식), 에러 처리, 의존성 주입 방식을 파악한다. 새 파일은 그 관례를 따른다. -- [ ] **Step 2: 가짜 IDB의 오류 배선을 확인한다** +- [x] **Step 2: 가짜 IDB의 오류 배선을 확인한다** `tests/helpers/memory-indexeddb.ts`를 읽는다. 커널은 요청 레벨 `onerror`를 새로 보게 되므로 가짜가 `request.error`를 채우는지가 전제다. 확인됨(2026-09-16): 채운다. `:167-170`이 `request.error = asException(error)` 후 `queueMicrotask`로 `onerror` 발화, `:309-311`이 같은 일을 **동기로** 한다. **두 경로의 타이밍이 다르므로** 테스트에서 주의한다. -- [ ] **Step 3: 실패하는 테스트를 먼저 쓴다** +- [x] **Step 3: 실패하는 테스트를 먼저 쓴다** 최소한 아래를 고정한다. 각각 먼저 실패하는 것을 확인한 뒤 구현한다. @@ -91,7 +105,7 @@ - 예산 콜백이 "삭제 행 기준"과 "스캔 행 기준" 양쪽을 표현할 수 있는지 - **CP-4 필수 요건:** `abort()`가 throw하면 caller-abort 표시를 세우지 않고 transaction 이벤트가 결과를 정한다 -- [ ] **Step 4: 구현한다 — 좁은 커널 함정을 피한다** +- [x] **Step 4: 구현한다 — 좁은 커널 함정을 피한다** 기존 커널 `abortable-operation.ts:11`은 `AbortTerminalReason` 3멤버를 **반환 타입**에 박아서 5종이 필요한 `http-execution-v3`가 아예 못 썼다. 같은 실수를 반복하면 이 작업은 실패다. @@ -101,11 +115,11 @@ 하나라도 수용되지 않으면 **구현을 멈추고 보고한다.** spec에 억지로 맞추지 않는다. -- [ ] **Step 5: INVENTORY 갱신** +- [x] **Step 5: INVENTORY 갱신** `docs/reviews/adapters/INVENTORY.md`에 두 행을 알파벳 위치에 넣고 번호를 다시 매긴다. 링크는 같은 그룹(`platform/`) 기존 행과 동일하게 `[Network/state](./01-network-and-state.md)`. 하단 합계를 `130/130`으로. -- [ ] **Step 6: 게이트** +- [x] **Step 6: 게이트** ```bash corepack pnpm check:types:app && corepack pnpm check:types:test \ @@ -115,7 +129,7 @@ corepack pnpm test:unit ``` Expected: 앞 묶음 전부 PASS. `test:unit`은 `ci-artifact-contract.test.ts` 외 실패 0. -- [ ] **Step 7: 커밋** +- [x] **Step 7: 커밋** ```bash git add src/adapters/platform tests/unit/indexeddb-*.test.ts docs/reviews/adapters/INVENTORY.md