# Spec: AI Models Settings Page

> **Purpose:** Builder-facing BrainDrive product/engineering spec for the existing AI Models page in Settings.
> **Generated from:** Product request and current implementation review on 2026-07-09.
> **Primary product surface:** Local-mode Settings modal, `AI Models` tab.
> **Recommendation:** V1 should keep `BrainDrive Models` as the recommended first path while preserving direct `OpenRouter` BYOK and `Ollama` choices as independent alternatives. Managed-hosted mode should not expose local provider controls unless a separate managed-provider-switching scope is approved.

## Overview

### What This Covers

The AI Models Settings page lets a local BrainDrive owner choose how BrainDrive connects to AI models, configure provider credentials safely, buy or repair BrainDrive Models credits, choose the default model used by conversations, and manage local Ollama model availability.

The current local-mode page supports three provider profiles:

1. `BrainDrive Models` - recommended provider, credit-backed, key provisioned or repaired through the local gateway and encrypted vault.
2. `OpenRouter` - owner-supplied API key, OpenAI-compatible cloud model catalog, default model selection.
3. `Ollama` - local or reachable Ollama server URL, installed model catalog, model pull, model delete, and optional remote API key.

This spec covers the owner-facing behavior, gateway/API contracts, persistence rules, trust boundaries, tests, and future-safe recommendations for the AI Models page. It is intended to become the source of truth for product review, implementation planning, QA, and future agents.

### Why It Matters

BrainDrive depends on model access to provide chat, agent, and tool-loop behavior. A local owner must be able to start successfully without learning provider mechanics, while still retaining owner choice and control. The settings page is also a trust boundary: it touches paid credits, raw API keys, encrypted secrets, provider base URLs, model identifiers, local model downloads/deletes, and the active runtime adapter used for future conversations.

The page is unsuccessful if it makes BrainDrive Models credits a requirement for local ownership, leaks API keys to client-readable settings or logs, hides BYOK/local alternatives, or lets a provider switch silently break the next conversation without a recoverable path.

### Target Audience And Stakeholders

| Audience | Role / Need |
|---|---|
| Local BrainDrive owner, non-technical | Needs the easiest safe path to working model access without understanding API keys, provider profiles, model IDs, or local model servers. |
| Local BrainDrive owner, technical | Needs explicit provider choice, BYOK OpenRouter, Ollama URL control, model catalog selection, and predictable runtime behavior. |
| Builder / implementation owner | Maintains Settings UI, gateway settings routes, adapter profile resolution, credits checkout/key provisioning, vault integration, and model catalog behavior. |
| QA / harness audience | Verifies local-only visibility, provider switching, model selection, credential secrecy, credits states, checkout, repair, Ollama operations, and regression impact on chat. |
| Operator / maintainer | Diagnoses provider setup and credits failures through safe status fields and audit logs without seeing raw credentials. |

### Success Definition

The AI Models Settings page is successful when a local owner can:

1. Open Settings and understand the available model connection choices.
2. Use BrainDrive Models by entering a real receipt email, choosing a credit amount, opening trusted checkout, and seeing activation/ready/zero-balance/repair states.
3. Use OpenRouter with their own API key without BrainDrive Models credits.
4. Use Ollama without BrainDrive Models credits, including setting the server URL and selecting, pulling, or removing local models.
5. Switch active providers and have the displayed default model remain provider-appropriate.
6. Select a default model from a provider catalog or safe fallback list.
7. Recover from missing credentials, invalid BrainDrive Models keys, model catalog failures, and provider chat errors by returning to Settings.
8. Trust that raw API keys are never returned in settings payloads, stored in memory preferences, embedded in logs, or exposed in browser-visible checkout payloads.

The work is not successful if:

1. BrainDrive-owned provider keys are placed in client config, memory files, test fixtures intended as owner state, or frontend-bundled code.
2. BrainDrive Models checkout or credit state blocks direct OpenRouter or Ollama selection.
3. The client receives raw provider keys, BrainDrive Models keys, Stripe checkout secrets, vault plaintext, or secret-by-value preferences.
4. Switching providers leaves the UI showing a model ID from the previous provider as if it were valid for the new provider.
5. A normal owner cannot tell whether they need credits, an API key, Ollama running locally, or a repair key.
6. Managed-hosted mode exposes local-only provider base URL or vault credential controls without an updated managed-mode spec.
7. Deleting an Ollama model is possible by accidental one-click action without a confirmation or undo-safe guard. Current implementation has one-click delete; this spec recommends confirmation before treating the behavior as source-of-truth V1.

### Definition Of Done (V1)

When V1 is done-done, it can:

1. Render `AI Models` as the first local-mode Settings tab and hide it in managed-hosted mode.
2. Present BrainDrive Models, OpenRouter, and Ollama as separate provider choices, with BrainDrive Models visually recommended.
3. Persist active provider, per-provider default model, provider base URL overrides, provider credential metadata, and BrainDrive Models key metadata through safe gateway APIs.
4. Store raw provider keys only in the encrypted vault or environment, never in client-readable settings or memory preferences.
5. Let BrainDrive Models checkout provision or reuse a vault key, open only trusted checkout URLs, poll credit status while activating, and show repair when the key is invalid or missing after prior metadata exists.
6. Let BYOK OpenRouter save/update API keys independently of BrainDrive Models.
7. Let Ollama save a normalized OpenAI-compatible base URL, browse installed models, pull models with progress, and remove models only after an explicit confirmation.
8. Let the owner browse/search model catalogs, select a default model, and see clear fallback/error messaging when the catalog cannot load.
9. Reset the gateway chat runtime after credential changes so the next message uses updated provider state.
10. Include focused automated coverage for provider switching, BrainDrive Models checkout/repair, BYOK independence, Ollama URL normalization, settings payload secrecy, model catalog behavior, and managed/local tab visibility.

Explicitly not required for V1:

- Managed-hosted owner selection among third-party providers. Recommendation: keep managed model access controlled outside this local settings page until a managed provider-choice product decision exists.
- Full provider marketplace or arbitrary custom provider profiles. Recommendation: support only configured adapter profiles in `openai-compatible.json` unless a separate extensible-provider spec is approved.
- Automatic Ollama installation. Recommendation: link to Ollama and provide URL guidance; do not install system software from this page in V1.
- Payment account management beyond checkout/top-up/status links already mediated by the gateway. Recommendation: avoid duplicating Account billing behavior.
- Provider-level rate caps, budget caps, or model pricing display. Recommendation: specify separately with credits/pricing work.

## Product Behavior

### User / System Experience

In local mode, the owner opens Settings and lands on `AI Models`. The page heading is `AI Models` with the description `Choose how BrainDrive connects to AI models.` Provider choices appear as selectable rows. `BrainDrive Models` is sorted first and marked `Recommended`.

Selecting a provider immediately saves it as the active provider. The selected row expands inline to show provider-specific setup and model controls:

- BrainDrive Models shows credits purchase, activation, balance, add-credits, and repair-key states.
- OpenRouter shows API key setup/update and model catalog/default model controls.
- Ollama shows server URL setup, optional API key setup, installed model catalog/default model controls, model pull, and model delete.

Model changes take effect on the next message. Credential changes reset the gateway chat runtime so future model calls use the updated provider credential.

In managed-hosted mode, the current Settings navigation does not render `AI Models`. The old `ProviderSection` managed copy exists in code but is not reachable through the current tab list. V1 source-of-truth behavior is: managed mode has no AI Models tab.

### Primary Flows

