# Session Handoff — Linux → Windows

**Date:** 2026-04-25
**Source:** Linux dev machine (Claude Code session)
**Target:** Windows dogfood machine (fresh Claude Code session)
**Reason:** Windows is the dogfood-priority platform (per spec §1.1). Implementation/test cycle should run there.

---

## TL;DR for the next session

Read these files first, in this order:

1. `inkling.md` — original product brief (v1.4)
2. `docs/superpowers/strategy/strategy.md` — psychology-based habit strategy
3. `docs/superpowers/specs/2026-04-24-inkling-vertical-slice-design.md` — **spec v0.2** (load-bearing)
4. `docs/superpowers/plans/2026-04-24-inkling-vertical-slice.md` — **implementation plan v0.2** (33 tasks, TDD)
5. This handoff doc

Then ask the user: "Spec v0.2 and plan v0.2 are committed but not yet implemented. Want me to start Task 1 (project bootstrap), or pick up from a specific task?"

The project is a git repo with 7 commits. No application code written yet. Slice is 33 TDD tasks ahead.

---

## What was decided (chronologically)

The Linux session ran `/brainstorming` twice and `/writing-plans` once. Each decision below was made jointly with the user. Don't relitigate.

### Brainstorming round 1 (initial slice scope)

Q1: **Vertical slice approach** chosen over foundation-first or UI-shell-first. Goal is a single end-to-end path: Quick Capture → SQLite → Local Ollama → Inbox. Reason: only this proves both core hypotheses (3-second capture friction, AI quality).

Q2: **Text + screenshot input** in slice. Voice/STT deferred to follow-up.

Q3: **Both Windows + macOS Electron from day 1**, with **Windows as dogfood priority** and macOS as build-passing-only. Tech stack already locked by spec §6.2: Electron + React + TypeScript.

Q4: **AI scope = title + 3-line summary + ≤3 tags.** Related-notes link and project classification deferred.

Q5: **Inbox = list + AI-field edit + delete.** Original always read-only. Manual AI re-process deferred.

Q6: **Habit engine = streak display only, no notifications**, in slice v0.1. Later upgraded in round 2 to Weekly Continuity (see below).

User then said "잘 따라옴, 작성해" → spec v0.1 written.

### Strategy doc shows up

User added `docs/superpowers/strategy/strategy.md` and said "매우 중요한 스펙들을 놓쳤어" → re-ran `/brainstorming` for Strategy integration.

### Brainstorming round 2 (Strategy integration)

Q1: **Group-A items in slice** (UX copy, post-submit reward toast, AI proposal labels, 5 product principles, recovery-friendly streak copy) + **Group-B partial** (one-line intent question, Weekly Continuity). Templates and onboarding deferred.

Q2: **Intent question = AI-done banner with skip option.** Variant A chosen. Stored in `notes.user_intent`, gated by `notes.intent_prompted_at`.

Q3: **Weekly Continuity = KST 월~일, target N건/주.** Initially proposed 3, user **bumped to 7**. Recovery toast on ≥7-day gap. Streak Freeze deferred.

Q4: **AI proposal label = per-field gray "AI" badge.** Disappears once `*_edited_by_user` flag flips. Tag source already distinguished. Schema columns added.

Q5: **All copy strings + tray menu copy + 5 product principles in spec §0.1 + native OS notification for reward toast.** Recovery-friendly tone enforced ("실패", "끊김", "연속 실패" forbidden).

Spec v0.2 + plan v0.2 then committed.

---

## User profile (carry into memory on Windows)

- **Name:** 김태현 (dlsrks0734@gmail.com)
- **Role:** IT 기획자, the persona in `inkling.md` §2.2. Building this app for himself first, then 10-person internal beta.
- **Language:** Speaks Korean. All product copy and AI output target Korean. Tags stay English kebab-case for clustering. Internal explanations from assistant should stay Korean (caveman-style is on, see below).
- **Hardware split:** Mac for company work, Windows for personal/side projects + Inkling dogfood. Has nvm available on Linux; Windows side will need nvm-windows or Volta.
- **Preferences:**
  - Latest LTS Node + latest stable major libraries. Current pin: Node 24.15.0 (Krypton). Update spec §7.2 + `package.json` together if newer stable surfaces during install.
  - Auto mode active in last session (execute autonomously, minimize interruptions).
  - Caveman mode active in last session (drop articles/filler/pleasantries, fragments OK, technical substance preserved). Default level: full. Code/commits/security: write normal.
  - Korean responses required regardless of caveman intensity.
