# AI-model — unlimited + fair use (geen credits voor de gebruiker)

> Owner-beslissing 2026-06-19 (vervangt het credit-pack-model van 2026-06-18).
> SSOT interne weging in code: `lib/core/ai/ai_credit_costs.dart`.
> Meet-laag live (`ai_usage_logs` + ai-proxy). Handhaving = fair use, voorlopig handmatig.

## Model

- **Plus = alle AI-opties inbegrepen, "unlimited" met fair-use-policy.** Geen
  credit-teller, geen credit-packs, geen "saldo op"-moment voor de gebruiker.
  Dit versimpelt de propositie en past bij de differentiator ("geen holle tier;
  Plus voelt gul").
- **We blijven meten per account/gezin** (`ai_usage_logs`). Daarop zetten we
  intern een **soft fair-use-limiet**; gebruik dat daar structureel overheen gaat
  benaderen we — **voorlopig handmatig** (monitoren + bij een echte uitschieter
  contact/throttle), later geautomatiseerd (zachte throttle/melding).
- **Waarom dit veilig is bij "unlimited":** alle AI is **gebonden, gestructureerde
  actie** (categoriseren, document/foto-extractie, suggesties, gap-detectie,
  capture, en de gegronde assistent hieronder). Geen open chat → geen ongebonden
  token-kraan. Een lichte actie kost ~$0,002–0,005, een document ~$0,003–0,01;
  zelfs 1000 acties/maand ≈ ~$3–10 — ruim binnen een Plus van €59,99/jr.

## Fair-use-signaal

- **Basis = tokens** per gezin/maand (`ai_usage_logs`, trueste kostproxy).
- **Gewogen-actie-view ernaast:** de tabel hieronder is geen gebruikersprijs meer
  maar een **interne weging** (licht 1 / document 2 / bulk 3) zodat we
  "document-scan telt zwaarder dan categorisatie" kunnen meewegen in de soft-limit.

| Weging | Actie | feature_id | Status |
|---|---|---|---|
| **1** | Inbox-categorisatie | `inbox_categorize` | live |
| **1** | Dagbriefing-samenvatting | `briefing_summarize` | live |
| **1** | Suggesties (dag-batch) | `suggestions_rewrite` | live |
| **1** | Vandaag gap-detectie | `vandaag_gap_detection` | gepland |
| **1** | Assistent — opzoek/route (per bericht) | `assistant_query` | v1 |
| **1** | Capture-routering (tekst→module) | `capture_route` | gepland |
| **1** | Simpele foto-scan | `document_extract` | live |
| **1** | Velden vertalen (bijv. recept naar app-taal) | `translate_fields` | live |
| **2** | Assistent — ingestion (create/update) | `assistant_ingest` | v2 |
| **2** | PDF / document-analyse | `document_pdf_extract` | gepland |
| **2** | Tekst-extractie (geplakt/scraped) | `text_extract` | live |
| **2** | Capture-extractie per module | `capture_extract` | gepland |
| **2** | Share-sheet capture | `share_sheet_capture` | gepland |
| **2** | URL-pagina-extractie | `url_page_extract` | gepland |
| **3** | Grote bulk-/import-actie | `bulk_import` | gepland |

Onbekende/nieuwe acties vallen terug op weging **1** (`kAiDefaultCredits`).

## De assistent — gegronde module-assistent (géén open chat)

Owner-beslissing 2026-06-19. De assistent is **geen open chatbot** maar een
**router/formatter over je eigen app-data** — vergelijkbaar met SnapSnel's
RAG/Feynman-chat die alleen z'n kennisbank gebruikt. Hij beantwoordt en doet
**uitsluitend** dingen die op de werkelijke content van dit gezin/deze gebruiker
slaan en over de modules gaan.

**Werking — twee fasen** (hergebruikt het `json_schema`-twee-fase-patroon uit
[`ai-capture-models.md`](ai-capture-models.md)):

1. **Route:** gestructureerde call → `{ intent: query|create|update|unsupported,
   module, action, params, confidence }`. Geen passende intent / te lage
   confidence → **beleefde weigering** ("Ik help alleen met je gezinsgegevens —
   verjaardagen, agenda, sport…").
2. **Uitvoeren:** de app draait deterministisch de repo-query (en formatteert kort
   het antwoord uit díe data), of toont bij een schrijf-actie een **bevestig-kaart**
   vóór er iets verandert.

**Vier guardrails (beperken misbruik + token-kost):**
- **Vaste intent-set, geen vrije generatie** — geen tool/intent → geen algemeen
  antwoord. Dé abuse-rem: niet bruikbaar als gratis ChatGPT.
- **Alleen app-data, household-scoped** — antwoorden komen uit de repo's van dít
  gezin (viewer-scoped), nooit uit model-kennis. Geen data van andere gezinnen.
- **Bevestigen vóór schrijven** — een create/update wordt als kaart voorgesteld
  ("Verjaardag: Robin, 15 april — Bevestigen?"); de AI muteert nooit stil.
- **Begrensde tokens** — router + korte format = kleine, voorspelbare calls.

**Fasering:** **v1** = gegronde vraag/opzoek (read-only, weigert off-topic),
vervangt de eerdere open assistent. **v2** = ingestion (create/update met
bevestiging). Beide delen de router; deze router ís tevens de capture/ingestion-laag
(tekst, gedeelde foto/PDF lopen er straks doorheen).

**Bijvangst — uitbreidbaar:** een nieuwe module krijgt AI door z'n **intenties** te
registreren (read/write + params-schema + repo-binding), aangehaakt op de bestaande
injectable module-registratie (zelfde patroon als `aiExtractor`).

## Pakketten

Voor nu zit **alle AI in één pakket** (Plus). **Later** moet de assistent
(of een andere zware feature) **achter een hoger pakketvlak** te zetten zijn
(bv. Plus → Premium) via een **feature-tier-vlag**, analoog aan de net gebouwde
module-tier-seam (`module_tier_overrides`) maar dan per feature i.p.v. per module —
met één regel, geen herbouw. Pakketnamen: nog te bepalen (apart sparren).

## Implementatiestatus

- ✅ Meet-laag: elke AI-call logt tokens per gezin/feature in `ai_usage_logs`
  (migratie 0011 + ai-proxy). *NB: ai-proxy is herdeployd (v3) en logt.*
- ✅ Interne weging als code-SSOT: `lib/core/ai/ai_credit_costs.dart` (nu weging,
  geen gebruikersprijs).
- ⏳ **Volgende stap:** client stuurt per call een `featureId` mee (→ `AiRequest`
  + de live callsites + `ProxyAiClient`), zodat `ai_usage_logs` per feature
  uitsplitst i.p.v. allemaal als `ai_proxy` — basis voor de fair-use-weging.
- ⏳ Gegronde assistent v1 (router→opzoek) — in aanbouw.
- ⏳ Fair-use soft-limit dashboard + (later) automatische zachte throttle.

## Vervallen t.o.v. 2026-06-18
- Credit-packs (geen koopbare credits), credit-saldo/-teller, "blokkeren bij 0",
  en de **consumable store-SKU** (alleen de abonnement-SKU's Family/Solo blijven).
  Dit verkleint de B5/RevenueCat-scope merkbaar.