1. **Open local AI Models settings**
   - Owner opens Settings in local mode.
   - Client loads `/settings`.
   - `AI Models` tab is visible and selected by default.
   - Client loads `/settings/models` for the active provider unless BrainDrive Models is selected with unset credentials.
   - UI shows provider cards and the selected provider's controls.

2. **Choose provider**
   - Owner selects `BrainDrive Models`, `OpenRouter`, or `Ollama`.
   - Client calls `PUT /settings` with `active_provider_profile`.
   - Gateway validates the profile against configured adapter profiles.
   - Gateway saves `active_provider_profile`.
   - If no explicit model is supplied, gateway syncs `default_model` to the selected provider's saved per-provider default or adapter profile model.
   - UI refreshes from the returned safe settings payload.

3. **Use BrainDrive Models checkout**
   - Owner selects BrainDrive Models.
   - Owner enters a real receipt email. Synthetic local emails such as `owner@local.paa` and `owner@local.braindrive` must not prefill checkout.
   - Owner chooses `$5`, `$10`, or `$25`.
   - Owner clicks `Continue to checkout`.
   - Client calls `POST /credits/checkout` with amount and email only.
   - Gateway ensures a BrainDrive Models checkout key, stores/reuses it in the vault, calls the credits service, and returns a checkout URL plus `purchase_status: activating`.
   - Client opens the checkout URL only if it passes trusted billing URL validation.
   - UI shows `Waiting for checkout to finish -- your credits will appear here automatically.` and polls `/credits/status`.
   - Once funded, UI shows the remaining credits and `Add credits`.

4. **Repair BrainDrive Models key**
   - Owner selects BrainDrive Models and the gateway/credits status indicates repair is required.
   - UI shows `BrainDrive Models can't use its key on this computer. Restore it with the backup key from your purchase email.`
   - Owner pastes an emailed key in `Paste your emailed BrainDrive Models key`.
   - Client validates key shape before save.
   - Client calls `PUT /settings/credentials` with `mode: secret_ref`, `api_key`, `required: true`, and `set_active_provider: true`.
   - Gateway validates BrainDrive Models key shape, attempts status validation against credits service, stores the key in vault, persists safe metadata, and returns safe settings.

5. **Use OpenRouter BYOK**
   - Owner selects OpenRouter.
   - UI shows `Cloud-based, requires API key` with link to `https://openrouter.ai/keys`.
   - If no key is configured, action is `Set API key`; if configured, action is `Update API key`.
   - Owner pastes a key and clicks `Save API Key`.
   - Gateway stores the key in vault under a provider secret reference, persists `provider_credentials` metadata, and returns safe settings.
   - OpenRouter remains selectable even when BrainDrive Models has no credits or key repair is needed.

6. **Use Ollama**
   - Owner selects Ollama.
   - UI shows `Runs on your computer, free` with link to `https://ollama.com`.
   - UI shows `Server URL` with help text for local and Docker installs.
   - Owner saves the URL.
   - Gateway validates URL and normalizes local Ollama base paths to OpenAI-compatible `/v1`.
   - Owner opens installed models, searches, selects a default model, pulls a new model, or removes an installed model.
   - Ollama remains selectable without BrainDrive Models credits and without an API key in the default local setup.

7. **Select default model**
   - Owner opens the selected provider's catalog with `Browse model catalog` or `Show installed models`.
   - Client shows current model, search box `Search models...`, and provider/fallback model list.
   - Owner selects a model row.
   - Client calls `PUT /settings` with `default_model`.
   - Gateway saves the model as both global `default_model` and the selected provider's entry in `provider_default_models`.
   - Next message uses the new effective adapter config.

8. **Recover from chat provider errors**
   - Chat receives a provider/model/API-key style error.
   - Chat error UI offers `Open Settings`.
   - Owner opens Settings and can repair provider configuration.

### Secondary Flows

- If settings are loading, the page shows `Loading provider settings...`.
- If settings fail to load, the page shows a danger-styled error message.
- If no provider profile exists, the page should show a clear configuration error rather than an empty provider list. Current implementation returns `null` only if settings are missing; V1 should explicitly guard the no-profile state.
- If selected BrainDrive Models credentials are unset, the client skips model catalog loading to avoid a misleading provider error.
- If model catalog loading fails, UI keeps configured fallback models visible and shows a warning.
- If the provider catalog returns an empty list, UI uses fallback configured models.
- If BrainDrive Models checkout is closed without paying, owner can use `Closed checkout without paying? Start over`.
- If credits status reports zero balance with a valid key, UI should let owner add credits without treating the key as broken.
- If credits service is unavailable, UI should show a recoverable purchase/status error and must not overwrite existing keys.
- If a BrainDrive Models existing key is invalid or prior metadata exists but the vault key is missing, checkout returns repair-required instead of silently provisioning over prior state.
- If a user has a non-synthetic account email, the email field can prefill and be stored in browser local storage as `bd_billing_email`.
- If the saved billing email is synthetic local email, the client clears it and disables checkout until a real email is entered.
- If Ollama cannot be reached, UI explains the likely URL mismatch and gives local and Docker URL guidance.
- If Ollama pull is running, UI shows status and percent progress when total/completed values are available.
- If Ollama pull/delete fails, UI shows the returned error and does not hide the provider controls.

### UX / Trust Bar

- The owner must understand that BrainDrive Models is the easiest recommended path, not the only path.
- BYOK OpenRouter and Ollama must feel first-class enough that local ownership is credible.
- Receipt email and checkout must not imply that a synthetic local account email is a real billing email.
- `Already have a key? Use it here` must remain secondary to checkout, not the default purchase path.
- The repair-key copy must explain that Migrate carries keys and Backup does not.
- The page must explain that model changes affect the next message, not an already-running response.
- Secret inputs must be password fields, use `autoComplete="new-password"`, and clear after save/cancel.
- The page must not show raw keys, token hashes, vault secret values, or hidden provider credentials.
- Ollama delete must be guarded with confirmation because it removes a local model from the owner's machine.
- Provider errors must be written in owner-action language: what to fix, where, and whether retry is safe.

### Plain-Language Owner-Facing Expectations

- `BrainDrive Models` means: "We pick the best AI model for you -- add credits and go."
- `OpenRouter` means: "Use your own OpenRouter API key."
- `Ollama` means: "Run models on your computer; make sure Ollama is installed and reachable."
- `Credits remaining` is spendable BrainDrive Models balance, not an API key status by itself.
- `API key configured` means BrainDrive has a stored secret reference, not that the key text can be recovered from Settings.
- `Model changes take effect on your next message` means active chats are not re-run or interrupted.

## Goals

### Product Goals

- Give every local owner a clear path to working model access.
- Preserve provider choice without making the default path feel technical.
- Keep BrainDrive Models purchase/activation inline with model setup.
- Keep local/offline model use available through Ollama.
- Make provider and model state recoverable from normal chat errors.

### User Goals

- Start using BrainDrive with minimal provider setup.
- Bring an existing OpenRouter key or local Ollama install.
- Understand whether the current model connection is ready.
- Change providers or models without restarting BrainDrive.
- Repair a missing/invalid BrainDrive Models key after reinstall or migration mistake.

### Engineering Goals

- Keep model provider behavior driven by adapter profiles and preferences rather than frontend constants.
- Keep provider-specific default model selection isolated by provider profile.
- Keep gateway settings payloads safe and minimal.
- Reuse existing auth/administration authorization for settings routes.
- Maintain focused tests around settings routes, provider switching, credits state, and client UX.

### Safety / Security / Trust Goals

