Skip to content

AI with your own key or a local Ollama — proposed, never applied #4

Description

@gillesgoetsch

Roadmap item 3, and the one with the most ways to get it wrong.

The shape, which is not negotiable

  • Your key or your machine. Either an API key you supply, or a local model over Ollama. There is no MailOh-hosted inference in the desktop app and no key of ours baked into a build — that would make a GPL binary that phones home, which is exactly what this repository exists not to be.
  • Proposed, never applied. A suggestion is rendered as a suggestion. Nothing is moved, filed, replied to or deleted because a model said so. The Screener already has the right interaction for this: the model fills in a suggested destination and the human presses the button.
  • Sensitive mail is structurally excluded, not excluded by a prompt. The protected-OTP path in the fixtures is the model for this: a message classified as protected is redacted structurally, and the exclusion is a property of the data path rather than an instruction a model can be talked out of.
  • Off by default, and visibly off. Settings must say which provider is in use, what leaves the machine, and what does not.

What it touches

  • SettingsView on both platforms: provider, endpoint, key storage (Keychain on macOS, DPAPI/libsecret elsewhere), and a model picker for Ollama.
  • The Screener's suggested-destination field, which is a fixture today — see ScreenerView on both clients. It renders already; it needs a real source.
  • Compose: draft replies. ComposeView has an honestly disabled Send; a drafted reply must land in the editor, not in the outbox.
  • A capability probe, so a machine with no Ollama and no key never shows a spinner that cannot finish.

Depends on

The engine slice. There is no point classifying a fixture mailbox — the value is in a real one, and the exclusion rules need real message structure to work on.

Acceptance

  • with no provider configured, the app behaves exactly as it does today, and the AI surfaces are absent rather than greyed out
  • with Ollama configured, no request leaves the machine (assert it the way the shell's offline guard is asserted — by making the network APIs observable in a test, not by reading the code)
  • a protected/OTP message is never sent to a provider, and a test proves it by mutating the classifier and watching the exclusion still hold
  • every suggestion has a visible, single-keystroke way to reject it

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions