m1 — HealthChecker.last={ok:true} sentinel 의도 주석 (line 17).
첫 healthy=ok=true 면 transition 으로 인식 안 됨, ok=false 면 unreachable
transition 으로 정상 인식. telemetry 누락 0.
m2 — runOnce in-flight guard 추가. polling 첫 호출이 늦게 끝나는 동안
setInterval 가 두 번째 호출 시작하면 같은 promise 반환. healthCheck 가
idempotent HTTP 라 race 안전하지만, 이중 onUpdate/telemetry emit 회피.
m3 — main.ts before-quit 핸들러 통합. trayInterval cleanup 별도 핸들러
(line 349) 제거하고 health.stop() 핸들러 안에 흡수. 모든 cleanup 한 곳.
n1 — OllamaBanner 재확인 button 의 onClick 에 .catch 추가.
recheckOllama Promise rejection 시 console.warn (silent swallow 회피).
n2 — App.tsx useEffect deps array 의도 주석 1줄. onOllamaStatus 콜백이
useInbox.setState 직접 호출 — store reference 안정적이라 deps 불필요.
n3 — HealthChecker idempotent test 강화. <=2 → ===2 (정확).
두 timer 등록되면 4 (각 timer 마다 즉시+1s) 가 됨.
n4 — runOnce 의 manual emit 이 healthCheck *전에* fire 인 의도 주석.
provider 실패 시에도 manual 카운트 1:1 보장.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Task 21 of the slice plan. registerInboxApi binds every
InboxApi method on the main side: inbox:list (paginated),
inbox:updateAi (delegates to NoteRepository.updateUserAiFields
which flips the *_edited_by_user flags), inbox:delete (routes
through CaptureService so the media dir gets cleaned up),
inbox:setIntent / inbox:dismissIntent (route through
IntentService for input validation), inbox:continuity (Weekly
Continuity snapshot), inbox:pendingCount, inbox:ollamaStatus
(reads the cached HealthChecker.lastStatus()). pushNoteUpdated
helper is exported so AiWorker.onUpdate (wired in Task 30) can
fan note:updated events to the inbox renderer.
Plan deviation: HealthChecker.ts was pulled forward from
Task 29 because Task 21 imports it at compile time. The class
is small and final; Task 29 commit only ships OllamaBanner.tsx.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>