- Never expose raw model provider keys to the browser after submission.
- Never persist secret-by-value fields in memory preferences.
- Never hard-code BrainDrive-owned provider keys in client config.
- Never make BrainDrive Models credits required for OpenRouter BYOK or Ollama.
- Treat provider base URLs as security-sensitive network configuration.
- Treat checkout URLs as untrusted until validated by `openTrustedBillingUrl`.
- Log provider/credits errors without raw keys or payment-sensitive payloads.

### Non-Goals

- No arbitrary custom provider editor in V1.
- No in-page Stripe account management beyond starting checkout/top-up through the gateway.
- No full model pricing/rate-cap calculator.
- No automated installation or system management of Ollama.
- No managed-hosted provider switching.
- No changes to memory backup/migrate behavior except referencing that migration carries secrets and backups do not.

## User Stories

### US-1: Open Local AI Models Settings - **Confirmed**

As a local BrainDrive owner, I want to open AI Models settings so that I can see how BrainDrive is connected to model providers.

**Source:** Implementation review of `SettingsModal.tsx`, `allTabs`, and local settings load behavior.

**Acceptance Criteria:**

```gherkin
Given BrainDrive is running in local mode
When the owner opens Settings
Then the first selected tab is "AI Models"
And the page heading is "AI Models"
And the page explains "Choose how BrainDrive connects to AI models."
```

```gherkin
Given BrainDrive is running in managed-hosted mode
When the owner opens Settings
Then the "AI Models" tab is not shown
And local provider URL or API-key controls are not reachable from Settings
```

**Recommendation:** Keep managed AI Models hidden in V1. If managed provider choice becomes needed, specify it separately because the security, billing, and tenant-isolation requirements differ.

### US-2: Choose Active Provider - **Confirmed**

As a local BrainDrive owner, I want to choose BrainDrive Models, OpenRouter, or Ollama so that I can decide how BrainDrive gets model access.

**Source:** Implementation review of provider cards and `PUT /settings`.

**Acceptance Criteria:**

```gherkin
Given the AI Models page has loaded local settings
When the owner selects "Ollama"
Then the client sends active_provider_profile "ollama" to the gateway
And the gateway persists the active provider profile if it is configured
And the returned settings reflect the active provider
```

```gherkin
Given the owner switches from one provider to another
When no default_model is included in the same settings update
Then the gateway updates default_model to the new provider's saved default if available
And otherwise uses the selected adapter profile model
```

**Recommendation:** Provider selection should remain an immediate save action because it directly changes runtime behavior. The UI should keep saving/loading feedback visible enough that failed provider switches are not mistaken for success.

### US-3: BrainDrive Models Checkout - **Confirmed**

As a local BrainDrive owner, I want to add BrainDrive Models credits from Settings so that I can use a working model without managing a third-party API key.

**Source:** Implementation review of `BrainDriveModelsPanel`, credits routes, and client tests.

**Acceptance Criteria:**

```gherkin
Given BrainDrive Models is selected and no usable key is configured
When the owner enters a valid non-synthetic receipt email
And selects a credit amount
And clicks "Continue to checkout"
Then the client calls POST /credits/checkout with amount and email only
And the request body does not contain a raw provider key
And the gateway provisions or reuses a checkout key through the encrypted vault
And the client opens only a trusted checkout URL
```

```gherkin
Given checkout has started
When purchase_status is "activating"
Then the UI shows "Waiting for checkout to finish -- your credits will appear here automatically."
And the client polls credits status
```

```gherkin
Given credits status reports a funded remaining balance
When the owner views BrainDrive Models
Then the UI shows the remaining dollar balance
And shows an "Add credits" action
```

**Recommendation:** Keep key provisioning gateway-side only. The frontend should never know whether the gateway provisioned a new key or reused an existing key except through safe status fields.

### US-4: Reject Synthetic Billing Emails - **Confirmed**

As a local BrainDrive owner, I want checkout to require a real receipt email so that purchase receipts and key recovery do not go to fake local account addresses.

**Source:** Implementation review and `SettingsModal.test.tsx` cases for `@local.paa` and `@local.braindrive`.

**Acceptance Criteria:**

```gherkin
Given the local session email is "owner@local.paa"
When the owner opens BrainDrive Models checkout controls
Then the receipt email field is empty
And "Continue to checkout" is disabled
```

```gherkin
Given browser local storage contains "bd_billing_email" with a synthetic local email
When the owner opens BrainDrive Models checkout controls
Then the synthetic value is cleared
And checkout remains disabled until a valid real email is entered
```

**Recommendation:** Keep the local-storage email convenience, but store only normalized non-synthetic email strings and never treat them as account identity.

### US-5: Repair BrainDrive Models Key - **Confirmed**

As a local BrainDrive owner, I want to paste an emailed BrainDrive Models key when this computer cannot use the stored key so that I can recover after reinstalling or missing migration.

**Source:** Implementation review of repair UI, gateway credential validation, and checkout repair-required tests.

**Acceptance Criteria:**

```gherkin
Given BrainDrive Models status is repair_required
When the owner opens AI Models
Then the UI explains that BrainDrive Models cannot use its key on this computer
And shows a repair-key password field
```

```gherkin
Given the owner enters a key that does not match the expected BrainDrive Models key shape
When they click "Save Key"
Then the client shows "That doesn't look like a BrainDrive Models key. Copy the full key from your purchase email."
And the key is not submitted
```

```gherkin
Given the owner submits a well-shaped repair key
When the gateway accepts the credential update
Then the key is stored in the encrypted vault
And safe credential metadata is returned
And the raw key is not included in the response
```

**Recommendation:** Keep the repair path visible but secondary. The default new-user path should remain checkout, not manual key paste.

### US-6: Preserve Direct OpenRouter - **Confirmed**

As a technical local BrainDrive owner, I want to use my own OpenRouter API key so that I am not required to buy BrainDrive Models credits.

**Source:** Implementation review and client test `keeps direct OpenRouter and Ollama selectable independently of BrainDrive Models credits`.

**Acceptance Criteria:**

```gherkin
Given BrainDrive Models has no credits or is not set up
When the owner selects OpenRouter
Then OpenRouter remains selectable
And no BrainDrive Models checkout call is made
```

```gherkin
Given OpenRouter is selected
When the owner saves an API key
Then the gateway stores the key in the vault
And preferences store only safe credential metadata
And the returned settings show credential_mode "secret_ref"
```

**Recommendation:** OpenRouter should remain the primary BYOK cloud option in V1. Do not remove it while improving BrainDrive Models onboarding.

### US-7: Preserve Ollama Local Model Path - **Confirmed**

As a local BrainDrive owner, I want to use Ollama so that BrainDrive can run against models on my computer without cloud credits.

**Source:** Implementation review of Ollama provider UI, base URL save, and gateway URL normalization test.

**Acceptance Criteria:**

```gherkin
Given BrainDrive Models has no credits or is not set up
When the owner selects Ollama
Then Ollama remains selectable
And no BrainDrive Models checkout call is made
```

```gherkin
Given the owner enters "http://localhost:11434"
When they save the Ollama server URL
Then the gateway stores the provider base URL as "http://localhost:11434/v1"
```

```gherkin
Given Ollama is selected
When the owner has not set an API key
Then the local setup remains usable because Ollama does not require a secret by default
```

**Recommendation:** Keep local and Docker URL guidance in the UI. Do not hide Ollama behind advanced settings.

### US-8: Browse And Select Default Model - **Confirmed**

As a local BrainDrive owner, I want to browse/search models for the active provider so that I can choose which model BrainDrive uses next.

