# CapsNav Privacy and Security Note

This note is the short customer-facing explanation for the commercial Windows GUI. Keep it factual and update it before every paid release if storage, sync, billing, support, or update behavior changes.

## Local Keyboard Access

CapsNav uses a local keyboard hook so CapsLock combinations can trigger cursor movement, selection, editing, and profile-defined actions. The hook runs on the user's Windows device.

The managed keyboard runtime does not send keystrokes, active window titles, typed text, clipboard contents, documents, screenshots, or application content to CapsNav services.

When app exclusions are enabled, the core reads the foreground process executable name, such as `code.exe`, to decide whether remapping should pass through. It does not need the document name or window title for that decision.

## Local Files

Installed Windows builds store local state under `%APPDATA%\capsnav` and local support logs under `%LOCALAPPDATA%\capsnav\logs`.

Important local files include:

- `config.toml`: active keyboard mapping config.
- `profiles.json`: closed-GUI profile list and profile snapshots.
- `commercial-state.json`: account status, pseudonymous device binding, sync queue metadata, and local access state.
- `runtime-entitlement.lease`: short-lived, server-signed trial or paid runtime entitlement. It contains no password or License Key.
- `gui-events.jsonl`: recent closed-GUI runtime errors used for support diagnostics.
- `support\capsnav-support-<timestamp>.json`: support bundle generated only when the user or QA flow exports it.

Portable builds keep using an adjacent `config.toml` when one exists beside the executable.

## Account, Trial, Device Identity, and Cloud Sync

Pro sync sends only the data needed for account and profile synchronization:

- email address and password during account registration or sign-in over HTTPS,
- optional License Key when creating an already-paid account or resetting a password,
- pseudonymous stable device id and user-visible device name,
- profile name, profile scope, profile mapping count, updated timestamp, and TOML profile snapshot,
- sync action metadata such as upload, list, download, or delete.

Passwords are never stored in plaintext. The service stores a per-account salted PBKDF2-SHA-256 password hash and uses a separate server-side pepper. License keys are stored as SHA-256 hashes with a short display hint. The GUI stores only a License Key hint, a device-bound account token, and a short-lived signed runtime lease. Support bundles redact both tokens and do not include full profile TOML snapshots.

On Windows, the app reads the system `MachineGuid` locally and hashes it with an CapsNav namespace to produce a stable pseudonymous device id. The raw `MachineGuid` is not sent to CapsNav. The service hashes the pseudonymous id again before placing it in the one-trial-per-device ledger. This allows a normal uninstall/reinstall to recognize the same device. Reinstalling Windows, virtual machines, cloned images, or manual system-identity changes can change this identifier.

Each email account and each Windows device may participate in one 30-day trial. The server keeps irreversible email and device hashes needed to prevent repeated trials even after the trial expires. Trial and device anti-abuse records are not removed merely by uninstalling the app.

Account, permanent-license, update-service, device-seat, and profile metadata are stored in Cloudflare D1. Profile TOML snapshots are stored in Cloudflare R2 while update service is active. Trial and one-device licenses include one active device; three-device licenses include three. Users can inspect connected devices and disconnect old devices. Extra device seats are recorded only after a verified billing webhook.

Ten failed passwords within fifteen minutes temporarily lock further sign-in attempts for fifteen minutes. Cloudflare edge rate limits also protect authentication, checkout creation, account, and sync endpoints.

The commercial keyboard runtime requires a valid trial or permanent license. The GUI refreshes a short-lived signed runtime lease on startup, when the window returns after a long interval, and every six hours while signed in or using an anonymous Trial. The lease lasts no more than 24 hours and never extends beyond trial expiry; a permanent license remains valid when update service expires. The adjacent `CapsNavCore.exe` is the managed keyboard runtime, not an alternate unlocked application: launching it without a valid signed lease exits before installing the keyboard hook. When a trial expires, a permanent license is revoked, or a valid lease is unavailable, the keyboard runtime is disabled by default; local profile files remain available for later activation or export.

## Support Bundles

Support bundles are written locally and are not uploaded automatically. A bundle can include:

- managed-runtime diagnostics and recent runtime log lines,
- profile summaries without full TOML snapshots,
- redacted commercial account and sync queue state,
- recent closed-GUI runtime events,
- service health, production readiness, warnings, and failures.

Support staff should ask users to inspect or share the generated support bundle only when troubleshooting.

## Updates and Signing

Commercial GUI update checks read the configured release manifest URL. Downloads are saved under `%APPDATA%\capsnav\updates`, checked against the manifest SHA256, and verified with Windows Authenticode before the GUI starts an installer.

Production builds should set `CAPSNAV_SIGNER_SUBJECT` so the GUI requires the expected publisher subject before launching a downloaded installer.

## Service Boundaries

The GUI calls the account, trial, sync, update, and billing-backed services. The managed keyboard runtime verifies a signed lease locally and does not receive passwords, License Keys, or billing credentials.

Billing webhooks are server-to-server only. The GUI never calls billing ingestion endpoints.

## User Controls

Users can:

- start one 30-day trial by creating an email/password account,
- sign out while keeping local config and profiles; signing out disables the keyboard runtime,
- review connected devices and disconnect devices other than the current session,
- export support data locally,
- uninstall the app through Windows uninstall flow,
- disable auto-launch through the app or uninstall flow.