- **Workflow expectations:** Comfortable with one-question-at-a-time brainstorming, design-then-plan-then-execute. Approves succinctly ("응" / "B" / "응 그리고 ...").

---

## Project state at handoff

**Git:** initialized repo, branch `main`, 7 commits (no remote yet). No tags.

```
a5afdc5 docs(strategy): Inkling 심리학 기반 습관화 전략 문서 추가  ← user added
35f900b Rewrite implementation plan to v0.2 with Strategy integration
c7bfd15 Update vertical slice spec to v0.2 with Strategy integration
4b25ba3 Add vertical slice implementation plan                      ← v0.1 (superseded)
cdb329e Pin Node 24.15.0 LTS via .nvmrc
e22194b Add tech stack and version policy section to vertical slice spec
bbbe292 Add vertical slice design spec for Inkling MVP              ← v0.1 (superseded)
```

**Files in repo:**
- `.nvmrc` (24.15.0)
- `inkling.md` (product brief)
- `docs/superpowers/strategy/strategy.md` (psychology strategy)
- `docs/superpowers/specs/2026-04-24-inkling-vertical-slice-design.md` (v0.2)
- `docs/superpowers/plans/2026-04-24-inkling-vertical-slice.md` (v0.2, 33 tasks)
- `docs/handoff/2026-04-25-linux-to-windows.md` (this file)

**No code yet.** No `package.json`, no `src/`, no `tests/`, no `node_modules/`.

---

## Implementation plan summary (33 tasks)

**Bootstrap (Tasks 1–5):** project init, Electron entry + Inbox shell, typed preload, logger, paths.

**Data layer (Tasks 6–9):** SQLite migration v1 (with `user_intent`, `intent_prompted_at`, `title_edited_by_user`, `summary_edited_by_user` columns), NoteRepository (with edited-flag overwrite guard), MediaStore, ContinuityService (Weekly Continuity, KST Mon-Sun, 7 notes/week, recovery detection).

**AI layer (Tasks 10–13):** zod schema validator (Korean title required, kebab tag filter, summary normalization to 3 lines), prompt template, InferenceProvider interface, LocalOllamaProvider (120s timeout), AiWorker (3-attempt backoff: immediate / 30s / 120s).

**Capture (Tasks 14–17):** CaptureService (with `enqueue` + `celebrate` hooks), NotificationService (4 rotating reward copies via SHA-256 mod 4), IPC captureApi, HotkeyService.

**Quick Capture (Tasks 18–19):** frameless 640x280 popup, React UI with paste-image + ctrl-enter + esc.

**Inbox (Tasks 20–28):** IntentService, IPC inboxApi, React shell + Zustand store + recoveryToast helper, ContinuityBadge, PendingBanner, NoteCard (AI labels + IntentBanner slot + intent badge), EditableField, IntentBanner (4 rotating prompts), RecoveryToast.

**Wiring (Tasks 29–31):** HealthChecker + OllamaBanner, tray with v0.2 copy + main entry final wiring, MediaGc.

**Verification (Tasks 32–33):** Playwright smoke + manual dogfood checklist (Strategy + base flows).

Each task is bite-sized, follows red → green → commit. No batching.

---

## Windows-specific gotchas to anticipate