**Source:** Implementation review of `ModelSection`, `GET /settings/models`, and model catalog client test.

**Acceptance Criteria:**

```gherkin
Given a provider model catalog is available
When the owner clicks "Browse model catalog"
And searches "free"
Then matching models are shown
And selecting a model calls PUT /settings with default_model set to that model ID
```

```gherkin
Given a provider model catalog cannot be reached
When the owner opens the catalog
Then the UI shows a catalog warning
And configured fallback models remain selectable
```

```gherkin
Given Ollama is the active provider
When the owner opens installed models
Then the action label is "Show installed models"
And the list represents local Ollama models or configured fallback models
```

**Recommendation:** Catalog search should remain client-side for V1. Server-side search/filtering is only needed if catalogs become too large for responsive rendering.

### US-9: Pull Ollama Model - **Confirmed**

As a local BrainDrive owner using Ollama, I want to pull a model by name so that I can install a model without leaving BrainDrive.

**Source:** Implementation review of Ollama pull UI and `POST /settings/models/pull`.

**Acceptance Criteria:**

```gherkin
Given Ollama is selected and the catalog panel is open
When the owner enters "llama3.2" in "Pull a new model"
And clicks "Pull"
Then the client posts the model name to /settings/models/pull
And streams pull status from NDJSON
And shows progress when total and completed values are available
And refreshes the catalog after success
```

```gherkin
Given Ollama pull fails
When the gateway returns an error
Then the UI shows the error
And does not change the selected default model
```

**Recommendation:** Pull should remain Ollama-only. Do not generalize this endpoint for cloud providers unless a provider-specific install concept exists.

### US-10: Remove Ollama Model - **Recommended**

As a local BrainDrive owner using Ollama, I want to remove an installed model only after confirming so that I do not accidentally delete local model data.

**Source:** Implementation review found one-click delete in current `ModelSection`; product recommendation based on destructive local action risk.

**Acceptance Criteria:**

```gherkin
Given Ollama is selected and installed models are visible
When the owner clicks the remove icon for a model
Then the UI asks for confirmation naming the model
And no delete request is sent until the owner confirms
```

```gherkin
Given the owner confirms deletion
When the gateway successfully deletes the Ollama model
Then the catalog refreshes
And if the deleted model was selected, the UI no longer presents it as a valid selected model
```

**Recommendation:** Add confirmation before treating delete as V1-complete. This should block production acceptance for the page because it is a destructive local operation.

### US-11: Auto-Open Settings For Missing Active Provider Credential - **Confirmed**

As a local BrainDrive owner, I want Settings to open automatically when the active provider cannot be used so that I know what to fix before chatting.

**Source:** Implementation review of `AppShell.tsx` onboarding-status effect.

**Acceptance Criteria:**

```gherkin
Given BrainDrive is running locally
And the active provider requires a secret
And the credential is unset or unresolved
When the app shell initializes
Then the client opens Settings
And the owner can configure AI Models
```

```gherkin
Given the active provider is Ollama
When no API key is configured
Then the missing-secret condition alone does not require onboarding
```

**Recommendation:** Keep auto-open scoped to local mode. Managed mode should use managed account/billing recovery paths.

### US-12: Provider Error Recovery From Chat - **Confirmed**

As a BrainDrive owner, I want chat provider errors to offer a path back to Settings so that I can repair model access.

**Source:** Implementation review of `ChatPanel.tsx` and `ErrorMessage.tsx`.

**Acceptance Criteria:**

```gherkin
Given chat receives an API-key, provider, timeout, or model-style error
When the error is shown
Then the owner sees an "Open Settings" action
And clicking it opens Settings
```

**Recommendation:** Provider error detection should remain conservative. Do not show model-settings recovery for unrelated app errors.

### US-13: Keep Settings Payload Secret-Safe - **Confirmed**

As a local BrainDrive owner, I want Settings to show whether credentials are configured without exposing credential values so that secrets stay protected.

**Source:** Implementation review of `buildSettingsPayload`, preference schema, vault writes, and tests.

**Acceptance Criteria:**

```gherkin
Given a provider key has been saved
When the client calls GET /settings
Then the response includes credential_mode and credential_ref metadata
And does not include the raw API key
```

```gherkin
Given BrainDrive Models checkout provisions a key
When preferences are saved
Then provider_credentials contains a secret_ref
And braindrive_models_key contains only metadata such as masked_key, status, checkout_pending, and timestamps
And no raw key appears in preferences
```

**Recommendation:** Treat any regression that exposes raw keys as a release blocker.

## Requirements

### Functional Requirements

- [ ] `AI Models` must be visible only in local-mode Settings.
- [ ] Local Settings must default to `AI Models` when opened.
- [ ] Provider profiles must be loaded from gateway settings, not hard-coded as the only source of truth in the client.
- [ ] BrainDrive Models must sort first when present and display `Recommended`.
- [ ] Selecting a provider must save `active_provider_profile` through `PUT /settings`.
- [ ] Unknown provider profiles must be rejected by the gateway.
- [ ] Switching providers must update the effective default model to that provider's saved/default model when no explicit default is submitted.
- [ ] Selecting a model must save the model as the selected provider's default.
- [ ] The current model must be displayed before catalog controls.
- [ ] Model catalog must merge provider-listed models with configured fallback models.
- [ ] Catalog search must match model ID, name, provider, and tags.
- [ ] Catalog failures must show warnings without hiding fallback models.
- [ ] BrainDrive Models checkout must require a valid non-synthetic email.
- [ ] BrainDrive Models checkout must submit amount and email only from the client.
- [ ] Checkout URLs must be opened only through trusted billing URL validation.
- [ ] BrainDrive Models activation state must poll credits status.
- [ ] BrainDrive Models funded state must show remaining balance and an add-credits path.
- [ ] BrainDrive Models repair must validate key shape before gateway submission.
- [ ] Gateway BrainDrive Models repair must reject unrecognized keys on 401/403 when validation is available.
- [ ] OpenRouter API key save/update must use the credential endpoint and encrypted vault storage.
- [ ] Ollama must not require an API key by default.
- [ ] Ollama server URL save must validate URL and normalize local Ollama paths to `/v1`.
- [ ] Ollama pull must stream progress and refresh the model catalog after success.
- [ ] Ollama delete must require explicit confirmation before gateway call.
- [ ] Credential saves must clear password inputs after success or cancel.
- [ ] Credential saves must reset gateway chat runtime.
- [ ] Chat provider errors must offer an `Open Settings` recovery action.

### AI / Model / Tool Behavior

- The AI Models page does not require model-generated content, prompts, tool calls, or memory writes to render.
- The selected provider/model affects later model-loop behavior through adapter configuration.
- Model changes must take effect on the next message, not mutate an in-flight model response.
- Credential changes must affect future requests without requiring an app restart.
- The page must not ask an AI model to inspect, validate, transform, or store provider keys.
- Future AI/tool assistance in this area may explain setup steps, but it must not request raw API keys in chat, store keys in memory, or bypass the Settings/vault credential path.

### Data, Memory, And Artifact Contracts

