Vision · Progress Review · Research Synthesis · 2026-07-03

ollwrite on-device — the local-first vision.

ollwrite becomes an AI writing studio that runs on the user's machine — the model, the memory/knowledgebase, and fast semantic search all local; nothing leaves the device. This is the honest synthesis: what's already built that de-risks it, what the research actually says (some of it corrects the naive dream), why "going local" is a backend swap, not a rewrite, and — front and centre — why this is the after-the-first-dollar arc, deliberately sequenced so Phase 0 (the humaniz franc) is never displaced.

🧭 debut = device install · WebGPU skipped ✅ the ollama provider is already coded in oll-model 7–8B is the floor · 1–3B fails Phase-1+ only · NOT before the first franc
This extends the ollwrite series — the spec, the product & architecture design, the GUI study — with the on-device thesis. Placement grammar (External / Internal / On-device) lives on The Platform (ADR-023). Order of record stays the Backlog.

01The vision in one line

An on-device, local-first AI writing studio — the model, your memory, and fast semantic search all run on your machine. Nothing leaves it.

ollwrite proves the pattern first. Once it works, the same three-part local stack — inference + a local knowledgebase + on-device search — becomes an oll-am on-device platform, delivered as an installable MVP. The debut is the device install, not a webapp (Sam, 2026-07-03): the Vault promise — pull the network and keep working, everything on your own disk — is something a browser tab structurally cannot make good on. Writing quality is validated separately by the existing cloud write.oll.am; this POC proves offline-native.

This is the deepest expression of the house line — "any AI model, without a subscription — pay once." "Pay once" is only fully honest when there is no per-call bill downstream, and that is exactly what on-device inference gives you: after the model is on the device, editing is free forever.

02Progress review — how much is already built

The single most de-risking fact: the local path is not a green-field build. The provider switch that makes "go local" a config flag is already in the codebase, verified by reading it.

✅ The oll-model gateway already has the ollama provider

services/oll-model/config.py declares LLM_PROVIDER with three branches — groq · claude · ollama — documented in the file itself: "ollama — an on-box model, NO per-call API bill (the 'pay once' path)." Boot gating is provider-aware: only the chosen provider's key/URL is demanded at startup, and the local branch requires only OLLAMA_BASE_URLno cloud key at all. The DTO documents a per-call provider override: 'groq' | 'claude' | 'ollama'. So the same write-service call runs cloud OR local by flipping one env var.

Here is the real boot-gate — the reason the local path needs no cloud secret:

# services/oll-model/config.py  (verbatim, trimmed)
LLM_PROVIDER = os.environ.get("LLM_PROVIDER", "groq").lower()

# REQUIRED_ENV is PROVIDER-AWARE: only the chosen provider's key/URL
# is demanded at boot (the local "pay once" provider needs no cloud key).
if   LLM_PROVIDER == "groq":   _REQUIRED.append("GROQ_API_KEY")
elif LLM_PROVIDER == "claude": _REQUIRED.append("ANTHROPIC_API_KEY")
elif LLM_PROVIDER == "ollama": _REQUIRED.append("OLLAMA_BASE_URL")

OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "http://localhost:11434")

The KEY unlock

We do not rebuild ollwrite to go local. We point it at a local backend. The provider switch is the seam.

write-service = thin Core client

services/write/text_client.py is the sole HTTP boundary to oll-model; llm_client.py owns write's own prompts. Product logic is already decoupled from the model backend.

ollwrite GUI shipped

Three design docs + the real /editor restyled as the premium Manuscript editor — design→build in 6 increments, #1 shipped & dev-verified.

The research is done

A full on-device-writing feasibility & market study already exists in research/. Its verdicts are synthesised in §03 — including where they correct the naive braindump.

03Research verdict — honest, and it corrects the dream

Numbers below are directional (benchmarks, market sizes). The conclusions are strong enough to design against; the caveats are real enough to respect.

① Model size is the dividing line — 7–8B is the floor, 1–3B fails

The naive dream — "a few tiny models that fit the hardware" — does not survive contact with the benchmarks. Sub-3B models (Gemma 2B, TinyLlama) hallucinate materially (~13.8% vs ~0% for frontier in BLESS human eval) and, damningly for a clarity tool, they lengthen text instead of tightening it — the opposite of the product's whole purpose. Gemma 2B also fell ~3× behind on grammar. The sweet spot is Llama 3.1 8B / Gemma 2 9B / Qwen 8B / Mistral 7B, 4-bit quantized. So "small enough to fit" only works if the smallest is ~7–8B — a genuine constraint (needs ~8GB+ of GPU/unified memory and a multi-GB download), not free.

② WebGPU is a demo, not the product — the debut is a device install

