From 16a7849e7139f73cbb26541dea7a51819779a383 Mon Sep 17 00:00:00 2001 From: "Sven (AAMOS AI)" Date: Mon, 10 Aug 2026 02:43:13 +0700 Subject: [PATCH] =?UTF-8?q?docs:=20persona-charter=20+=20personaliseringsp?= =?UTF-8?q?lan=20godk=C3=A4nd=20med=20justeringar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Checkar in docs/31-persona-personalisering.md (nordstjärna). - Uppdaterar docs/34-personalisering-implementation.md: - R7: välmående / icke-restriktiv hälsa-framing. - Personaliseringstexter = mallar med grundade fakta, inte fri AI-text. - ai_inferred-minnen: låg konfidens, användarbekräftelse, aldrig säkerhetsbeslut. - UPDATE_USER_MEMORY: budgettak + mock-mönster som skanning. - S0 får starta; S1 inväntar godkännande. - Staging helig, prod orörd. --- docs/31-persona-personalisering.md | 162 ++++++++++++++++++++++ docs/34-personalisering-implementation.md | 61 +++++--- 2 files changed, 203 insertions(+), 20 deletions(-) create mode 100644 docs/31-persona-personalisering.md diff --git a/docs/31-persona-personalisering.md b/docs/31-persona-personalisering.md new file mode 100644 index 0000000..9ad80d9 --- /dev/null +++ b/docs/31-persona-personalisering.md @@ -0,0 +1,162 @@ +# Cibello – Persona & personalisering (nordstjärna) + +> Detta dokument definierar **en gång** hur Cibello ska kännas personlig, så att +> alla AI-nära funktioner (sök, "vad ska vi äta", rekommendationer, proaktiva +> puffar, receptpresentation) byggs mot samma själ i stället för att uppfinnas +> per funktion. Det är en kravspec för *känslan* – inte en teknisk migrering. +> Allt nedan förankras i motorer som redan finns i plattformen. + +--- + +## 1. Nordstjärnan + +Cibello är inte "ännu en receptsök". Cibello är en **Food Twin som har din rygg**: +den bär den mentala lasten kring mat åt dig, för att den faktiskt känner ditt kök, +dina smaker och ditt folk. Målet är att en vanlig, trött människa ska känna att +appen *ser* dem och gör vardagen enklare – aldrig att de blir övervakade eller +bedömda. + +Ledstjärna i en mening: **"Den vet var räkosten står, förstår att du tycker den +är god, och är ärlig om att den kanske minns fel."** + +--- + +## 2. Röst & personlighet + +- **Varm och mänsklig**, som någon som bor i hemmet och råkar ha koll på maten. + Erkänner suget ("jag fattar, den är ju god"), dömer aldrig. +- **Kompetent men ödmjuk**. Säker när den vet, öppen när den gissar. Skryter inte. +- **Lätt kvick** där det passar, men aldrig på användarens bekostnad och aldrig så + att skämtet skymmer nyttan. +- **Kort och konkret**. En trött människa vill ha svar, inte en essä. +- **Aldrig en robot, aldrig en tjatig coach.** Ingen pekpinne, ingen skam. + +Rösten är en varumärkesegenskap – den ska kunna finjusteras centralt, inte +hårdkodas per skärm. + +--- + +## 3. Vad appen får känna till (och varifrån) + +All personalisering byggs på data som redan samlas in. "Lära känna användaren" är +till stor del att *väva ihop* dessa källor – inte att samla in nytt. + +| Vad appen kan veta | Källa som redan finns | +| --- | --- | +| Vad du har hemma och var | `inventory_items` + `storage_locations` (+ `sublocation`) | +| Hur säker den är på att det stämmer | Trust-motorn (`trusted`/`decaying`/`stale`) | +| Vad du gillar/ogillar | `taste_signals`, betyg, laghistorik | +| Hur mycket ni brukar äta | `cooking_assumption_profiles` | +| Vilka ni är i hushållet | `household_members`, personer/portioner | +| Allergener & kostbehov | `user_health_profiles` (**alltid användarsatt**) | +| Uttalade mål & preferenser | onboarding-mål, `user_preferences` | +| Uttryckliga minnen | `memory_items` / `food_memories` ("barnen ogillar broccoli") | +| Språk | locale-preferens (×12) | + +--- + +## 4. Grundregeln: aldrig påhittat + +Detta är regeln som gör det personliga **magiskt i stället för trasigt eller +creepy**, och den är icke-förhandlingsbar: + +- Appen påstår **bara** fakta som finns i verklig data. "Står i kyldörren" endast + om lager + plats säger det. Ingen påhittad hylla, ingen påhittad vara. +- Osäkerhet kommer från **trust-motorn**, aldrig från ett påklistrat skämt. En + `decaying`/`stale` vara får hedgen "…om du inte flyttat/ätit den"; en `trusted` + vara får en säker ton. +- Personalisering bygger på **observerat beteende + uttalade preferenser** – aldrig + på gissningar om känsliga egenskaper. +- Detaljnivån följer datan: "i kylen" alltid, "övre hyllan till vänster" bara när + det registrerats. + +Detta är samma princip som håller skanningen trovärdig, applicerad på tonen. + +--- + +## 5. Samtycke, transparens & kontroll + +"Appen känner mig" blir varmt när jag har kontroll, och kusligt när profilen är +osynlig. Därför: + +- Allt appen minns ska vara **synligt och redigerbart** för användaren + (minnesskärmen). Inget hemligt profilbygge. +- Personalisering är **samtyckesgatad** och kan stängas av per kategori. +- Appen visar gärna **varför**: "jag föreslår detta för att du lagat det tre + gånger" – proveniens skapar förtroende. +- Inget känsligt härleds tyst. Allergener och kostbehov **sätter användaren**. +- Radering är redan komplett (GDPR-flödet): det appen vet kan alltid tas bort. + +--- + +## 6. Ton & välmående + +En app som känner din mat måste vara snäll. Icke-förhandlingsbart: + +- **Aldrig skam** för vad du äter, hur mycket, eller för svinn. Hjälp, polisa inte. +- **Ingen skadlig kaloripolisiär.** Stötta en sund relation till mat; peppa, + sänk stressen, minska svinn *varsamt* (mjölkprincips-andan riktad mot människan). +- **Säkerhet går före personlighet.** Allergenvarningar är hårda fakta, aldrig + mjukade av ton, aldrig AI-gissade. +- **Familjesäkert.** Hushåll har barn; håll språk och innehåll åldersanpassat. + +--- + +## 7. Hur personligheten syns per funktion + +Samma själ, konsekvent applicerad: + +- **"Vad ska vi äta?" / rekommendationer:** tonat mot smak + vad som finns hemma + + vad som snart går ut + kostbehov. Förklarar valet kort. +- **Fritextsök (byggt):** räkost-svaret – varm ton, FoodTwin-plats, trust-hedge, + aldrig tyst tomhet. +- **Proaktiva puffar (opt-in, dismissbara):** "din grädde närmar sig bäst-före – + här är två recept du brukar gilla som använder den." Aldrig tjat. +- **Receptpresentation:** respektera kostbehov, flagga/dölj allergener tydligt. +- **Onboarding:** lär målen, sätt relationen – hjälpsam direkt, mer personlig med + tiden. + +--- + +## 8. Progressiv förtrogenhet + +Appen ska "lära känna dig" **gradvis**: börja hjälpsam men generell, bli mer +personlig i takt med att den observerar mer – och alltid förtjäna förtroendet. +Aldrig påflugen tidigt ("jag ser att du…" innan den faktiskt sett något). + +--- + +## 9. Lokalisering av personlighet + +Rösten ska **översättas, inte transkriberas** till alla 12 språk. En svensk +kvickhet motsvaras av en naturlig formulering i mål­språket, inte en ordagrann +översättning. Paritetstest gäller för alla persona-strängar precis som för övrig +i18n. + +--- + +## 10. Cibello får ALDRIG + +- hitta på fakta, platser eller varor som inte finns i datan +- gissa allergener eller kostbehov +- skämma användaren för mat, mängd eller svinn +- agera på användarens vägnar i säkerhetskritiska beslut utan bekräftelse +- exponera en hushållsmedlems privata data för en annan olämpligt +- bygga en osynlig profil användaren inte kan se, redigera eller radera + +--- + +## 11. Koppling till befintliga motorer (så det blir ihopkoppling, inte nybygge) + +| Persona-behov | Befintlig motor att väva in | +| --- | --- | +| "Vet var grejen står" | inventory + storage_locations + sublocation | +| "Ärlig om osäkerhet" | trust-motorn (states + score) | +| "Kommer ihåg mig" | memory_items / food_memories | +| "Vet vad jag gillar" | taste_signals + laghistorik | +| "Vet hur mycket vi äter" | cooking_assumption_profiles | +| "Respekterar mina behov" | user_health_profiles (användarsatt) | +| "Jag har kontroll" | user_consents + GDPR-radering (klart) | +| "Pratar mitt språk" | i18n ×12 | + +Nästan varje personlig känsla har redan en motor. Uppgiften är att ge den röst. diff --git a/docs/34-personalisering-implementation.md b/docs/34-personalisering-implementation.md index 6fc5a15..be34ffd 100644 --- a/docs/34-personalisering-implementation.md +++ b/docs/34-personalisering-implementation.md @@ -2,9 +2,7 @@ > Status: **plan för granskning**. Ingen funktionskod får skrivas förrän planen är godkänd. > Omfattning: Staging endast. Prod/AAMOS förblir orörd. -> Mål: mappa persona-chartern (se `docs/31-persona-nordstjärnan.md`)* till konkreta, granskningsbara skivor som återanvänder befintliga motorer. - -\* *Dokumentet `docs/31-persona-nordstjärnan.md` saknas för närvarande i repot. Planen nedan bygger på de principer och datamodeller som redan finns i Del 3–12, Del 29, FAS3/4-audits och minnesarkitekturen i `packages/memory-client`. Om en separat persona-charter checkas in bör den refereras explicit här innan skiva 1 påbörjas.* +> Mål: mappa persona-chartern (`docs/31-persona-personalisering.md`) till konkreta, granskningsbara skivor som återanvänder befintliga motorer. --- @@ -13,7 +11,7 @@ | Yta | Nuvarande läge | Persona-effekt efter Spår 1 | Varför denna yta? | | --- | --- | --- | --- | | **A. "Vad ska vi äta?" / `GET /v1/recommendations/what-to-eat`** | ✅ Byggd. Rankar recept efter täckning, utgångsdatum, näringsfit, smak, betyg, säsong, högtid, tid, budget, variation, väder, craving. | Recept rangordnas med tydlig proveniens som inkluderar *användarens egna minnen* ("Du lagade kycklinggryta tre tisdagar i rad — här är en annan variant"), *hushållsförbrukningsmönster* och *utgångs-varor*. | Appens viktigaste surface; här märks personliga förslag mest. | -| **B. Grupperade sök-svar / recept-sök** | 🔧 Delvis byggd (`/v1/recipes/search` finns troligen; söksvar är grundade i katalogen). | Sökresultat tonas av användarens smakprofil, hushållsbegränsningar och lager. Proaktivt utesluter allergener/undvikanden. | Sök är en aktiv användarintent; personlig rangordning måste vara förklarlig. | +| **B. Grupperade sök-svar / recept-sök** | 🔧 Delvis byggd (`/v1/recipes/search` finns troligen; söksvar är grundade i katalogen). | Sökresultat tonas av användarens smakprofil, hushållsbegränsningar och lager. Proaktivt utesluter allergener/undvikanden. **Bygger PÅ befintligt grundat svar (lager + plats + trust-hedge); no-fabrication-grundningen bevaras.** | Sök är en aktiv användarintent; personlig rangordning måste vara förklarlig. | | **C. Proaktiva puffar** | 🔧 `SEND_EXPIRY_NOTIFICATION` körs dagligen kl 07. Matlådepåminnelser finns. | Nya puffar: "Gurkan börjar se trött ut — tre recept du brukar gilla med gurka", "Ni har ätit risotto ofta på söndagar; vill du planera en?" | Hög användarnytta, låg frekvens, kräver explicit opt-in. | | **D. Receptrangordning efter smak/hälsa/lager** | ✅ Motor finns (`packages/recommendation-engine/src/scoring.ts`). | Skapa tre fördefinierade vyer: **Smak** (favoritkök + taste_signals), **Hälsa** (näring mot dagsmål + health_profile), **Lager** (täckning + utgår-snart). Användaren växlar; ingen hemlig viktning. | Ger användaren kontroll och transparens. | | **E. Onboarding-relationen** | ✅ Onboarding med mål, allergier, favoritkök. | Onboarding-klassifikationer skrivs som `user_stated`-minnen och `taste_signals`; de synkroniseras tillbaka till "Vad plattformen vet om mig". | Tidigt förtroende: användaren ser att svaren används. | @@ -64,11 +62,15 @@ Persona-chartern översätts till följande tekniska regler. Varje regel ska gå ### R1. Grundat, aldrig påhittat - Alla personliga påståenden måste ha ett spårbart ursprung i `memory_items.origin` (`user_stated`, `observed`, `ai_inferred`). -- `ai_inferred`-poster visas aldrig utan att användaren kan se att det är ett "mönster vi har observerat" och kan pausa/radera. +- `ai_inferred`-poster: + - Har **låg startkonfidens** (t.ex. 0.5). + - Formuleras som "ett mönster vi sett", aldrig "du gillar". + - Kräver **användarbekräftelse eller avfärdande** innan de påverkar rekommendationer som säkerhetsbeslut. + - Driver **aldrig** säkerhetsbeslut (allergen/diet/exkludering). - Ingen AI får fabricera recept, ingredienser eller påståenden om användaren. ### R2. Samtycke + synligt/redigerbart minne -- `personalization`-samtycke krävs för alla personliga ytor (redan i `userConsents`). +- `personalization`-samtycke krävs för alla personliga ytor (redan i `userConsents`). **Enkeltflaggat samtycke är OK för Spår 1**; granulär uppdelning skjuts till senare spår om behov uppstår. - "Vad plattformen vet om mig" (`GET /v1/me/memory`) visar alla minnen, inklusive ursprung och konfidens. - Användaren kan rätta (`PATCH /v1/me/memory/:id`), pausa (`POST /v1/me/memory/pause-all`) och radera (`DELETE /v1/me/memory/:id` samt `DELETE /v1/me/memory`). - Användarkorrigering ändrar `origin` till `user_stated` och `confidence` till `1`. @@ -91,13 +93,23 @@ Persona-chartern översätts till följande tekniska regler. Varje regel ska gå ### R6. Proveniens - Varje personaliserat förslag ska kunna förklara *varför* det valdes. -- Exempel på provenienssträngar: - - "För att du har berättat att du gillar italienskt kök." - - "För att ni har tre ägg som bör användas inom två dagar." - - "För att du lagat kycklinggryta tre gånger den senaste månaden." - - "För att det passar ditt återstående proteinbehov i dag." +- **Personaliseringstexter (proveniens, why, puffar) genereras från mallar med grundade fakta**, inte fri AI-text. Mallarna är översatta, skam- och fabriceringsfria per konstruktion. +- Exempel på mallar (svenska): + - `"För att du har berättat att du gillar {{cuisine}}."` + - `"För att ni har {{count}} {{ingredient}} som bör användas inom {{days}} dagar."` + - `"För att du lagat {{recipe}} {{count}} gånger den senaste månaden."` + - `"För att det passar ditt återstående proteinbehov i dag."` +- Förbudslistan (R3) behålls som skyddsnät för mall-renderade strängar. +- **Fri AI-text får endast användas för `ai_inferred`-minnesförslag** (events-only + Zod + användarbekräftelse). - Proveniens lagras/transporteras i `ScoredRecommendation.parts` + en ny valfri `provenance` array. +### R7. Välmående — icke-restriktiv hälsa-framing +- Hälso-vyn och all näringsmåls-framing ska vara **stödjande och icke-restriktiv**. +- Tillåten copy: `"Passar ditt proteinmål"`, `"Bidrar till dina grönsaker i dag"`. +- **Förbjuden copy:** `"Du har överskridit ditt kalorimål"`, `"Bara X kcal kvar"`, `"Begränsa dig"`, `"Undvik …"` eller annan negativ/restriktiv framing. +- Näringsmål visas endast för användare som själva har satt dem i `userHealthProfiles`/`userPreferences`. +- Copy-granskning + eval-fall ska täcka välmående-framing. + --- ## 4. SKIVINDELNING — små reviewbara skivor med testplan @@ -106,14 +118,16 @@ Ingen skiva får påbörjas förrän föregående är godkänd. Varje skiva leve ### Skiva S0 — förberedelse (inga användarfunktioner) **Innehåll:** -- Checka in `docs/31-persona-nordstjärnan.md` om den finns separat; annars lyft in charter-reglerna ovan i Del 34. -- Säkerställ att `userConsents` för `personalization` läses korrekt överallt. +- Checka in `docs/31-persona-nordstjärnan.md` och förankra R1–R7 explicit mot varje avsnitt i chartern. +- Säkerställ att `userConsents` för `personalization` läses korrekt överallt. **Enkeltflaggat `personalization`-samtycke är OK för Spår 1** (ingen granulär uppdelning av personalisering ännu). - Uppdatera `packages/recommendation-engine/src/types.ts` med `provenance` och `memorySignalIds` på `ScoredRecommendation`. - Skriv test-fixtur för `taste_signals`, `memory_items`, `cooking_assumption_profiles`. +- Sätt upp budgettak + mock-testmönster för `UPDATE_USER_MEMORY` (samma mönster som skanning: `GEMINI_DAILY_BUDGET_USD`, `MockAamosClient`, hermetiska tester). **Testplan:** - Typecheck och enhetstester gröna. - Fixturen kan skapa en användare med samtycken, minnen, smaksignaler och matlagningshistorik. +- `UPDATE_USER_MEMORY`-anrop kan mockas och kostnadsräknas utan att träffa AAMOS. **Estimat:** 1 dag. @@ -168,6 +182,8 @@ Ingen skiva får påbörjas förrän föregående är godkänd. Varje skiva leve - Koppla minnen till reella ytor: t.ex. "Du gillar italienskt kök" → visar vilka recept som påverkas. - Lägg till `GET /v1/me/memory/impact` som returnerar vilka rekommendationer som påverkas av ett specifikt minne (utan att exponera andras data). - Förbättra `UPDATE_USER_MEMORY`-jobbet: + - Använd samma budgettak + kostnadsräkning som skanning (`packages/ai-contracts/src/gemini.ts`, `GEMINI_DAILY_BUDGET_USD`). + - Hermetiska tester med `MockAamosClient` (inga API-nycklar i tester, inga subagents). - Be AAMOS om nya minnesförslag med explicit prompt som förbjuder påhitt. - Validera output mot Zod-kontraktet. - Avvisa förslag som saknar stöd i events. @@ -257,13 +273,17 @@ Ingen skiva får påbörjas förrän föregående är godkänd. Varje skiva leve ## Godkännande-checklista för planen -- [ ] Persona-charter (`docs/31-persona-nordstjärnan.md`) checkas in eller refereras korrekt. -- [ ] Yt-inventeringen täcker alla AI-nära ytor som ska personaliseras i Spår 1. -- [ ] Motor-mappningen anger befintliga motorer/data för varje yta; inga parallella motorer. -- [ ] Charter-reglerna (R1–R6) är tydliga och testbara. -- [ ] Skivindelningen är tillräckligt liten; varje skiva har testplan. -- [ ] Risker och testmetoder accepteras. -- [ ] Ingen kod skrivs förrän denna plan är godkänd. +- [x] Persona-charter (`docs/31-persona-personalisering.md`) checkas in och förankras. +- [x] Yt-inventeringen täcker alla AI-nära ytor som ska personaliseras i Spår 1. +- [x] Motor-mappningen anger befintliga motorer/data för varje yta; inga parallella motorer. +- [x] Charter-reglerna (R1–R7) är tydliga och testbara. +- [x] Personaliseringstexter = mallar med grundade fakta, inte fri AI-text. +- [x] `ai_inferred`-minnen: låg konfidens, användarbekräftelse, driver inte säkerhetsbeslut. +- [x] `UPDATE_USER_MEMORY`: budgettak + mock-mönster som skanning. +- [x] Skivindelningen är tillräckligt liten; varje skiva har testplan. +- [x] Risker och testmetoder accepteras. +- [x] Ingen kod skrivs förrän denna plan är godkänd. +- [x] S0 får starta; S1 påbörjas efter godkännande. --- @@ -272,3 +292,4 @@ Ingen skiva får påbörjas förrän föregående är godkänd. Varje skiva leve | Datum | Revision | Författare | | --- | --- | --- | | 2026-08-10 | Initial plan för granskning | Sven | +| 2026-08-10 | Godkänd med justeringar: R7 välmående, mall-baserade texter, ai_inferred-konfidens, UPDATE_USER_MEMORY-budget, docs/31 incheckad | Sven / Johan |