| Data / Artifact | Source | Owner | Read/Write Rules | Retention / Migration |
|---|---|---|---|---|
| Adapter profile config | `builds/typescript/adapters/openai-compatible.json` | Product/runtime config | Read by gateway; defines provider profiles, base URLs, models, API key env names, and default provider profile. | Versioned with app. Do not store secrets here. |
| `default_model` preference | Memory preferences via `config.ts` schema | Local owner/runtime | Read/write through gateway; effective value should match active provider's selected model. | Migrates with memory export/import. Must not imply model is valid for all providers. |
| `active_provider_profile` preference | Memory preferences | Local owner/runtime | Set through `PUT /settings`; must match configured adapter profile or be null/unset. | Migrates with memory export/import. |
| `provider_default_models` preference | Memory preferences | Local owner/runtime | Gateway stores per-provider selected model IDs. | Migrates with memory export/import. Needed to avoid cross-provider model confusion. |
| `provider_base_urls` preference | Memory preferences | Local owner/runtime | Gateway stores per-provider URL overrides after validation/normalization. | Migrates with memory export/import. Treat as sensitive network config, but not a secret. |
| `provider_credentials` preference | Memory preferences | Local owner/runtime | Stores only credential mode, secret ref/env ref, and required flag. No raw key. | Migrates as metadata only. Raw vault secrets require migration, not git backup. |
| Encrypted vault provider secret | Secrets vault under refs such as `provider/openrouter/api_key` or `provider/ai-gateway/api_key` | Local owner/secrets subsystem | Written by gateway credential routes; never returned to client. | Carried by migration flow when supported. Not carried by memory backup. |
| BrainDrive Models key metadata | `braindrive_models_key` preference | Gateway/credits integration | Stores status, checkout_pending, key_id/hash, masked key, timestamps, last error. No raw key. | Migrates with preferences as metadata. Missing corresponding vault key requires repair. |
| Billing email convenience | Browser `localStorage` key `bd_billing_email` | Local browser profile | Client may store normalized non-synthetic email only. Must clear synthetic local values. | Browser-local only. Not memory, not backup, not migration source of truth. |
| Credits status payload | `GET /credits/status` | Gateway/credits service | Returns balance, spend totals when available, key_valid, and purchase_status. No raw key. | Runtime status only; gateway may persist safe key status metadata. |
| Checkout request | `POST /credits/checkout` | Client/gateway/credits service | Client sends amount and email. Gateway adds Authorization from vault key to upstream request. | Not persisted except safe key status metadata. |
| Checkout URL | Credits service response | Credits service/gateway | Client may open only after trusted billing URL validation. | Runtime only. Do not log full sensitive payment session data if avoidable. |
| Provider model catalog | `GET /settings/models` | Gateway/provider adapter | Returns provider_profile, provider_id, source, warning, models. No credentials. | Runtime only, merged with configured fallback models in client. |
| Ollama pull stream | `POST /settings/models/pull` | Gateway/Ollama | Streams NDJSON progress from Ollama. Requires configured provider profile. | Runtime only. Audit success/error by provider/model without secrets. |
| Ollama delete request | `POST /settings/models/delete` | Client/gateway/Ollama | Requires model name and optional provider profile. Must be confirmation-gated in UI. | Removes local model from Ollama store outside BrainDrive memory. |
| Settings audit logs | Gateway `auditLog` | Maintainer/operator | Log provider profile, provider ID, status, and sanitized errors only. Never log raw keys. | Retained according to app logging policy. |
| Chat runtime cache | Gateway/client runtime | Runtime | Reset after credential changes. | Runtime only. |

### Interface / UX Requirements

- [ ] Tab label must be `AI Models`.
- [ ] Page heading must be `AI Models`.
- [ ] Page intro copy must say `Choose how BrainDrive connects to AI models.` or an approved equivalent.
- [ ] Provider display labels must be `BrainDrive Models`, `OpenRouter`, and `Ollama` for the current built-in profiles.
- [ ] BrainDrive Models must show `Recommended`.
- [ ] BrainDrive Models subcopy should remain owner-simple: `We pick the best AI model for you -- add credits and go`.
- [ ] OpenRouter subcopy must state it is cloud-based and requires an API key, with a safe link to `https://openrouter.ai/keys`.
- [ ] Ollama subcopy must state it runs on the owner's computer and link to `https://ollama.com`.
- [ ] BrainDrive Models checkout email label must be `Email for your receipt`.
- [ ] BrainDrive Models credit amount choices must include `$5`, `$10`, and `$25` for current V1.
- [ ] BrainDrive Models primary checkout action must be `Continue to checkout`.
- [ ] BrainDrive Models activating copy must communicate waiting for checkout completion.
- [ ] BrainDrive Models funded state must show `$N.NN credits remaining` and `Add credits`.
- [ ] BrainDrive Models repair placeholder must be `Paste your emailed BrainDrive Models key`.
- [ ] BrainDrive Models repair copy must explain: use Migrate to carry keys; backups do not carry keys.
- [ ] OpenRouter/API key action labels must distinguish `Set API key`, `Update API key`, and `Save API Key`.
- [ ] If an API key is already configured, UI must say `API key configured -- enter a new key below to replace it`.
- [ ] Ollama URL label must be `Server URL`.
- [ ] Ollama URL help must include local and Docker examples.
- [ ] Catalog toggle must use `Browse model catalog` for cloud providers and `Show installed models` for Ollama.
- [ ] Catalog search placeholder must be `Search models...`.
- [ ] Ollama pull section must be labeled `Pull a new model`.
- [ ] Ollama pull placeholder should include examples such as `e.g. llama3.2, gemma2, mistral`.
- [ ] Model section must include `Model changes take effect on your next message.`
- [ ] Error messages must be shown inline near the failed control.
- [ ] Buttons must have disabled/loading states during async work.
- [ ] Text must fit within the Settings modal at supported desktop and mobile widths.

### Observability / Evidence Requirements

- [ ] Gateway must audit credential update start, BrainDrive Models validation result/unavailability, provider model catalog errors, Ollama pull success/error, and Ollama delete success/error without secrets.
- [ ] Checkout/key provisioning tests must prove raw keys do not appear in preferences or browser-visible checkout request payloads.
- [ ] UI tests must prove synthetic emails do not prefill checkout.
- [ ] UI tests must prove OpenRouter and Ollama remain selectable when BrainDrive Models is not funded.
- [ ] API tests must prove Ollama URL normalization.
- [ ] API tests must prove invalid BrainDrive Models existing keys are not silently overwritten.
- [ ] Manual evidence for release should include screenshots or video of: first-time BrainDrive Models checkout, funded state, repair state, OpenRouter key save, Ollama URL save, catalog browse, Ollama pull, and delete confirmation.
- [ ] Verification output must include focused test command names and pass/fail output.

## Scope

### Work Type

- [x] **Production** - Existing user-facing settings surface with credentials, paid credits, provider runtime impact, and destructive local Ollama operations.
- [x] **V1** - Source-of-truth behavior for the current local AI Models page.
- [x] **Documentation/specification** - This spec establishes product/engineering requirements.
- [x] **Interface / shell** - Settings modal tab and chat recovery entry point.
- [x] **Backend / gateway** - Settings, credential, credits, and model routes.
- [x] **Secrets** - Vault-backed provider credentials and safe settings payloads.
- [x] **Testing / harness** - Focused UI/API/regression checks.

### Implementation Location / Ownership