- **Node install:** `.nvmrc` says `24.15.0`. nvm-windows uses different syntax (`nvm install 24.15.0` then `nvm use 24.15.0`). Volta auto-detects `.nvmrc`. Either is fine — user's choice.
- **Native modules:** `better-sqlite3` requires a C++ build chain on first install. On Windows: `npm install --global windows-build-tools` is deprecated; the modern path is Visual Studio Build Tools 2022 with "Desktop development with C++" workload. If install fails, this is the first thing to check.
- **Ollama:** must be running with `gemma4:9b` pulled before AI tests work. `ollama serve` (background) + `ollama pull gemma4:9b`. Health check expects `http://localhost:11434/api/tags` to list `gemma4:9b`.
- **Global hotkey conflict:** `Ctrl+Shift+J` on Windows can collide with Chrome DevTools or Edge DevTools when those apps have focus. Pre-flight check: close DevTools-using apps before dogfood.
- **OS notification permission:** first `new Notification(...)` triggers a Windows toast permission flow. If denied, NotificationService falls back silently — capture still works. User can re-enable via Settings → Notifications → Inkling.
- **Code signing:** out of scope for this slice. `electron-vite` produces unsigned dev build. Windows Defender SmartScreen may warn on first launch — click "More info" → "Run anyway".
- **File paths:** `app.getPath('userData')` returns `%APPDATA%\Inkling\...` on Windows. Logs and DB end up there. Tests use `:memory:` SQLite + tmpdir for media — no Windows-specific issues expected.
- **Line endings:** `.gitattributes` not yet set. Recommend adding `* text=auto eol=lf` to prevent CRLF noise in tests. Optional for slice.
- **Playwright Electron E2E:** `_electron.launch({ args: [resolve('out/main/index.js')] })` works cross-platform. Build (`npm run build`) before E2E.

---

## Memory hints for the new session

The new Claude Code session on Windows will start with empty memory dir. Recommend writing these on day 1:

- **user (file: `user_profile.md`):** Role + Korean preference + hardware split + LTS preference + caveman/auto-mode habits. Source: this handoff §"User profile".
- **feedback (file: `feedback_brainstorm_style.md`):** User responds to one-at-a-time multiple-choice questions tersely ("응" / letter pick). When confirming a non-obvious choice (like bumping weekly target from 3 to 7), note it as validated judgment, not casual approval.
- **feedback (file: `feedback_caveman_mode.md`):** Caveman mode (full) is on and is the user's default. Drop articles/filler/pleasantries. Code/commits/security write normal. Korean output required regardless.
- **project (file: `project_inkling_status.md`):** As of 2026-04-25, spec v0.2 + plan v0.2 are committed but no code. Slice = vertical slice MVP. Aha Moment is "7-day-3-consecutive-records" (KPI §7.1 of inkling.md) but slice itself measures via 2-week dogfood completion (spec §1.3). **Why:** verify whether plan execution should proceed or whether scope/tech decisions need refresh based on Windows reality.
- **reference (file: `reference_docs.md`):** Spec at `docs/superpowers/specs/2026-04-24-inkling-vertical-slice-design.md`, plan at `docs/superpowers/plans/2026-04-24-inkling-vertical-slice.md`, strategy at `docs/superpowers/strategy/strategy.md`, product brief at `inkling.md`. Always check these before recommending architecture changes.

---

## Load-bearing invariants (do not relitigate)

- **`raw_text` is immutable.** No update method exists. Don't add one. (Spec §3.3, principle 1)
- **AI re-runs do not overwrite user-edited title/summary.** Guard via `*_edited_by_user` columns + CASE WHEN in `updateAiResult`. (Spec §3.3, Plan Task 7)
- **IntentBanner appears exactly once per note.** Gate: `intent_prompted_at IS NULL`. Both setIntent and dismissIntent close the gate. (Spec §3.3, Plan Task 22+27)
- **Logs never contain `raw_text`/`ai_title`/`ai_summary`/`user_intent` content.** Only IDs, lengths, hash prefixes. (Spec §6.2, Plan Notes)
- **The words "실패", "끊김", "연속 실패" are forbidden in all UI strings in this slice.** Recovery-friendly tone enforced. (Spec §1.1, Plan Notes)
- **Native notifications must never block submit.** Permission denied = silent fallback. (Spec §6.1 row 10, Plan Task 15)
- **Versions are pinned exactly (no `^`).** Update spec §7.2 + `package.json` together if `npm install` reveals a newer stable major. (Spec §7.1, Plan Task 1)

---

## Suggested first messages on Windows

If the user wants to start fresh execution:

> Read `docs/handoff/2026-04-25-linux-to-windows.md`, then the spec and plan it points to. Once oriented, ask whether to begin Task 1 of the plan (project bootstrap) or to do a quick Windows-environment sanity check first (Node version, build tools, Ollama running).

If the user already started a `git status` and there are local changes (e.g. `node_modules` after a partial install):

