Enforce a truthful local-first AI/privacy contract #23

Closed
Tyler wants to merge 0 commits from pr/03-privacy-ai-contract into main
Owner

Phase 1 of the improvement plan, PR 3 of the sequence. Mirrors GitHub PR Twest2/StepForge#7.

  • capture.captureTypedText (default false): raw keystrokes no longer buffered/emitted unless explicitly opted in; the Windows C# hook only emits CHAR events when enabled. Shortcut detection unaffected.
  • AI network: AbortController timeout (ai.timeoutMs), cancellation (ai:cancel + cancel on editor close + on shutdown), bounded concurrency, screenshot size/attach gating.
  • Local-first host policy: isLoopbackHost/validateOllamaHost; remote Ollama refused (and never contacted) unless ai.allowRemoteHost is enabled.
  • Docs: dropped false 'fully offline' claims (README/package.json/welcome screen); new docs/PRIVACY.md.

Verified: 224 unit tests incl. new AI/privacy suite; startup smoke + workflow E2E pass.

Phase 1 of the improvement plan, PR 3 of the sequence. Mirrors GitHub PR Twest2/StepForge#7. - capture.captureTypedText (default false): raw keystrokes no longer buffered/emitted unless explicitly opted in; the Windows C# hook only emits CHAR events when enabled. Shortcut detection unaffected. - AI network: AbortController timeout (ai.timeoutMs), cancellation (ai:cancel + cancel on editor close + on shutdown), bounded concurrency, screenshot size/attach gating. - Local-first host policy: isLoopbackHost/validateOllamaHost; remote Ollama refused (and never contacted) unless ai.allowRemoteHost is enabled. - Docs: dropped false 'fully offline' claims (README/package.json/welcome screen); new docs/PRIVACY.md. Verified: 224 unit tests incl. new AI/privacy suite; startup smoke + workflow E2E pass.
Tyler added 1 commit 2026-07-03 18:36:48 +00:00
Enforce a truthful local-first AI/privacy contract
Template tests / tests (pull_request) Failing after 34s
ccbb9b03dc
Phase 1 of the improvement plan (PR 3 of the sequence). The docs claimed
"fully offline"/"never talks to the network," but text-intel makes HTTP
requests to a configurable Ollama host that could be remote, with no timeout,
no cancellation, and no size limit; the Windows hook logged raw keystrokes
into capture metadata that could then be sent to that host.

Privacy — raw keystroke capture:
- New capture.captureTypedText setting, default false. With it off, printable
  characters are never buffered in JS and the Windows keyboard hook never even
  emits them across the process boundary (the flag is threaded into the C#).
  Shortcut/navigation detection (Ctrl+T, Enter, …) is unaffected.

AI network hardening (app/text-intel.js):
- Every Ollama call goes through fetchJson with an AbortController deadline
  (ai.timeoutMs, default 60s): a dead endpoint fails fast instead of leaving
  UI actions pending forever.
- Cancellation: in-flight requests are tracked and cancelInflight(guideId)
  aborts them; new ai:cancel IPC + api.ai.cancel are called when the editor
  closes, and shutdown cancels everything.
- Bounded concurrency (2) for AI network work.
- Screenshots are only attached when allowed (ai.attachScreenshots), the model
  is vision-capable, and the image is within ai.maxImageBytes — no more
  unbounded base64-expanded 4K bodies.

Local-first host policy (core/text-intel.js):
- New isLoopbackHost + validateOllamaHost. By default only a loopback Ollama
  endpoint is contacted; a remote host is refused with a clear message unless
  ai.allowRemoteHost is explicitly enabled. Blocked hosts are never contacted.

Honest documentation:
- README, package.json, and the welcome screen drop "fully offline"/"never
  talks to the network"/"Electron is the only dependency" for an accurate
  local-first contract that discloses the optional AI path and the bundled
  Tesseract OCR dependency.
- New docs/PRIVACY.md details exactly what is collected locally and the one
  outbound (opt-in, loopback-by-default) AI feature.

Tests: loopback/remote host matrix, remote-blocked-without-opt-in (and never
contacted), remote-allowed-with-opt-in, request timeout, explicit cancel vs
timeout, typed-text off-by-default vs opted-in, shortcut detection still works,
and a source guard that the C# CHAR emission stays behind the opt-in. 224 unit
tests pass; startup smoke and workflow E2E pass.

Co-Authored-By: Claude Fable 5 <[email protected]>
Author
Owner

Merged into main as c916234 (same-SHA merge to both forges; GitHub mirror PR Twest2/StepForge#7 MERGED, CI green ubuntu+windows). Closing.

Merged into main as c916234 (same-SHA merge to both forges; GitHub mirror PR Twest2/StepForge#7 MERGED, CI green ubuntu+windows). Closing.
Tyler closed this pull request 2026-07-03 18:39:18 +00:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Tyler/StepForge#23