v0.3.2 — cleanup cut (잠재 bug 4 + cosmetic 5 + #20 deferred) #32

Merged
altair823 merged 11 commits from worktree-v032-cleanup into main 2026-05-10 07:15:25 +00:00
Owner

Summary

v0.3.2 — cleanup cut. semver patch. backlog 잔여 23 → 14 (-9 처리, -1 deferred 잔존). 신기능 X, 잠재 bug fix + cosmetic + 기록 정리. dogfood baseline 정리.

  • 잠재 bug 4건:
    • vocabSet COLLATE NOCASE 정합 (#31) — DB COLLATE NOCASE 와 strict-eq vocabSet 충돌 회피, lowercase normalize 양쪽 적용
    • time-dependent test flake fix — NoteRepository.create(input, now?: Date) signature (기존 setStatus/updateRawText 패턴 정합), 6 testcase v1 capture 시간 명시 주입
    • PII reason 마스킹 (#39) — LocalOllamaProvider.healthCheck catch 시 classifyFetchError 로 error class enum (network/timeout/dns/other) 변환, LAN endpoint URL 노출 회피
    • KST_OFFSET_MS inline 5 callsite migrate (#19) — src/shared/util/kstDate.ts canonical export 활용 (NoteRepository, ftsHelpers, BackupService, ContinuityService, NoteCard)
  • cosmetic 5건:
    • 탭 ARIA aria-pressedrole="tab" + aria-selected (#14) — canonical pattern
    • loadExpired dead-code 제거 (#18) — App.tsx 호출 0건, loadInitial/refreshMeta 가 inline fetch
    • AiWorker per-tag emit Promise.all 병렬화 (#32) — 3 tag = 1 round-trip, file-append 동시
    • recall IPC handleon (#36) — fire-and-forget honest pattern, Promise<void>void
    • OllamaSettingsModal 폐기 audit (#41+#42) — v0.2.7 cut 에서 이미 폐기, backlog entry close 만
  • 기록 정리 2건:
    • v0.2.2 stale memory 폐기 (project_v022_feedback.md — 6건 모두 v0.2.3+ cut 들에서 처리됨, 8일 stale)
    • v024-backlog.md 처리 이력 갱신 (잔여 14건 = 46 - 처리 31 - stale 1)
  • #20 deferred: telemetry .catch silent → debug logCaptureServicelogger 미주입. constructor 변경 회피로 cleanup cut 외 후속.

변경 내역 (9 commits)

Task 단위

  • 36eafa1 Task 1 — NoteRepository.create(now?: Date) + 6 testcase 시간 주입
  • 6985db3 Task 2 — vocabSet COLLATE NOCASE
  • 302bbd4 Task 3 — LocalOllamaProvider PII reason 마스킹
  • 41310db Task 4 — KST_OFFSET_MS 5 callsite migrate (cherry-picked from earlier subagent session)
  • 9073e78 Task 5 — 탭 ARIA + loadExpired 제거
  • aa7eb9d Task 6 — AiWorker per-tag Promise.all
  • 4db7a0b Task 7 — recall IPC handleon (#20 deferred)
  • 83cefcc Task 7 fix — AiWorker Promise.all closure type narrowing 회복
  • bb909e4 Task 8 — release v0.3.2 + backlog 갱신

변경 파일

  • production: NoteRepository (signature + KST), AiWorker (vocabSet + Promise.all + closure capture), LocalOllamaProvider (classifyFetchError), inboxApi (handle→on), preload (invoke→send), shared/types (Promise→void), App.tsx (ARIA), store.ts (loadExpired 제거 + await drop), 4 KST migration files
  • 신규 test: tests/unit/recall-ipc.test.ts
  • 갱신 test: NoteRepository / NoteRevisions / upsertFromSync / AiWorker (COLLATE 3) / LocalOllamaProvider (PII 4) / App / store.expired (loadExpired 제거) / 4 sibling IPC mocks

테스트 / 빌드

  • 단위: 710 → 723 pass (+13: vocabSet 3 + create now param 2 + PII 4 + recall-ipc 3 + ARIA 1, -2 loadExpired test 제거 + 회복 6 = net +13). 1 pre-existing fail (SyncService.test.ts EPERM Windows temp cleanup flake — 본 cut 무관)
  • typecheck: 0 errors
  • e2e: 본 세션 미수행 — UI 변경 = 탭 ARIA 만 (canonical 정정, screen reader 동작 무변), 머지 후 main 에서 검증 권장
  • 산출물: 후속 release 단계 Windows exe + macOS dmg + Linux AppImage/deb

Schema 변경

m007 (Cut D) 이후 변경 없음. 본 cut 은 코드 만 (test 시간 주입 + import migration + ARIA + dead code 제거).

메모리 정책 갱신 (v0.3.2 머지 후 적용)

  • vocabSet lowercase normalize: tags.name COLLATE NOCASE 와 정합 — vocab pool 확장 시 case mismatch silently skip 회피
  • PII reason 마스킹 패턴: classifyFetchError (network/timeout/dns/other) — telemetry 에 host/IP 노출 0
  • NoteRepository.create(now?: Date): setStatus/updateRawText 패턴 정합. test 결정성 + production 무영향
  • fire-and-forget IPC = on + send (canonical pattern, return value 의존 X)
  • logger 의존성 정책 (#20 deferred): 신규 .catch 시 logger.debug 사용. service 별 logger 주입 누락 시 별도 cut 으로 wiring

Risk 잔재 (final review)

  • #20 deferred: telemetry .catch silent — debug 시 reproduce 어려움. v0.3.3 에서 CaptureService DI 정리 + logger.debug 적용
  • e2e 본 세션 미수행: 머지 후 main 에서 smoke. 탭 ARIA 만 영향, capture/onboarding flow 무관
  • pre-existing SyncService EPERM Windows flake: 본 cut 무관, 별도 cut 에서 fix
  • vocabSet COLLATE fix 의 production 효과: getTopUsedTagsKEBAB_CASE_RE 로 capital 필터링 → production 에서 capital vocab 등장 X. defense-in-depth (vocab 정책 완화 시 안전)

Test Plan

  • npx vitest run tests/unit/AiWorker.test.ts → 28 PASS (vocabSet COLLATE 3 + Promise.all 회귀)
  • npx vitest run tests/unit/LocalOllamaProvider.test.ts → 16 PASS (PII 4 + 회귀 12)
  • npx vitest run tests/unit/NoteRevisions.test.ts tests/unit/NoteRepository.upsertFromSync.test.ts → 시계 지나도 deterministic PASS
  • npx vitest run tests/unit/recall-ipc.test.ts → 3 PASS (ipcMain.on 등록 검증)
  • npx vitest run tests/unit/App.test.tsx → 탭 aria-selected 검증
  • git grep -n "KST_OFFSET_MS = 9" -- src/ → 1 hit (canonical export 만)
  • 머지 후 packaged build smoke — capture / settings / inbox flow 회귀 X
  • dogfood ≥ 1주 soak: vision (Cut F) + sync (Cut E) + cleanup baseline 동시 검증 → Cut G brainstorm 진입

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

## Summary v0.3.2 — cleanup cut. semver **patch**. backlog 잔여 23 → 14 (-9 처리, -1 deferred 잔존). 신기능 X, 잠재 bug fix + cosmetic + 기록 정리. dogfood baseline 정리. - **잠재 bug 4건**: - vocabSet COLLATE NOCASE 정합 (#31) — DB COLLATE NOCASE 와 strict-eq vocabSet 충돌 회피, lowercase normalize 양쪽 적용 - time-dependent test flake fix — `NoteRepository.create(input, now?: Date)` signature (기존 `setStatus`/`updateRawText` 패턴 정합), 6 testcase v1 capture 시간 명시 주입 - PII reason 마스킹 (#39) — `LocalOllamaProvider.healthCheck` catch 시 `classifyFetchError` 로 error class enum (network/timeout/dns/other) 변환, LAN endpoint URL 노출 회피 - KST_OFFSET_MS inline 5 callsite migrate (#19) — `src/shared/util/kstDate.ts` canonical export 활용 (NoteRepository, ftsHelpers, BackupService, ContinuityService, NoteCard) - **cosmetic 5건**: - 탭 ARIA `aria-pressed` → `role="tab"` + `aria-selected` (#14) — canonical pattern - `loadExpired` dead-code 제거 (#18) — App.tsx 호출 0건, `loadInitial`/`refreshMeta` 가 inline fetch - AiWorker per-tag emit `Promise.all` 병렬화 (#32) — 3 tag = 1 round-trip, file-append 동시 - recall IPC `handle`→`on` (#36) — fire-and-forget honest pattern, `Promise<void>` → `void` - OllamaSettingsModal 폐기 audit (#41+#42) — v0.2.7 cut 에서 이미 폐기, backlog entry close 만 - **기록 정리 2건**: - v0.2.2 stale memory 폐기 (`project_v022_feedback.md` — 6건 모두 v0.2.3+ cut 들에서 처리됨, 8일 stale) - v024-backlog.md 처리 이력 갱신 (잔여 14건 = 46 - 처리 31 - stale 1) - **#20 deferred**: telemetry `.catch silent → debug log` — `CaptureService` 가 `logger` 미주입. constructor 변경 회피로 cleanup cut 외 후속. ## 변경 내역 (9 commits) ### Task 단위 - `36eafa1` Task 1 — `NoteRepository.create(now?: Date)` + 6 testcase 시간 주입 - `6985db3` Task 2 — vocabSet COLLATE NOCASE - `302bbd4` Task 3 — `LocalOllamaProvider` PII reason 마스킹 - `41310db` Task 4 — KST_OFFSET_MS 5 callsite migrate (cherry-picked from earlier subagent session) - `9073e78` Task 5 — 탭 ARIA + `loadExpired` 제거 - `aa7eb9d` Task 6 — AiWorker per-tag `Promise.all` - `4db7a0b` Task 7 — recall IPC `handle`→`on` (#20 deferred) - `83cefcc` Task 7 fix — AiWorker `Promise.all` closure type narrowing 회복 - `bb909e4` Task 8 — release v0.3.2 + backlog 갱신 ### 변경 파일 - production: NoteRepository (signature + KST), AiWorker (vocabSet + Promise.all + closure capture), LocalOllamaProvider (classifyFetchError), inboxApi (handle→on), preload (invoke→send), shared/types (Promise<void>→void), App.tsx (ARIA), store.ts (loadExpired 제거 + await drop), 4 KST migration files - 신규 test: tests/unit/recall-ipc.test.ts - 갱신 test: NoteRepository / NoteRevisions / upsertFromSync / AiWorker (COLLATE 3) / LocalOllamaProvider (PII 4) / App / store.expired (loadExpired 제거) / 4 sibling IPC mocks ## 테스트 / 빌드 - 단위: 710 → **723 pass** (+13: vocabSet 3 + create now param 2 + PII 4 + recall-ipc 3 + ARIA 1, -2 loadExpired test 제거 + 회복 6 = net +13). 1 pre-existing fail (`SyncService.test.ts` EPERM Windows temp cleanup flake — 본 cut 무관) - typecheck: **0 errors** - e2e: 본 세션 미수행 — UI 변경 = 탭 ARIA 만 (canonical 정정, screen reader 동작 무변), 머지 후 main 에서 검증 권장 - 산출물: 후속 release 단계 Windows exe + macOS dmg + Linux AppImage/deb ## Schema 변경 m007 (Cut D) 이후 변경 없음. 본 cut 은 코드 만 (test 시간 주입 + import migration + ARIA + dead code 제거). ## 메모리 정책 갱신 (v0.3.2 머지 후 적용) - **vocabSet lowercase normalize**: `tags.name COLLATE NOCASE` 와 정합 — vocab pool 확장 시 case mismatch silently skip 회피 - **PII reason 마스킹 패턴**: `classifyFetchError` (network/timeout/dns/other) — telemetry 에 host/IP 노출 0 - **NoteRepository.create(now?: Date)**: `setStatus`/`updateRawText` 패턴 정합. test 결정성 + production 무영향 - **fire-and-forget IPC = `on` + `send`** (canonical pattern, return value 의존 X) - **logger 의존성 정책 (#20 deferred)**: 신규 .catch 시 `logger.debug` 사용. service 별 logger 주입 누락 시 별도 cut 으로 wiring ## Risk 잔재 (final review) - **#20 deferred**: telemetry .catch silent — debug 시 reproduce 어려움. v0.3.3 에서 CaptureService DI 정리 + logger.debug 적용 - **e2e 본 세션 미수행**: 머지 후 main 에서 smoke. 탭 ARIA 만 영향, capture/onboarding flow 무관 - **pre-existing SyncService EPERM Windows flake**: 본 cut 무관, 별도 cut 에서 fix - **vocabSet COLLATE fix 의 production 효과**: `getTopUsedTags` 가 `KEBAB_CASE_RE` 로 capital 필터링 → production 에서 capital vocab 등장 X. defense-in-depth (vocab 정책 완화 시 안전) ## Test Plan - [ ] `npx vitest run tests/unit/AiWorker.test.ts` → 28 PASS (vocabSet COLLATE 3 + Promise.all 회귀) - [ ] `npx vitest run tests/unit/LocalOllamaProvider.test.ts` → 16 PASS (PII 4 + 회귀 12) - [ ] `npx vitest run tests/unit/NoteRevisions.test.ts tests/unit/NoteRepository.upsertFromSync.test.ts` → 시계 지나도 deterministic PASS - [ ] `npx vitest run tests/unit/recall-ipc.test.ts` → 3 PASS (`ipcMain.on` 등록 검증) - [ ] `npx vitest run tests/unit/App.test.tsx` → 탭 `aria-selected` 검증 - [ ] `git grep -n "KST_OFFSET_MS = 9" -- src/` → 1 hit (canonical export 만) - [ ] 머지 후 packaged build smoke — capture / settings / inbox flow 회귀 X - [ ] dogfood ≥ 1주 soak: vision (Cut F) + sync (Cut E) + cleanup baseline 동시 검증 → Cut G brainstorm 진입 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) &lt;noreply@anthropic.com&gt;
altair823 added 11 commits 2026-05-10 05:41:51 +00:00
backlog 잔여 23건 audit 결과:
- 잠재 bug 4건: vocabSet COLLATE / time-dep test flake / PII reason / KST inline 5 callsite
- cosmetic 6건: 탭 ARIA / loadExpired 제거 / per-tag Promise.all / recall IPC on / OllamaSettingsModal 폐기 audit / .catch debug log
- 기록 정리 2건: v0.2.2 stale memory 폐기 / v024-backlog 갱신
- 보류: data-dependent 9 + future-proof 2 (dogfood 후 재평가)

목표 단위 710 → 약 720 (+10), typecheck 0
Spec: 2026-05-10-v032-cleanup-design.md
Tasks: time-dep test fix / vocabSet COLLATE / PII reason / KST migration /
       탭 ARIA + loadExpired / Promise.all / recall IPC + .catch / 기록 정리

목표 단위 710 → 약 720 (+10 신규, -2 제거), typecheck 0
- create(input, now?: Date) signature 추가 (기존 setStatus/updateRawText 패턴 정합)
- NoteRevisions.test.ts 4 testcase v1 capture 시간 명시 주입 (2026-05-09T00:00:00Z)
- upsertFromSync.test.ts 2 testcase v1 capture 시간 명시 주입
- 시스템 시계가 2026-05-10T00:00:00Z 초과 시 DESC ordering 깨지던 회귀 회복

backlog: time-dependent flake (Cut F audit 발견)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DB tags.name 가 COLLATE NOCASE 인데 vocabSet 은 strict-eq 였음 →
대문자/소문자 vocab 과 AI tag 가 다를 때 silently skip.

vocab.toLowerCase() + tagName.toLowerCase() 양쪽 normalize 로 정합.
err.message 안에 LAN endpoint URL (예: 192.168.x.x:11434) 이 포함될 수
있어 telemetry 파일에 PII 우회 노출. v0.2.3.1 in-app endpoint UI 가 LAN
사용을 흔하게 만들어 노출 경로 확대.

classifyFetchError 로 error class 분류 (network/timeout/dns/other) 후
reason: 'unreachable:{class}' 형태만 emit. host/IP 노출 0.
- App.tsx 탭 button 의 aria-pressed → role="tab" + aria-selected
  (canonical pattern, a11y audit 정정)
- store.ts loadExpired action + test 제거 (App.tsx 호출 0건,
  loadInitial/refreshMeta 가 inline fetch — dead code)
기존 serial for-await: 3 태그 → 3 round-trip file-append.
Promise.all: 동일 결과, file-append 동시 실행 (telemetry 파일은
append-only, 순서 의존 단위 0).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- inbox:emitRecallShown / emitRecallSnoozed: ipcMain.handle → on
  (fire-and-forget honest pattern, return value 의존자 0)
- preload: ipcRenderer.invoke → send (matching on the main side)
- shared/types: Promise<void> → void on both recall emit methods
- store.ts: drop await on emitRecallSnoozed (now void)
- inboxApi-*.test.ts: add ipcMain.on to electron mock (broken by above)
- tests/unit/recall-ipc.test.ts: new TDD test for handle→on migration

Note: #20 CaptureService telemetry .catch debug log skipped —
CaptureService has no logger field; adding one would require non-trivial
constructor signature change. Reported as CONCERN below.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Task 6 의 Promise.all 도입 시 async callback closure 가 this.telemetry?
narrowing 잃어 TS2532 발생. const telemetry = this.telemetry 로 narrowed
reference capture 후 closure 안에서 사용.
backlog 잔여 23 → 14 (-9 처리, +1 deferred 잔존, +1 stale):
- 잠재 bug 4: vocabSet COLLATE / time-dep test flake / PII reason / KST inline
- cosmetic 5: 탭 ARIA / loadExpired 제거 / per-tag Promise.all / recall IPC on
  / OllamaSettingsModal 폐기 audit
- deferred: #20 (.catch debug log — CaptureService logger 미주입)

기록 정리: v0.2.2 stale memory 폐기 + v024-backlog 처리 이력 갱신

단위 710 → 724, typecheck 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 callsite (NoteRepository, ftsHelpers, BackupService, ContinuityService,
NoteCard) 모두 canonical export 로 정리. 알고리즘 동일 (9 * 60 * 60 * 1000),
회귀 PASS 검증.

v0.2.6 commit 3cfa60b 가 4 callsite migrate 했지만 5 callsite 잔여.
Cut F audit 에서 발견.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
altair823 changed title from v0.3.2 ? cleanup cut (���� bug 4 + cosmetic 5 + #20 deferred) to v0.3.2 — cleanup cut (잠재 bug 4 + cosmetic 5 + #20 deferred) 2026-05-10 07:12:36 +00:00
claude-reviewer-01 approved these changes 2026-05-10 07:14:43 +00:00
claude-reviewer-01 left a comment
Member

코드 리뷰 — v0.3.2 cleanup cut

Scope: 9 commits (4deb777..bb909e4 → cherry-pick 41310db) — semver patch (cleanup, 신기능 X, backward compat)

Spec coverage 11/12 (1 honestly deferred)

spec 의 모든 항목이 task 매핑됨. #20 (.catch silent → debug log) 만 deferred — CaptureServicelogger 미주입 → constructor 변경 회피로 v0.3.3+ 후속.

spec § 구현 단위
§3-1 vocabSet COLLATE AiWorker.processJob:189 lowercase normalize 양쪽 +3
§3-2 time-dep test fix NoteRepository.create(now?: Date) + 6 testcase 시간 주입 +2 신규 + 6 회복
§3-3 PII reason LocalOllamaProvider.healthCheck classifyFetchError enum +4
§3-4 KST inline 5 callsite @shared/util/kstDate import (NoteRepository / ftsHelpers / BackupService / ContinuityService / NoteCard) 회귀 PASS
§4-1 탭 ARIA App.tsx role="tab" + aria-selected +1
§4-2 loadExpired 제거 store.ts action + interface 제거 + test 제거 -2
§4-3 per-tag Promise.all AiWorker:189-207 Array.from + map 회귀 PASS
§4-4 recall IPC handle→on inboxApi + preload + types + 4 sibling mocks +3 신규
§4-5 OllamaSettingsModal audit grep src/ → 0 hits, v0.2.7 폐기 확인 코드 변경 0
§4-6 .catch debug log 🟡 deferred — CaptureService logger 미주입 -
§5-1 v0.2.2 memory 폐기 file delete + MEMORY.md 라인 제거 repo 외
§5-2 backlog 갱신 v024-backlog.md 처리 이력 + 잔여 카운트 repo 변경

코드 품질

Strengths

  • Single write path 유지: note_tags / note_revisions 4-path invariant 보존. NoteRepository.create signature 만 변경 (capture revision INSERT path 그대로) — 기존 호출자 무영향 (default = new Date()).
  • PII 마스킹 principled: classifyFetchError(network|timeout|dns|other) enum + unreachable:{class} reason 만 emit. 디버그 가능성 보존 (error class 분류) + LAN endpoint URL 노출 0. PII negative assertion (not.toContain('192.168.1.5')) 명시 검증.
  • AiWorker triple-touch 일관: Task 2 (vocabSet COLLATE) + Task 6 (Promise.all) + Task 7 fix (closure capture const telemetry = this.telemetry) 셋이 합성. if (this.telemetry) 가드 narrowing 을 closure 안에서 유지하는 idiom 적용.
  • Backwards compat:
    • NoteRepository.create(input, now?: Date = new Date()) — production 호출자 무영향
    • recall IPC handle→on 변경 시 Promise<void>void + 호출자 4곳 (store / RecallBanner / preload / types) 모두 동기 갱신. orphaned await 0
  • fire-and-forget honest pattern: ipcMain.on + ipcRenderer.send canonical. return value 의존 호출��� 0 검증 후 migration.
  • KST canonical 정합: @shared/util/kstDate 단일 source of truth. v0.2.6 commit 3cfa60b 가 4 callsite 정리, 본 cut 가 5 callsite 잔여 정리 → 0 inline duplicate.
  • Memory hygiene: v0.2.2 stale memory (8일) 폐기. MEMORY.md index 라인 제거. backlog 처리 이력 정확히 갱신 (#20 deferred 명시 표시).

Final review follow-up 적용 (cherry-pick 41310db)

initial implementer 진행 중 Task 4 (KST migration) 가 fresh subagent session 의 HEAD 인식 오류로 worktree branch 에서 누락됨 (1193c3c 이 dangling). final review (Opus, 1차) 가 발견 → cherry-pick 으로 복구:

  • ⚠ KST migration commit (1193c3c) 가 worktree-v032-cleanup branch 에 없음 — Task 5 implementer 가 fresh session 에서 이전 task 의 HEAD 못 봄
  • → cherry-pick 41310db 로 release commit 뒤에 복구. typecheck + 723 PASS 검증

re-verification 결과:

  • 723/724 PASS (1 pre-existing SyncService EPERM Windows flake — 본 cut 무관)
  • typecheck 0
  • git grep KST_OFFSET_MS = 9 -- src/ → 1 hit (canonical only)
  • bounded scope (cherry-pick 외 변경 없음)

Architecture

  • 단위 분해 명확 (각 task = 단일 책임. 다중 file touch = 모두 같은 fix 의 일부)
  • 책임 명확성 — NoteRepository (DB CRUD) / AiWorker (orchestration) / LocalOllamaProvider (transport + 분류) / kstDate (canonical helper) / inboxApi (IPC routing)
  • 일관성 — 기존 패턴 (signature now: Date) + canonical helper 활용
  • 명명 정확성 (Cut E lesson) — 새 식별자 도입 X (cleanup 이라 rename 부재)

Risk 잔재 (final review)

  • #20 deferred: telemetry .catch silent → debug log. CaptureService DI 정리 + logger 주입 후 v0.3.3 진행. estimate ≤ 1h
  • vocabSet COLLATE fix 의 production 효과: KEBAB_CASE_RE 가 capital 필터링 → 현재 production 에서 capital vocab 등장 0. defense-in-depth (vocab 정책 완화 시 안전)
  • e2e 본 세션 미수행: 탭 ARIA canonical 정정 만 영향. screen reader 동작 무변. 머지 후 packaged build smoke 권장
  • pre-existing SyncService EPERM Windows flake: 본 cut 무관, 별도 cut 에서 fix
  • commit ordering: cherry-pick 으로 KST migration 이 release commit 뒤. PR delta 정확 (9 commit), backlog 갱신 정합. functional 동일

Sub-review 트레일

  • Task 1 (NoteRepository.create now param) — Sonnet, 6 testcase 회복 + 2 신규
  • Task 2 (vocabSet COLLATE) — Sonnet + 3 신규
  • Task 3 (PII reason) — Sonnet + 4 신규
  • Task 4 (KST migration) — Haiku, 5 callsite (cherry-pick 으로 복구)
  • Task 5 (탭 ARIA + loadExpired) — Sonnet + 1 신규 -2 제거
  • Task 6 (per-tag Promise.all) — Haiku (typecheck 회귀 → Task 7 fix 로 복구)
  • Task 7 (recall IPC + #20 defer) — Sonnet + 3 신규 + 4 sibling mock , follow-up 83cefcc typecheck 회복
  • Task 8 (release commit) — Haiku, backlog 갱신 + version bump
  • Final code review (Opus, 1차) — ⚠ Approved with KST cherry-pick recovery + 1 minor (#20 deferral honesty)
  • Cherry-pick re-verification 723/724

머지 권장

  1. PR #32 머지
  2. tag v0.3.2 + npm run dist:win → Windows exe 빌드
  3. Gitea release v0.3.2 + exe attach
  4. macOS host: dist:mac + dist:linux 후 dmg/AppImage/deb 추가 attach
  5. 메모리 정책 갱신 — vocabSet lowercase / PII reason masking / NoteRepository.create now param / fire-and-forget IPC pattern / logger 의존성 정책 (#20 deferred)
  6. 종합 dogfood ≥ 1주 soak — Cut E (sync) + Cut F (vision) + Cut 본 (cleanup) baseline. dogfood 결과 (sync 충돌 빈도 / vision 한국어 정확도 / capability detection 정확도 / time-dep flake 회귀 X 확인) → v0.3.3 Cut G plan + #20 + data-dependent 9건 일괄 triage

Overall

Ready to merge. Spec 11/12 coverage (#20 honestly deferred), 710 → 723 unit (+13) + typecheck 0, schema 변경 없음, backward compat 보장 (signature default + recall sync), single write path invariant 4-path 유지. Cherry-pick recovery 정직 기록. Cut G (v0.3.3 — F25 사이드바 + notebook_id) 진입 가능.

🤖 Reviewed by Claude Opus 4.7 (1M context) with subagent-driven-development per skill

## 코드 리뷰 — v0.3.2 cleanup cut **Scope**: 9 commits (4deb777..bb909e4 → cherry-pick 41310db) — semver patch (cleanup, 신기능 X, backward compat) ### Spec coverage ✅ 11/12 (1 honestly deferred) [spec](docs/superpowers/specs/2026-05-10-v032-cleanup-design.md) 의 모든 항목이 task 매핑됨. #20 (`.catch silent → debug log`) 만 deferred — `CaptureService` 가 `logger` 미주입 → constructor 변경 회피로 v0.3.3+ 후속. | spec § | 구현 | 단위 | |---|---|---| | §3-1 vocabSet COLLATE | `AiWorker.processJob:189` lowercase normalize 양쪽 | +3 | | §3-2 time-dep test fix | `NoteRepository.create(now?: Date)` + 6 testcase 시간 주입 | +2 신규 + 6 회복 | | §3-3 PII reason | `LocalOllamaProvider.healthCheck` `classifyFetchError` enum | +4 | | §3-4 KST inline 5 callsite | `@shared/util/kstDate` import (NoteRepository / ftsHelpers / BackupService / ContinuityService / NoteCard) | 회귀 PASS | | §4-1 탭 ARIA | `App.tsx` `role="tab"` + `aria-selected` | +1 | | §4-2 loadExpired 제거 | `store.ts` action + interface 제거 + test 제거 | -2 | | §4-3 per-tag Promise.all | `AiWorker:189-207` Array.from + map | 회귀 PASS | | §4-4 recall IPC handle→on | `inboxApi` + preload + types + 4 sibling mocks | +3 신규 | | §4-5 OllamaSettingsModal audit | grep `src/` → 0 hits, v0.2.7 폐기 확인 | 코드 변경 0 | | §4-6 .catch debug log | **🟡 deferred** — CaptureService logger 미주입 | - | | §5-1 v0.2.2 memory 폐기 | file delete + MEMORY.md 라인 제거 | repo 외 | | §5-2 backlog 갱신 | v024-backlog.md 처리 이력 + 잔여 카운트 | repo 변경 | ### 코드 품질 **Strengths** - **Single write path 유지**: `note_tags` / `note_revisions` 4-path invariant 보존. `NoteRepository.create` signature 만 변경 (capture revision INSERT path 그대로) — 기존 호출자 무영향 (default = `new Date()`). - **PII 마스킹 principled**: `classifyFetchError(network|timeout|dns|other)` enum + `unreachable:{class}` reason 만 emit. 디버그 가능성 보존 (error class 분류) + LAN endpoint URL 노출 0. PII negative assertion (`not.toContain('192.168.1.5')`) 명시 검증. - **AiWorker triple-touch 일관**: Task 2 (vocabSet COLLATE) + Task 6 (Promise.all) + Task 7 fix (closure capture `const telemetry = this.telemetry`) 셋이 합성. `if (this.telemetry)` 가드 narrowing 을 closure 안에서 유지하는 idiom 적용. - **Backwards compat**: - `NoteRepository.create(input, now?: Date = new Date())` — production 호출자 무영향 - `recall IPC handle→on` 변경 시 `Promise<void>` → `void` + 호출자 4곳 (store / RecallBanner / preload / types) 모두 동기 갱신. orphaned await 0 - **fire-and-forget honest pattern**: `ipcMain.on` + `ipcRenderer.send` canonical. return value 의존 호출��� 0 검증 후 migration. - **KST canonical 정합**: `@shared/util/kstDate` 단일 source of truth. v0.2.6 commit `3cfa60b` 가 4 callsite 정리, 본 cut 가 5 callsite 잔여 정리 → 0 inline duplicate. - **Memory hygiene**: v0.2.2 stale memory (8일) 폐기. MEMORY.md index 라인 제거. backlog 처리 이력 정확히 갱신 (#20 deferred 명시 표시). **Final review follow-up 적용** (cherry-pick `41310db`) initial implementer 진행 중 Task 4 (KST migration) 가 fresh subagent session 의 HEAD 인식 오류로 worktree branch 에서 누락됨 (1193c3c 이 dangling). final review (Opus, 1차) 가 발견 → cherry-pick 으로 복구: - ⚠ KST migration commit (`1193c3c`) 가 worktree-v032-cleanup branch 에 없음 — Task 5 implementer 가 fresh session 에서 이전 task 의 HEAD 못 봄 - → cherry-pick `41310db` 로 release commit 뒤에 복구. typecheck + 723 PASS 검증 re-verification 결과: - 723/724 PASS (1 pre-existing SyncService EPERM Windows flake — 본 cut 무관) - typecheck 0 - `git grep KST_OFFSET_MS = 9 -- src/` → 1 hit (canonical only) - bounded scope (cherry-pick 외 변경 없음) ### Architecture - 단위 분해 명확 (각 task = 단일 책임. 다중 file touch = 모두 같은 fix 의 일부) - 책임 명확성 — `NoteRepository` (DB CRUD) / `AiWorker` (orchestration) / `LocalOllamaProvider` (transport + 분류) / `kstDate` (canonical helper) / `inboxApi` (IPC routing) - 일관성 — 기존 패턴 (signature `now: Date`) + canonical helper 활용 - 명명 정확성 (Cut E lesson) — 새 식별자 도입 X (cleanup 이라 rename 부재) ### Risk 잔재 (final review) - **#20 deferred**: telemetry .catch silent → debug log. CaptureService DI 정리 + logger 주입 후 v0.3.3 진행. estimate ≤ 1h - **vocabSet COLLATE fix 의 production 효과**: `KEBAB_CASE_RE` 가 capital 필터링 → 현재 production 에서 capital vocab 등장 0. defense-in-depth (vocab 정책 완화 시 안전) - **e2e 본 세션 미수행**: 탭 ARIA canonical 정정 만 영향. screen reader 동작 무변. 머지 후 packaged build smoke 권장 - **pre-existing SyncService EPERM Windows flake**: 본 cut 무관, 별도 cut 에서 fix - **commit ordering**: cherry-pick 으로 KST migration 이 release commit 뒤. PR delta 정확 (9 commit), backlog 갱신 정합. functional 동일 ### Sub-review 트레일 - **Task 1 (NoteRepository.create now param)** — Sonnet, 6 testcase 회복 + 2 신규 ✅ - **Task 2 (vocabSet COLLATE)** — Sonnet + 3 신규 ✅ - **Task 3 (PII reason)** — Sonnet + 4 신규 ✅ - **Task 4 (KST migration)** — Haiku, 5 callsite ✅ (cherry-pick 으로 복구) - **Task 5 (탭 ARIA + loadExpired)** — Sonnet + 1 신규 -2 제거 ✅ - **Task 6 (per-tag Promise.all)** — Haiku ✅ (typecheck 회귀 → Task 7 fix 로 복구) - **Task 7 (recall IPC + #20 defer)** — Sonnet + 3 신규 + 4 sibling mock ✅, follow-up `83cefcc` typecheck 회복 - **Task 8 (release commit)** — Haiku, backlog 갱신 + version bump ✅ - **Final code review (Opus, 1차)** — ⚠ Approved with KST cherry-pick recovery + 1 minor (#20 deferral honesty) - **Cherry-pick re-verification** — ✅ 723/724 ### 머지 권장 1. PR #32 머지 2. tag `v0.3.2` + `npm run dist:win` → Windows exe 빌드 3. Gitea release v0.3.2 + exe attach 4. macOS host: `dist:mac` + `dist:linux` 후 dmg/AppImage/deb 추가 attach 5. 메모리 정책 갱신 — vocabSet lowercase / PII reason masking / NoteRepository.create now param / fire-and-forget IPC pattern / logger 의존성 정책 (#20 deferred) 6. **종합 dogfood ≥ 1주 soak** — Cut E (sync) + Cut F (vision) + Cut 본 (cleanup) baseline. dogfood 결과 (sync 충돌 빈도 / vision 한국어 정확도 / capability detection 정확도 / time-dep flake 회귀 X 확인) → v0.3.3 Cut G plan + #20 + data-dependent 9건 일괄 triage ### Overall **Ready to merge.** Spec 11/12 coverage (#20 honestly deferred), 710 → 723 unit (+13) + typecheck 0, schema 변경 없음, backward compat 보장 (signature default + recall sync), single write path invariant 4-path 유지. Cherry-pick recovery 정직 기록. Cut G (v0.3.3 — F25 사이드바 + notebook_id) 진입 가능. 🤖 Reviewed by Claude Opus 4.7 (1M context) with subagent-driven-development per skill
altair823 merged commit f37e17dd81 into main 2026-05-10 07:15:25 +00:00
altair823 deleted branch worktree-v032-cleanup 2026-05-10 07:15:26 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: altair823-org/inkling#32