Files
inkling/docs/handoff/2026-04-25-linux-to-windows.md
altair823 ccc166917a Record native-Windows-vs-WSL decision and LAN Ollama implication
Adds to handoff: rationale for choosing native Windows over WSL2
(global hotkey, OS notifications, clipboard image, tray, data path,
performance measurements all break under WSLg). Pre-flight
checklist updated so Ollama runs on a LAN server, not on the
Windows machine. Notes the one-line env-var change needed in Plan
Task 30 to wire LocalOllamaProvider to a LAN endpoint, and clarifies
that this is configuration (not a new Provider class).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 02:15:10 +00:00

16 KiB
Raw Blame History

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.mdspec v0.2 (load-bearing)
  4. docs/superpowers/plans/2026-04-24-inkling-vertical-slice.mdimplementation 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 15): project init, Electron entry + Inbox shell, typed preload, logger, paths.

Data layer (Tasks 69): 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 1013): 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 1417): CaptureService (with enqueue + celebrate hooks), NotificationService (4 rotating reward copies via SHA-256 mod 4), IPC captureApi, HotkeyService.

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

Inbox (Tasks 2028): 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 2931): HealthChecker + OllamaBanner, tray with v0.2 copy + main entry final wiring, MediaGc.

Verification (Tasks 3233): 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
    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.