> Don't squash or destroy any work. Inspect first. The plan begins from a clean state with no dependencies installed.

---

## Decision: Native Windows over WSL2 (2026-04-25)

User asked whether to use WSL Ubuntu 24.04 or native Windows. **Native Windows chosen.** Reasons:

1. **Global hotkey** — WSL Electron cannot register a Windows OS-level shortcut. `Ctrl+Shift+J` from real Windows apps (Chrome, Slack, Excel) won't reach WSL Electron. Spec §1.1 core feature broken; "3-second friction" hypothesis (Spec §0 hypothesis 1) untestable.
2. **OS native notifications** — WSLg cannot bridge libnotify to Windows action center. Strategy §4.1 immediate-reward toast invisible when user is in another app.
3. **Clipboard image paste** — WSLg image clipboard is unreliable. In-scope screenshot flow (Spec §1.1) breaks.
4. **Tray icon** — WSLg has no system tray API. Tray menu, close-to-hide, "구출한 메모 보기" entry path (Spec §5.5) gone.
5. **Data path** — `\\wsl$\...` instead of `%APPDATA%\Inkling\`. User can't browse data via Explorer.
6. **Performance numbers** — "hotkey → window p95 < 100ms" measurement skewed by WSLg compositor.

Dev-DX cost (less Linux-shell familiarity) is single-session pain. Dogfood-hypothesis cost (WSL silently breaks the slice) is fatal.

**Hybrid recommendation:** core dev (npm/Electron) on Windows native; WSL allowed only as auxiliary for Linux utilities (`grep`/`find`/`jq`) when convenient.

### Pre-flight checklist for the Windows machine

1. Node 24.15.0 LTS via **nvm-windows** or **Volta**
2. **Visual Studio Build Tools 2022** + workload "Desktop development with C++" (required for `better-sqlite3` native compile)
3. **Ollama on a LAN server** (not on the Windows machine). User-defined IP, e.g. `http://192.168.x.y:11434`. Pre-pull `gemma4:9b` on that server. Confirm reachable from Windows: `curl http://<lan-ip>:11434/api/tags` should list `gemma4:9b`.
4. **Git for Windows**
5. Editor (VS Code, Cursor, etc.)
6. **Claude Code for Windows**

### Implication for slice plan/spec (LAN Ollama)

The slice plan currently wires `new LocalOllamaProvider()` with no args (defaults to `http://localhost:11434`) in **Plan Task 30 main entry**. Since the dogfood machine reaches Ollama over LAN, that one line needs adjustment. Two minimal-change paths:

- **Env var (recommended):** change the Task 30 instantiation to
  ```ts
  const provider = new LocalOllamaProvider({
    endpoint: process.env.INKLING_OLLAMA_ENDPOINT
  });
  ```
  `undefined` falls back to localhost (preserves Linux/local-Ollama dev). Set `INKLING_OLLAMA_ENDPOINT=http://192.168.x.y:11434` in Windows env (User-level Environment Variables) before running `npm run dev`.
- **Hardcode for dogfood:** pass the LAN URL directly during dogfood; revert before any commit. Simplest but not committable.

Spec §1.2 lists "LAN Ollama Provider" as deferred, but that meant a separate `LanOllamaProvider` *class*. `LocalOllamaProvider` already accepts a custom `endpoint`, so this is configuration, not new code. The Provider abstraction (Spec §2.2) was designed for exactly this.

The new session should ask the user whether to fold the env-var change into Task 30 (preferred) or treat it as a one-off dogfood hardcode.

Health-check expectations under LAN:
- LAN unreachable (server off, wrong IP, firewall) → OllamaBanner shows "Inkling 정리가 잠시 멈췄습니다. Ollama를 실행해주세요." Capture continues normally; pending notes accumulate. Spec §6.1 row 4 behavior unchanged.
- 120s generate timeout (Plan Task 12) is generous enough to absorb LAN latency on slow GPUs. No tuning needed initially.

---

## What this session did NOT do

- No code written
- No `npm install` run on Linux
- No tests run
- No Ollama model downloaded or benchmarked
- No remote git pushed (no GitHub URL exists)
- No CI configured

The new session inherits a clean greenfield with one design and one plan. Execution is the next phase.