The research liked WebGPU for onboarding: WebLLM runs Llama 3.1 8B (4-bit) at ~41 tok/s on an M3 Max in a browser tab (~71–80% of native), and WebGPU now ships by default in all four major browsers (~83–84% coverage). Zero install, widest reach. But that finding is overruled here — for a decisive reason:

🧭 Decision (Sam, 2026-07-03): skip WebGPU, go direct to the device-install POC

WebGPU gives local inference — but it can never give the actual Vault promise. A browser tab loads its shell from a server, keeps data in an evictable IndexedDB sandbox, has no real filesystem, and needs the network for first load and updates. "Pull the cable and keep working — corpus, index, model, processing all on your own disk" is not deliverable in a browser.

Vault isn't "a local model." It's data sovereignty + offline-complete operation, and that is a native install, full stop. WebGPU was always going to be a demo that can't fulfil the core promise — so we skip the half-measure and make the device install the POC. The cloud write.oll.am webapp already covers "is the writing any good?"; the POC exists to prove the one thing the web literally cannot: offline-native.

tradeoff accepted: no zero-install "anyone with a link" funnel — first value now costs a multi-GB download + install. That's the price of a promise the browser can't keep.

③ The killer feature is the per-rewrite tier switch — not "local" alone

The differentiator is choosing your privacy/quality level per rewrite:

🔒 Vault

On-device 8B via bundled Ollama. Unlimited, free after purchase. Nothing leaves the machine — works with the network unplugged. Default for the bulk of edits.

provider = ollama · cost-to-serve ≈ $0 · offline-complete

⚖️ Balanced

Private server (Groq/Llama). Fast, low cost — optional, for bigger jobs or a device too weak for the local 8B (requires network, so not Vault).

provider = groq

⚡ Turbo

Claude, metered. One click when 8B isn't good enough. Reintroduces the recurring revenue pure pay-once sacrifices.

provider = claude

This turns the honest 8B quality gap into a feature: "no, it's not Claude-grade — but it's good enough for most edits, and when it isn't, one click escalates." Local by default; escalate on demand. Note each tier maps one-to-one onto the provider field the gateway already accepts — the tier switch is literally the provider override, surfaced in the UI.

④ A fine-tuned small clarity model beats a generic large one

Grammarly's own CoEdIT is the proof: a 3B fine-tune beat 175B GPT-3-Edit, preferred 64% vs 10% in human eval. The path is therefore prompt-engineer / RAG first, fine-tune a clarity model later — do not ship vanilla Llama and call it done. Raw open models hallucinate too much; the CoEdIT precedent says a dedicated small model closes the gap.

⑤ Economics: on-device cost-to-serve ≈ $0 after delivery

This inverts the competitor model. Grammarly sustains ~80% margins but carries continuous inference cost that grows with usage; every Vault user, by contrast, is pure margin after the sale. Precedent for pay-once sustainability: iA Writer, Scrivener, Hemingway. Price the Vault tier at ~$39–49 one-time inside oll.am (anchored against Hemingway $19.99 and OpenWriter $39.99).

⑥ Competitor & moat