- `builds/typescript/client_web/src/components/settings/SettingsModal.tsx` - AI Models tab, provider cards, BrainDrive Models panel, model catalog, Ollama controls.
- `builds/typescript/client_web/src/api/gateway-adapter.ts` - Settings, credentials, credits, model catalog, pull, and delete client calls.
- `builds/typescript/client_web/src/api/types.ts` - Gateway settings, provider profile, BrainDrive Models key state, credits status, credential, and model catalog contracts.
- `builds/typescript/client_web/src/components/layout/AppShell.tsx` - Local onboarding-status auto-open behavior.
- `builds/typescript/client_web/src/components/chat/ChatPanel.tsx` and `ErrorMessage.tsx` - Provider error recovery to Settings.
- `builds/typescript/gateway/server.ts` - `/settings`, `/settings/onboarding-status`, `/settings/credentials`, `/settings/models`, `/settings/models/pull`, `/settings/models/delete`, `/credits/status`, `/credits/checkout`.
- `builds/typescript/config.ts` - Adapter/preference schema, BrainDrive Models key metadata, forbidden secret-by-value validation.
- `builds/typescript/adapters/openai-compatible.json` - Default provider profiles.
- `builds/typescript/adapters/index.ts` - Effective adapter profile/model/base URL resolution.
- `builds/typescript/gateway/credits-provisioning.ts` - BrainDrive Models checkout key provisioning behavior.
- `builds/typescript/client_web/src/components/settings/SettingsModal.test.tsx` - Settings UI regression coverage.
- `builds/typescript/gateway/auth-routes.integration.test.ts` - Settings/credits route integration coverage.
- `builds/typescript/adapters/index.test.ts` - Provider-specific model resolution coverage.

### Included

- Local-mode AI Models tab behavior.
- Provider selection among configured profiles.
- BrainDrive Models checkout, status, balance, add-credits, and repair-key behavior.
- OpenRouter BYOK setup/update.
- Ollama base URL setup, model catalog, pull, and delete confirmation requirement.
- Default model selection and per-provider model persistence.
- Gateway settings payload and credential contracts.
- Onboarding/chat recovery entry points into Settings.
- Security, privacy, trust, and evidence requirements.

### Explicitly Excluded

- Managed-hosted provider switching -> separate managed-provider/settings spec.
- Arbitrary custom provider profile authoring -> future provider marketplace/custom-provider spec.
- BrainDrive Models pricing/rate-cap UI -> separate billing/pricing spec.
- Stripe portal/account management beyond starting checkout/top-up -> Account/Billing spec.
- Ollama install automation -> future local model setup assistant or installer scope.
- Memory backup/migrate implementation changes -> existing Backup/Migrate specs.
- Provider reasoning controls or provider-specific advanced generation parameters -> separate model behavior specs.
- Removing OpenRouter or Ollama while changing BrainDrive Models behavior -> forbidden without updated scope.

### Future Versions / Deepenings

- Custom provider profile editor with validation, test connection, and secret storage.
- Provider/model health check button with safe diagnostics.
- Model pricing and spend estimate display.
- BrainDrive Models usage details and transaction history.
- Safer model recommendations based on task type, context length, and cost policy.
- Ollama install/setup detection and guided install.
- Provider capability badges, such as context length, tool-use support, multimodal support, and free/paid tags.
- Managed-hosted owner-visible model plan or model choice if product/billing/security scope is approved.

## Invariants And Edge Cases

### Properties That Must Always Hold

- Raw API keys must never be returned by `/settings`, `/settings/onboarding-status`, or model catalog routes.
- Raw API keys must never be persisted in memory preferences.
- BrainDrive-owned OpenRouter or BrainDrive Models provider keys must never be bundled into the client.
- BrainDrive Models credits must never be required for OpenRouter BYOK or Ollama.
- Ollama must remain no-secret by default.
- Provider IDs and provider profile IDs must not be treated as interchangeable in persistence. Current code stores provider credential preferences by provider ID and active/default model selections by profile ID; builders must preserve this distinction.
- Active provider profile must be validated against configured adapter profiles before saving.
- Default model must be provider-scoped in practice, even though a global `default_model` field remains for compatibility.
- Model catalog failures must not erase selected model preferences.
- Checkout must be mediated by the gateway; the client must not call credits service with a raw key.
- Trusted checkout URL validation must gate browser opening.
- Synthetic local emails must not be used for billing checkout.
- Existing invalid BrainDrive Models keys must not be silently overwritten by automatic provisioning.
- Prior BrainDrive Models metadata plus missing vault key must lead to repair, not silent new-key provisioning.
- Deleting a local Ollama model must require explicit confirmation.
- Managed mode must not expose local vault/API-key/provider URL controls in this page.

### Edge Cases To Test

- Settings load fails.
- Adapter has no provider profiles.
- Active provider profile in preferences is unknown.
- Switching providers while model catalog is loading.
- Selecting a model while a save is already in progress.
- Provider catalog returns empty list.
- Provider catalog route cannot resolve credential.
- OpenRouter key save succeeds, then settings read transiently fails.
- BrainDrive Models checkout service unavailable.
- BrainDrive Models checkout returns unexpected/untrusted URL.
- BrainDrive Models status returns 401/403 for existing key.
- BrainDrive Models status returns zero balance with valid key.
- BrainDrive Models status remains activating after checkout closes.
- Repair key has invalid shape.
- Repair key validation service is unreachable after key shape passes.
- Saved billing email is synthetic or malformed.
- Ollama URL entered without `/v1`.
- Ollama URL entered as `/api`, `/api/chat`, or `/api/generate`.
- Ollama unavailable at configured URL.
- Ollama pull stream contains malformed NDJSON lines.
- Ollama pull response has no body.
- Ollama delete fails.
- Deleted Ollama model was selected as current default.
- Chat provider error should show `Open Settings`; non-provider error should not.

### Failure Modes

| Scenario | Expected Behavior |
|---|---|
| `/settings` fails | AI Models page shows loading failure and does not render stale provider controls as if current. |
| Unknown provider profile submitted | Gateway returns invalid request and preferences are not changed. |
| Provider catalog credential missing | Gateway returns fallback models with warning; UI shows warning and keeps setup controls visible. |
| Provider catalog provider failure | Gateway audits sanitized error and UI shows catalog warning. |
| BrainDrive Models checkout provisioning fails | Gateway returns 502 with safe error/code; UI shows checkout failure and does not affect OpenRouter/Ollama. |
| BrainDrive Models existing key invalid | Gateway returns repair-required; UI shows repair key path. |
| Checkout URL is untrusted | Client does not open it and shows `Received an unexpected checkout link. Please try again.` |
| Synthetic email is present | Client clears/ignores it and disables checkout. |
| OpenRouter key save fails | UI shows credential error and keeps typed input until owner cancels or edits. |
| Ollama URL invalid | Gateway rejects request; UI shows URL save error. |
| Ollama server unreachable | UI shows URL-specific guidance. |
| Ollama pull fails | UI shows pull error, clears progress state, keeps controls usable. |
| Ollama delete fails | UI shows delete error and keeps catalog visible. |
| Ollama delete succeeds for selected model | Catalog refreshes; UI must not keep deleted model as selected without warning or replacement. |
| Credential saved successfully | Password input clears and gateway chat runtime is reset. |
| Managed mode opens Settings | AI Models tab is absent. |

## Technical Context

### Existing System Context

The current settings surface is a React `SettingsModal` in the web client. Local mode renders tabs in this order: `AI Models`, `Your Profile`, `Your Agent`, desktop-only `Browser Access`, `Backup`, and `Migrate`. Managed mode renders `Account`, `Your Profile`, `Your Agent`, and `Migrate`; the `AI Models` tab is local-only.

The page loads settings from the local gateway and maintains a separate model catalog request for the active provider. The client skips model catalog loading when BrainDrive Models is selected and credentials are unset, avoiding an expected missing-key error during first-time checkout.

Provider configuration is defined by the OpenAI-compatible adapter config. The checked config currently sets:

- `braindrive-models` as the default provider profile with base URL `https://my.braindrive.ai/credits/v1` and model `braindrive-models-default`.
- `openrouter` with base URL `https://openrouter.ai/api/v1` and model `z-ai/glm-5.2`.
- `ollama` with base URL `http://127.0.0.1:11434/v1` and no default model in the JSON file.

