docs: correct the IndexedDB kernel economics with measured numbers

사양은 커널을 470줄로 추정했으나 실제 구현은 1,132줄이다. 그래서 레포
순증감이 -223에서 약 +439로 뒤집힌다. 이 작업은 줄 수를 줄이지 않는다.
근거는 상태기계 4개가 1개가 되는 것 하나뿐이라는 점을 명시하고, 이행을
멈추면 쓰이지 않는 커널이 남아 최악이라는 점도 적는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
DongHyeonka
2026-09-16 19:11:46 +09:00
co-authored by Claude Opus 5
parent cb62bfb9a9
commit 9c0124ef08
@@ -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