OpenWriter ($39.99 one-time, local llama.cpp) is the only direct competitor — and it's still "Coming Soon." It validates the category without locking it. The moat is structural: incumbents like Grammarly ($700M ARR) can't follow — unlimited on-device rewriting cannibalises their subscription inference revenue (the disruptor's-dilemma wedge). Privacy is an ownable trust angle, with one hard rule from Sam's memory:

⚠️ Positioning guardrail (locked)

Never claim "Swiss-hosted" / data-residency, and never name the cloud provider or its location (the VPS is Frankfurt). Use only true privacy claims — for the on-device tier, the honest and powerful one is "nothing leaves your machine."

04On-device building blocks — Sam's parts, made concrete

The on-device stack
ollwrite UI
Angular / Plate editor — the Manuscript surface
▼ ▲ queries memory + issues ops
① Inference
Bundled Ollama sidecar — one 7–8B model, on local disk. Speaks the oll-model provider contract. Runs offline.
② Local vector DB / memory
sqlite-vec or LanceDB — embedded, no server, fast on-device ANN. Local embeddings via nomic-embed-text / bge-small.
③ Personalization
RAG style transfer FIRST (your passages as few-shot + a style card); fine-tune later.
④ Citation / verify
Same vector store grounds claims — retrieve source passages you added, cite/verify against them.
⑤ Transcription
whisper.cpp / faster-whisper local — LATER phase. "Listen, transcribe, store."
everything above runs on the device — nothing leaves it

The honest packaging correction

An installable that "gets Ollama" is a desktop app — Tauri with an Ollama sidecar binary (tiny, Rust) or Electron. Capacitor/mobile cannot carry 8B models, so the installable MVP is desktop-first, not phone. Sam's house stack is Angular/Ionic/Capacitor (web + mobile); the desktop installable is a new delivery target. Recommendation: Tauri, reusing the existing Angular frontend inside its webview.

05The architecture insight — local is a SWAP, not a rewrite

Because product logic (write-service) already calls the oll-model gateway over a fixed contract, and the gateway already has the ollama provider, "going local" reduces to two additive moves: swap the model backend (flip the provider) and add a local vector store the UI queries for memory + RAG. The Core contract (auth / billing) is untouched.

the request path — and the one parallel addition
ollwrite Angular UI
the editor
write-service
product logic (prompts) · thin client
oll-model gateway
provider switch: groq | claude | OLLAMA
swap = flip the flag
the UI & product also query, in parallel ↓
local vector store
sqlite-vec / LanceDB — memory + RAG + citation. The one net-new piece.
Core (auth / billing)
UNCHANGED — magic-link + Stripe, frozen
no change

The vision is cheap relative to its ambition — because the seams were built in before we needed them.

This is the Clean-Code / dependency-inversion payoff made real: write-service depends on an abstraction (the gateway's provider-agnostic contract), not on a concrete vendor. Swapping Groq→Ollama changes a value, not a shape. That's why an idea this ambitious costs a config flag plus one embedded database, not a re-platform.

06Phased roadmap — respects the ship-vs-build guardrail

Phase 0 comes first, and this vision does not touch it

The plan of record's single P0 is closing the humaniz.me money path (prompt fix + credit pack + Reddit — the fastest free dollar this week). The on-device platform must not displace it. Named once, plainly: Sam is a strong builder whose gap has always been monetizing a finished asset, not writing code. This on-device vision is the after-first-dollar arc — captured and ready here so it exists, deliberately sequenced so it never pulls focus from revenue.

  1. Phase 0 — NOW, UNCHANGED: the first stranger franc. do this Close the humaniz money path. Nothing below starts until a stranger pays.
  2. Phase 1 — the device-install POC (Tauri shell + bundled Ollama sidecar + one 7–8B model + local sqlite-vec store). after franc Wraps the shipped ollwrite editor and runs a local oll-model gateway with provider = ollamareusing existing code. Proves the one thing the web can't: offline-native writing with local memory.
  3. Phase 2 — memory / RAG / style learning on the local store. after franc Add a resource → embed → retrieve; style card + few-shot from the user's own corpus; citation/verify against retrieved passages.
  4. Phase 3 — the sellable installable later = offline license (pay-once, validated locally), code-signing / notarization, auto-update = the oll-am on-device platform.
  5. Phase 4 — transcription / listen-and-store later (whisper.cpp local).

🎯 The POC, scoped — and its one acceptance test

Build (minimal): ① a Tauri desktop shell reusing the existing Angular editor in its webview; ② an Ollama sidecar + one 4-bit 7–8B model (e.g. Llama 3.1 8B / Qwen 8B) + nomic-embed-text for embeddings; ③ a local oll-model gateway instance with provider = ollama — the existing code, no rewrite; ④ a local SQLite + sqlite-vec store: add a document → embed → retrieve on rewrite.

Definition of done = the airplane-mode test: disconnect the network, open a draft, retrieve from the local store, and get a rewrite back. If that works with the cable pulled, the thesis is proven.

Deferred (not in the POC): the offline license / pay-once entitlement, code-signing & notarization, auto-update, a second model or model-picker, transcription, style fine-tuning. Ship one model, one flow, offline.

⚠️ Consequence to lock now: entitlement must be offline-checkable

Pay-once Vault means the app cannot phone home to check a subscription on each launch — that would break airplane-mode, the whole promise. So entitlement is a signed license file validated locally (buy once online → receive a license → the app verifies it offline). This is a clean fit for pay-once and a genuine departure from Core's JWT/subscription model — worth designing deliberately, but only at Phase 3 (the POC needs no license gate).

07Open decisions for Sam

08Risks & honesty caveats

Status: vision + progress review + research synthesis, captured 2026-07-03; debut decision locked the same day — device-install POC, WebGPU skipped (the browser can't keep the offline-complete Vault promise). The de-risking headline is verified in-code: the oll-model gateway already carries the ollama provider with provider-aware boot gating, so going local is a backend swap plus one embedded vector store, not a rewrite. Honest corrections baked in: 7–8B is the floor (1–3B fails), the Vault/Balanced/Turbo per-rewrite tier switch is the actual differentiator, RAG-before-fine-tune, Tauri + bundled Ollama for the installable, and entitlement must be offline-checkable. Sequencing is locked to the guardrail: Phase 0 (the humaniz franc) is untouched; everything here is the after-first-dollar arc. Order of record stays the Backlog; the product surface is in the ollwrite design.