The gateway settings payload intentionally returns safe metadata only. Raw provider keys are stored through the secrets vault, and preference schema validation rejects forbidden secret-by-value fields.

BrainDrive Models checkout uses gateway-side credits routes. The gateway provisions or reuses a key, stores it in the vault, persists safe key metadata, and calls the credits service with Authorization server-side. The client receives a checkout URL and purchase status, not a key.

The effective adapter config resolves selected provider profile, provider-specific default model, and provider-specific base URL overrides. It avoids falling back to a global model ID when switching providers because model IDs are provider-specific.

### Integration Points

- **UI:** Settings modal, provider cards, BrainDrive Models panel, model catalog, chat error recovery, local onboarding auto-open.
- **API:** `/settings`, `/settings/onboarding-status`, `/settings/credentials`, `/settings/models`, `/settings/models/pull`, `/settings/models/delete`, `/credits/status`, `/credits/checkout`.
- **Backend:** Fastify gateway routes with administration authorization.
- **Storage:** Memory preferences for provider/profile metadata and model choices.
- **Secrets:** Encrypted vault and optional env refs for provider keys.
- **Auth:** Local-owner administration authorization for settings/credits/model routes.
- **Provider config:** OpenAI-compatible adapter profiles and environment base URL overrides.
- **External services:** BrainDrive credits service, Stripe checkout URL returned by credits service, OpenRouter API/model catalog, Ollama local API.
- **Runtime:** Model adapter resolution for future chat requests.
- **Tests:** Vitest UI tests, gateway integration tests, adapter tests.

### Hard Constraints

- Do not put BrainDrive-owned provider keys in client config.
- Do not require BrainDrive Models credits for Ollama or BYOK OpenRouter.
- Do not remove Ollama or BYOK OpenRouter provider choices while changing BrainDrive Models behavior.
- Do not hard-code production/staging hosted URLs without checking existing config patterns.
- Do not expose local provider controls in managed mode without a new managed spec.
- Do not suppress provider/credential errors just to make the UI appear ready.
- Do not log raw API keys, raw checkout keys, or full secrets.
- Do not store raw keys in memory backup/export artifacts.
- Do not bypass gateway authorization for settings or credits routes.
- Do not generalize Ollama pull/delete behavior to cloud providers without provider-specific safety review.

### Build Workflow Inputs

- Treat this page as a combined product surface, not three unrelated controls.
- Keep provider-specific copy plain-language and owner-actionable.
- Preserve the adapter profile model: frontend should render returned profiles and not assume only three providers forever.
- Add the Ollama delete confirmation as the first recommended product gap to close.
- Use existing tests as the baseline and add focused tests for gaps rather than broad snapshot tests.
- When changing BrainDrive Models behavior, run both client settings tests and gateway credits/key provisioning tests.
- When changing provider resolution, run adapter tests and at least one chat/provider smoke path.

## Test Strategy

### Test Levels Required

- **Unit:** Adapter effective config resolution; billing email normalization/synthetic email detection if extracted; trusted billing URL validation.
- **Client component:** SettingsModal provider switching, checkout states, repair path, BYOK independence, model catalog search/save, Ollama controls, delete confirmation, local/managed tab visibility.
- **Gateway integration:** Settings read/write, credential update, settings payload secrecy, BrainDrive Models checkout provisioning/reuse/repair, credits status mapping, Ollama URL normalization, model catalog fallback/warnings, Ollama pull/delete error handling.
- **Regression:** Chat provider error recovery opens Settings; local onboarding auto-open for missing active provider credential.
- **Manual verification:** Browser run through BrainDrive Models checkout start, repair UI, OpenRouter key save with test key, Ollama URL save/catalog/pull/delete confirmation.
- **Security verification:** Inspect settings payloads, preferences, logs, and test output for absence of raw keys.

### Verification Approach

Run focused checks during implementation and broader checks before handoff:

```bash
cd builds/typescript
npm run web:test -- SettingsModal.test.tsx
```

```bash
cd builds/typescript
npm run test -- auth-routes.integration.test.ts credits-provisioning.test.ts adapters/index.test.ts
```

```bash
cd builds/typescript
npm run web:typecheck
```

```bash
cd builds/typescript
npm run build
```

If the test runner does not support file arguments exactly as shown, use the repo's Vitest invocation pattern and report the exact command used.

### Acceptance Evidence

- Passing focused client tests for AI Models settings.
- Passing gateway tests for settings/credentials/credits/model routes.
- Passing adapter model-resolution tests.
- Typecheck output.
- Build output for release-bound changes.
- Manual screenshots or video for key UI states:
  - local AI Models default tab
  - BrainDrive Models checkout email/amount
  - activating state
  - funded balance/add credits
  - repair key state
  - OpenRouter API key setup/update
  - Ollama URL guidance
  - catalog browse/search/default model selection
  - Ollama pull progress
  - Ollama delete confirmation
  - managed Settings without AI Models tab
- Evidence that raw keys are absent from settings payloads and preferences after credential save/checkout.

### Baseline / Regression Impact

- Chat must continue using the active provider/model after settings changes.
- Missing credential onboarding must continue to open Settings in local mode.
- Managed mode Settings tabs must remain Account/Profile/Agent/Migrate oriented.
- Backup and Migrate behavior must not regress.
- BrainDrive Models checkout must not break BYOK OpenRouter or Ollama selection.
- Provider credential save must not require app restart.
- Memory preferences schema must continue rejecting secret-by-value fields.

## Security, Privacy, And Trust Considerations

### Risk Level

**High.** The surface handles paid credits, model provider credentials, encrypted vault writes, provider network endpoints, and local model deletion. A bug can leak keys, charge the wrong billing email, break all chat/model access, or remove local Ollama model data.

### Threat / Trust Assessment

| Area | Assessment |
|---|---|
| User input | Receipt email, API keys, provider base URLs, model names, and provider/model selections are owner-entered and must be validated. |
| Code execution | The page does not execute owner code, but Ollama pull/delete causes gateway network calls to local services and modifies local Ollama state. |
| Data sensitivity | API keys and BrainDrive Models keys are highly sensitive. Billing email is personal data. Provider base URLs can reveal local/network topology. |
| Network surface | Gateway calls credits service, OpenRouter/model providers, and Ollama. Ollama URL overrides may target local or remote hosts. |
| Model/tool behavior | Selected provider/model affects future model-loop behavior and tool-call reliability. The page itself should not invoke AI/tool behavior. |
| Blast radius | Bad active provider config can break all chat. Secret leakage can expose paid accounts. Ollama delete removes local model artifacts. |
| Owner trust | Owners must believe BrainDrive supports both convenient paid models and self-owned provider/local alternatives. |

### Required Mitigations

- Use encrypted vault for raw provider keys.
- Return only safe credential modes/refs/status metadata to the client.
- Validate BrainDrive Models key shape client-side and server-side before storing.
- Verify BrainDrive Models keys against credits status when service is reachable.
- Treat invalid existing BrainDrive Models keys as repair-required.
- Preserve existing keys when checkout starts and status proves they are valid or zero-balance.
- Do not provision over missing vault keys when prior BrainDrive Models metadata indicates a previous key existed.
- Validate and normalize provider base URLs gateway-side.
- Restrict provider profile updates to configured known profiles.
- Validate trusted billing URLs before opening checkout.
- Clear secret input fields after successful save/cancel.
- Confirm Ollama model deletion before calling the gateway.
- Audit errors with provider/profile/status but never raw secrets.
- Keep managed mode separated from local provider controls.

## Explicit Boundaries

### Do Not Modify Without Updated Scope

- Managed-hosted provider and billing behavior.
- Credits service API semantics or Stripe checkout implementation.
- Memory backup/migration secret handling.
- Adapter profile schema beyond fields already used by provider settings.
- Auth/authorization model for settings routes.
- Chat/model loop behavior beyond consuming selected provider/model/credentials.
- Installer-level Ollama installation or system service management.

### Do Not Introduce

- BrainDrive-owned provider keys in frontend code, adapter JSON, memory starter packs, or test memory fixtures.
- Raw API keys in settings responses, localStorage, memory preferences, logs, screenshots, or error messages.
- A requirement to buy BrainDrive Models credits before OpenRouter/Ollama can be used.
- A hidden provider switch triggered by checkout, catalog browse, or failed credits status.
- One-click destructive Ollama delete without confirmation.
- Silent fallback from one provider's model ID to another provider's model ID.
- Broad try/catch suppression that makes broken provider setup look ready.
- Client-side direct calls to credits service with provider keys.
- Public/staging hosted URLs hard-coded outside existing config override patterns.

### Out Of Scope Even If Related

- General Account billing portal.
- Memory Backup and Migrate panels, except cross-copy explaining secrets.
- Tailscale/Browser Access settings.
- OpenRouter reasoning controls.
- Prompt audit and provider payload logging preferences.
- Tool/MCP provider configuration.
- Multi-account/team provider administration.

## Open Questions And Recommendations

| Item | Question / Gap | Recommendation | Blocks V1? |
|---|---|---|---|
| Managed AI Models | Should managed-hosted owners ever see model/provider controls? | No for V1. Keep hidden until managed billing/provider choice is specified separately. | No |
| Ollama delete confirmation | Current UI sends delete from one icon click. Should destructive local model deletion require confirmation? | Yes. Add a confirmation naming the model before V1 acceptance. | Yes |
| No provider profiles configured | Current happy path assumes provider profiles exist. What should UI show if adapter config has none? | Show a clear "No provider profiles are configured" state and do not render empty controls. | No, unless supporting custom configs in release |
| BrainDrive Models amount set | Are `$5`, `$10`, `$25` the permanent credit amounts? | Treat as V1 defaults from current implementation; move pricing/product changes to billing spec. | No |
| OpenRouter key validation | Should OpenRouter keys be validated before storing, like BrainDrive Models keys? | Recommended future improvement: add optional "test connection" rather than blocking save on provider availability. | No |
| Ollama remote API key | Current UI allows optional API key for remote Ollama. Is remote Ollama a first-class supported mode? | Keep optional for technical users, but V1 copy should emphasize local/default no-key setup. | No |
| Model deletion selected default | What should happen if the deleted Ollama model is selected? | Clear selection or switch to a safe installed fallback and show a message; do not leave deleted model displayed as valid. | Yes if delete is shipped |
| Catalog scale | What if provider model catalogs become very large? | Keep client-side search in V1; revisit pagination/server search only if performance evidence requires it. | No |
| Provider status badge | Should each provider card show ready/needs key/needs credits? | Recommended V2. Current selected panel states are enough for V1 if errors are clear. | No |
| Secrets in migration/backups | How much should AI Models explain migration vs backup secret behavior? | Keep the existing repair-path note; deeper explanation belongs in Migrate/Backup specs. | No |

## Recommended Product Decisions

1. Keep BrainDrive Models as the recommended first provider, but never as a forced dependency for local owners.
2. Keep the AI Models tab local-only for V1.
3. Treat raw key secrecy as a release-blocking invariant.
4. Add confirmation before Ollama model deletion.
5. Keep manual BrainDrive Models key repair as a secondary recovery path, not the default purchase path.
6. Preserve provider-specific default model persistence and avoid cross-provider model fallback.
7. Keep checkout mediated by the gateway and trusted URL validation.

## Changelog

| Date | Change | Reason | Source | Decision |
|---|---|---|---|---|
| 2026-07-09 | Created source-of-truth AI Models Settings spec. | No complete spec existed for the page. | User request and implementation review. | V1 source of truth pending review. |
| 2026-07-09 | Marked Ollama delete confirmation as recommended V1 blocker. | Current one-click delete is destructive local behavior. | Implementation review of `SettingsModal.tsx`. | Recommend confirmation before production acceptance. |
| 2026-07-09 | Confirmed BrainDrive Models should not remove OpenRouter/Ollama alternatives. | Repo instructions and tests identify this as a product boundary. | AGENTS.md and SettingsModal tests. | Confirmed invariant. |

## Conversation References

| Date | Source | Topics Discussed | Link |
|---|---|---|---|
| 2026-07-09 | User request pasted into Codex attachment | Requested complete builder-facing product/engineering spec for `The AI Models Settings Page` at `Settings - Specs`. | `/home/hex/.codex/attachments/d7e39514-f347-43f2-a077-676b056acab5/pasted-text.txt` |
| 2026-07-09 | Repo AGENTS instructions supplied in chat | Local repo constraints, verification expectations, provider/security boundaries. | `/home/hex/Project/BrainDrive-Test-01/AGENTS.md` equivalent chat instructions |

## Implementation Evidence Reviewed

### Files Reviewed

- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/client_web/src/components/settings/SettingsModal.tsx`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/client_web/src/api/gateway-adapter.ts`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/client_web/src/api/types.ts`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/client_web/src/components/layout/AppShell.tsx`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/client_web/src/components/chat/ChatPanel.tsx`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/client_web/src/components/chat/ErrorMessage.tsx`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/gateway/server.ts`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/config.ts`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/adapters/openai-compatible.json`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/adapters/index.ts`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/client_web/src/components/settings/SettingsModal.test.tsx`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/gateway/auth-routes.integration.test.ts`
- `/home/hex/Project/BrainDrive-Test-01/builds/typescript/adapters/index.test.ts`
- `/home/hex/Reference/Designs/BrainDrive-MVP/Settings - Backup/settings-backup-panel-spec.md`
- `/home/hex/Reference/Designs/BrainDrive-MVP/Settings - Tailscale/settings-tailscale-access-panel-spec.md`
- `/home/hex/Reference/BrainDrive-Library/system/templates/spec-template.md`

### Commands Reviewed / Run

- `pwd && git branch --show-current && git status --short`
- `sed -n '1,240p' '/home/hex/.codex/attachments/d7e39514-f347-43f2-a077-676b056acab5/pasted-text.txt'`
- `sed -n '241,520p' '/home/hex/.codex/attachments/d7e39514-f347-43f2-a077-676b056acab5/pasted-text.txt'`
- `sed -n '1,260p' /home/hex/.codex/skills/feature-spec/SKILL.md`
- `sed -n '1,260p' /home/hex/Reference/BrainDrive-Library/system/templates/spec-template.md`
- `rg -n "AI Models|Models|model|provider|OpenRouter|BrainDrive Models|ollama|api key|Settings" ...`
- `find '/home/hex/Reference/Designs/BrainDrive-MVP' -maxdepth 3 -type f ...`
- Focused `sed` and `rg` reads for SettingsModal, gateway settings routes, API types, adapter config, and tests.

### Verification Not Run

No product code or tests were modified for this spec-only task. Automated test commands are listed in Test Strategy for future implementation verification.

## Approval

- [ ] Reviewed by: _______________
- [ ] Date: _______________
- [ ] Ready for Planning: [ ]
