diff --git a/docs/intent/architecture-swift-cortex-v2.md b/docs/intent/architecture-cortex-v2.md similarity index 99% rename from docs/intent/architecture-swift-cortex-v2.md rename to docs/intent/architecture-cortex-v2.md index 8130571..c38bbaa 100644 --- a/docs/intent/architecture-swift-cortex-v2.md +++ b/docs/intent/architecture-cortex-v2.md @@ -1,6 +1,6 @@ -# 🧠 Swift Cortex V2 - Uitgebreid Architectuurplan +# 🧠 Cortex V2 - Uitgebreid Architectuurplan -**Project:** Swift Intent System V2 +**Project:** Cortex Intent System V2 **Versie:** 2.0 **Datum:** 29-12-2025 **Status:** Technisch Ontwerp @@ -27,9 +27,9 @@ ## 1. Executive Summary ### Huidige Situatie (V1) -Het huidige Swift systeem is **reactief**: gebruiker geeft commando β†’ systeem voert uit. Het werkt met single-intent classificatie en heeft een two-tier architectuur (lokaal regex + AI fallback). +Het huidige Cortex systeem is **reactief**: gebruiker geeft commando β†’ systeem voert uit. Het werkt met single-intent classificatie en heeft een two-tier architectuur (lokaal regex + AI fallback). -### Doel V2: "The Swift Cortex" +### Doel V2: "The Cortex" Transformatie naar een **agentic systeem** dat: - **Multi-intents** begrijpt ("Zeg Jan af **en** maak notitie") - **Context-aware** is (snapt wie "hij" is, wat "morgen" betekent) @@ -113,7 +113,7 @@ Transformatie naar een **agentic systeem** dat: β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Swift β”‚ β”‚ Artifact β”‚ β”‚ Suggestionβ”‚ + β”‚ Cortex β”‚ β”‚ Artifact β”‚ β”‚ Suggestionβ”‚ β”‚ Store │◄───│ Updates β”‚ β”‚ Toast β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` @@ -716,7 +716,7 @@ import type { AIClassificationResult } from './types'; -const ORCHESTRATOR_SYSTEM_PROMPT = `Je bent de Intent Orchestrator voor Swift, een Nederlands EPD systeem. +const ORCHESTRATOR_SYSTEM_PROMPT = `Je bent de Intent Orchestrator voor Cortex, een Nederlands EPD systeem. ## Je Taak Analyseer de gebruikersinput en extraheer ALLE intenties, ook als er meerdere zijn. @@ -2218,7 +2218,7 @@ export function isCortexV2Enabled(userId?: string): boolean { ### B. Referenties -- [FO Cortex Intent System V2](./fo-swift-intent-system-v2.md) +- [FO Cortex Intent System V2](./fo-cortex-intent-system-v2.md) - [UX Simulatie Next Level](./ux-simulation-intent-next-level.md) - [UX Evaluatie Schaalbaarheid](./ux-evaluation-intent-scalability.md) - [Architecture Proposal V2](./intent-architecture-v2-proposal.md) diff --git a/docs/intent/architecture-intent-scalability.md b/docs/intent/architecture-intent-scalability.md index c192008..2b518c9 100644 --- a/docs/intent/architecture-intent-scalability.md +++ b/docs/intent/architecture-intent-scalability.md @@ -1,3 +1,5 @@ +> **Note:** "Swift" is hernoemd naar "Cortex". Dit document bevat historische referenties naar de oude naam. + # Architecture: Intent System Schaalbaarheid (GGZ) **Document:** Intent System Scalability & Optimization voor GGZ diff --git a/docs/intent/fo-swift-intent-system-v2.md b/docs/intent/fo-cortex-intent-system-v2.md similarity index 91% rename from docs/intent/fo-swift-intent-system-v2.md rename to docs/intent/fo-cortex-intent-system-v2.md index 569b1a3..ae52807 100644 --- a/docs/intent/fo-swift-intent-system-v2.md +++ b/docs/intent/fo-cortex-intent-system-v2.md @@ -1,6 +1,6 @@ -# 🧩 Functioneel Ontwerp (FO) – Swift Intent System V2 +# 🧩 Functioneel Ontwerp (FO) – Cortex Intent System V2 -**Projectnaam:** Swift Intent Architecture V2 +**Projectnaam:** Cortex Intent Architecture V2 **Versie:** v2.0 (Draft) **Datum:** 29-12-2025 **Auteur:** Colin Lit (Antigravity AI) @@ -9,7 +9,7 @@ ## 1. Doel en relatie met het PRD 🎯 **Doel van dit document:** -Dit FO beschrijft de functionele werking van de "Next Gen" Swift Intent Architectuur. Waar V1 focuste op snelheid en basiscommando's ("Reactive"), focust V2 op contextbegrip, meervoudige intenties en proactieve ondersteuning ("Agentic"). +Dit FO beschrijft de functionele werking van de "Next Gen" Cortex Intent Architectuur. Waar V1 focuste op snelheid en basiscommando's ("Reactive"), focust V2 op contextbegrip, meervoudige intenties en proactieve ondersteuning ("Agentic"). πŸ“˜ **Relatie tot vorige documentatie:** Dit document vervangt de architectuur uit `architecture-intent-scalability.md` (Strategie 1: Strict Hierarchy) en kiest voor de **Hybride Route** (Strategie 5 + Agentic extensions) zoals besproken in de UX Evaluatie. @@ -17,7 +17,7 @@ Dit document vervangt de architectuur uit `architecture-intent-scalability.md` ( --- ## 2. Overzicht van de belangrijkste onderdelen -🎯 **Architectuurmodel:** "The Swift Cortex" +🎯 **Architectuurmodel:** "The Cortex" Het systeem bestaat uit drie samenwerkende lagen die elk een andere rol spelen in de interactie: 1. **Layer 1: The Reflex Arc (De Snelle Reflex)** @@ -54,8 +54,8 @@ Het systeem bestaat uit drie samenwerkende lagen die elk een andere rol spelen i ### 4.1 Layer 1: The Reflex Arc (Local First) * **Trigger:** Elke gebruikersinput (spraak/tekst). * **Werking:** Checkt razendsnel (<20ms) of de input matcht met een `Local Pattern` (Regex). -* **Conditie:** Alleen bij **Confidence > 0.9** (vrijwel zeker) voert hij direct uit. -* **Fallback:** Bij twijfel (<0.9) of geen match β†’ *Direct doorsturen naar Layer 2*. +* **Conditie:** Alleen bij **Confidence >= 0.7** (industry standard) voert hij direct uit. +* **Fallback:** Bij twijfel (<0.7), ambiguΓ―teit (top-2 delta <0.1), of escalatie-triggers β†’ *Direct doorsturen naar Layer 2*. ### 4.2 Layer 2: The Intent Orchestrator (AI Router) * **Trigger:** Input die te complex of dubbelzinnig is voor Layer 1. @@ -162,6 +162,6 @@ interface IntentAction { --- ## 8. Bijlagen & Referenties -* **PRD/Vision:** `docs/swift/ux-simulation-intent-next-level.md` +* **PRD/Vision:** `docs/intent/ux-simulation-intent-next-level.md` * **Technical Base:** `lib/cortex/intent-classifier-ai.ts` -* **Legacy Docs:** `docs/swift/intent-architecture-v2-proposal.md` +* **Legacy Docs:** `docs/intent/intent-architecture-v2-proposal.md` diff --git a/docs/intent/haalbaarheidsanalyse-swift-cortex-v2.md b/docs/intent/haalbaarheidsanalyse-cortex-v2.md similarity index 95% rename from docs/intent/haalbaarheidsanalyse-swift-cortex-v2.md rename to docs/intent/haalbaarheidsanalyse-cortex-v2.md index e442810..54c84fd 100644 --- a/docs/intent/haalbaarheidsanalyse-swift-cortex-v2.md +++ b/docs/intent/haalbaarheidsanalyse-cortex-v2.md @@ -1,4 +1,4 @@ -# Haalbaarheidsanalyse: Swift Cortex V2 +# Haalbaarheidsanalyse: Cortex V2 **Datum:** 29-12-2025 **Auteur:** Claude Code (Opus 4.5) @@ -10,7 +10,7 @@ **Conclusie: HAALBAAR met gefaseerde aanpak** -De Swift Cortex V2 architectuur is **goed haalbaar** binnen de bestaande codebase. De huidige implementatie biedt een solide fundament met ~70% van de benodigde infrastructuur al aanwezig. De voorgestelde V2 architectuur sluit naadloos aan op bestaande patterns. +De Cortex V2 architectuur is **goed haalbaar** binnen de bestaande codebase. De huidige implementatie biedt een solide fundament met ~70% van de benodigde infrastructuur al aanwezig. De voorgestelde V2 architectuur sluit naadloos aan op bestaande patterns. | Aspect | Score | Toelichting | |--------|-------|-------------| @@ -303,7 +303,7 @@ export async function classifyIntent(input: string, context?: CortexContext) { ### Haalbaarheid: βœ… JA -De Swift Cortex V2 architectuur is **volledig haalbaar** binnen de bestaande codebase: +De Cortex V2 architectuur is **volledig haalbaar** binnen de bestaande codebase: 1. **70% infrastructuur bestaat al** - Classifier, entity extraction, store, chat API 2. **Incrementeel te bouwen** - Elke fase levert werkende software @@ -344,8 +344,8 @@ Start met **Fase 1: Foundation** - de CortexContext API endpoint. Dit is: ### B. V2 Documentatie Verwijzingen -- `architecture-swift-cortex-v2.md` - Uitgebreid technisch plan -- `fo-swift-intent-system-v2.md` - Functioneel ontwerp +- `architecture-cortex-v2.md` - Uitgebreid technisch plan +- `fo-cortex-intent-system-v2.md` - Functioneel ontwerp - `intent-architecture-v2-proposal.md` - Architectuur voorstel - `mvp-userstories-intent-system.md` - MVP scope diff --git a/docs/intent/intent-architecture-v2-proposal.md b/docs/intent/intent-architecture-v2-proposal.md index 90e1d19..a4ea11d 100644 --- a/docs/intent/intent-architecture-v2-proposal.md +++ b/docs/intent/intent-architecture-v2-proposal.md @@ -1,3 +1,5 @@ +> **Note:** "Swift" is hernoemd naar "Cortex". Dit document bevat historische referenties naar de oude naam. + # Architecture Proposal: Swift Intent System V2 **Status:** Draft diff --git a/docs/intent/mvp-userstories-intent-system.md b/docs/intent/mvp-userstories-intent-system.md index a2bafb8..d100ba5 100644 --- a/docs/intent/mvp-userstories-intent-system.md +++ b/docs/intent/mvp-userstories-intent-system.md @@ -1,3 +1,5 @@ +> **Note:** "Swift" is hernoemd naar "Cortex". Dit document bevat historische referenties naar de oude naam. + # πŸš€ MVP Userstories & Scope: Swift Cortex (Public Prototype) **Betreft:** Scope voor de "Build in Public" fase van het Swift Intent System V2. diff --git a/docs/intent/prd-cortex-v2.md b/docs/intent/prd-cortex-v2.md new file mode 100644 index 0000000..89d2db6 --- /dev/null +++ b/docs/intent/prd-cortex-v2.md @@ -0,0 +1,306 @@ +# Product Requirements Document (PRD) – Cortex V2 + +**Projectnaam:** Cortex Intent System V2 +**Versie:** v1.0 +**Datum:** 30-12-2025 +**Auteur:** Colin Lit (Antigravity AI) + +--- + +## 1. Doelstelling + +**Waarom bouwen we dit?** + +Het huidige Cortex systeem (V1) is **reactief**: de gebruiker geeft een commando, het systeem voert uit. Hoewel dit snel werkt (<100ms), mist het de intelligentie die zorgprofessionals nodig hebben. V2 transformeert Cortex van een "spraakgestuurd toetsenbord" naar een **AI Collega**. + +**Beoogd resultaat:** +> Een werkend prototype dat de kernwaarde van "Agency" demonstreert: het systeem begrijpt **meerdere intenties** in één zin, is **context-aware** (snapt wie "hij" is en wat "morgen" betekent), en geeft **proactieve suggesties** op basis van medische logica. + +**Type release:** MVP / Public Prototype ("Build in Public") + +**Kernprincipe:** +> "We stoppen met optimaliseren voor milliseconden en starten met optimaliseren voor intelligentie." + +--- + +## 2. Doelgroep + +### Primaire gebruikers + +| Rol | Behoeften | Pijnpunten V1 | +|-----|-----------|---------------| +| **Verpleegkundige** | Snelheid, handen-vrij werken, administratieve lastenverlichting | "Ik moet drie losse commando's geven voor één situatie" | +| **Psycholoog** | Nuance, cliΓ«nt-context, emotionele lading | "Het systeem snapt niet dat 'uitzichtloos' een alarmsignaal is" | +| **Psychiater/Regiebehandelaar** | Veiligheid, medicatie-checks, overzicht | "Ik wil dat het systeem meedenkt over labwaardes en interacties" | + +### Stakeholders + +- **Product Owner:** Waarde aantonen, haalbaarheid bewaken +- **Developers:** Technische implementatie, AI-integratie +- **UX Designer:** "Invisible Interface" - minder frictie, meer begrip + +### Gebruikersquote (uit UX simulatie) + +> **Regiebehandelaar:** "'Ontlasten' betekent dat ik mijn *intentie* uitspreek, niet mijn *administratie*. Mijn intentie is 'Zorg voor Jan regelen'. De administratie (agenda, brief, notitie) is jullie probleem." + +--- + +## 3. Kernfunctionaliteiten (MVP-scope) + +### 3.1 The Three-Layer Cortex Model + +| Layer | Functie | Latency | Voorbeeld | +|-------|---------|---------|-----------| +| **Layer 1: Reflex Arc** | Lokale regex voor simpele commando's | <20ms | "Agenda vandaag", "Zoek Jan" | +| **Layer 2: Intent Orchestrator** | AI-classificatie voor complexe/multi-intent zinnen | ~400ms | "Zeg Jan af en maak notitie: grieperig" | +| **Layer 3: Nudge Engine** | Proactieve suggesties na acties | async | "Wondcontrole inplannen over 3 dagen?" | + +### 3.2 MVP Features + +1. **Hybrid Architecture** + - Naadloze switch tussen Reflex (lokaal) en Orchestrator (AI) + - Confidence threshold: >= 0.7 voor lokale afhandeling + - Ambiguity detection: escaleer bij top-2 score delta < 0.1 + +2. **Multi-Intent Support** + - Herkenning van signaalwoorden: "en", "daarna", "ook", "eerst" + - Opsplitsen in Action Chain met sequentiΓ«le uitvoering + - UI: Stacked Cards met progressie-indicatie + +3. **Context Awareness** + - Pronoun resolution: "hij/zij" β†’ actieve patiΓ«nt + - Relatieve tijd: "morgen", "volgende week" β†’ concrete datum + - Context injection: ActivePatient, CurrentView, AgendaToday, RecentIntents + +4. **UI Feedback** + - Processing indicator bij AI-acties + - ActionChainCard voor meerdere acties + - ClarificationCard bij ambigue input + +5. **Basic Nudge (Proof of Concept)** + - Hardcoded protocol: Wondzorg β†’ Wondcontrole suggestie + - NudgeToast met accept/dismiss en countdown timer + +### 3.3 Ondersteunde Intents + +| Intent | Beschrijving | Layer | +|--------|--------------|-------| +| `dagnotitie` | Notitie/rapportage maken | Reflex + Orchestrator | +| `zoeken` | PatiΓ«nt zoeken | Reflex | +| `agenda_query` | Agenda bekijken | Reflex | +| `overdracht` | Dienst overdracht | Reflex | +| `create_appointment` | Afspraak maken | Orchestrator | +| `cancel_appointment` | Afspraak annuleren | Orchestrator | +| `reschedule_appointment` | Afspraak verzetten | Orchestrator | + +--- + +## 4. Gebruikersflows (MVP-flows) + +### Flow 1: Multi-Intent Commando + +``` +Gebruiker: "Zeg Jan af voor vandaag en maak notitie: hij heeft griep" + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Layer 1 (Reflex): Detecteert "en" β†’ Escaleer β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Layer 2 (Orchestrator): Parse naar 2 acties β”‚ +β”‚ 1. cancel_appointment (Jan, vandaag) β”‚ +β”‚ 2. dagnotitie (Jan, "hij heeft griep") β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ UI: ActionChainCard β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ βœ… 1. Afspraak Jan geannuleerd β”‚ β”‚ +β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ +β”‚ β”‚ ⏳ 2. Notitie: "hij heeft griep" β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Flow 2: Context-Aware Pronoun Resolution + +``` +Context: PatiΓ«nt "Marie de Vries" is geopend in dossier + +Gebruiker: "Maak notitie voor haar: medicatie ingenomen" + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Layer 2: Resolves "haar" β†’ Marie de Vries β”‚ +β”‚ patientResolution: "pronoun" β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +Notitie aangemaakt voor Marie de Vries +``` + +### Flow 3: Proactieve Suggestie (Nudge) + +``` +Gebruiker: "Notitie: wond verzorgd, ziet er goed uit" + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Notitie opgeslagen βœ… β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Layer 3 (Nudge): Protocol "wondzorg-controle" match β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ NudgeToast (bottom-right) β”‚ +β”‚ πŸ’‘ "Wondcontrole inplannen over 3 dagen?" β”‚ +β”‚ [Ja, doe maar] [Nee, bedankt] β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Flow 4: Simpel Commando (Reflex) + +``` +Gebruiker: "Agenda vandaag" + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Layer 1 (Reflex): Match "agenda" pattern β”‚ +β”‚ Confidence: 1.0 β†’ Direct uitvoeren β”‚ +β”‚ Latency: <20ms β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +Agenda artifact opent direct (geen spinner) +``` + +--- + +## 5. Niet in Scope + +De volgende features vallen **bewust buiten** de MVP: + +| Feature | Reden | Post-MVP? | +|---------|-------|-----------| +| **Complete medische protocollen** | Te complex voor prototype | Ja, rule-engine | +| **Rollback/Undo** | Vereist transactie-systeem | Ja | +| **Offline mode** | Prototype veronderstelt internet | Nee (low priority) | +| **Advanced error handling** | Retry-mechanismes, circuit breakers | Ja | +| **Analytics & learning** | Telemetry opslag, model training | Ja | +| **Productie-beveiliging** | NEN7510 compliance, audit logs | Ja (kritiek voor productie) | +| **Externe integraties** | Teams, ECD-koppelingen | Ja | +| **Adaptive confidence** | User-specific thresholds | Nice-to-have | +| **Sentiment analysis** | Emotionele lading detectie | Nice-to-have | + +--- + +## 6. Succescriteria + +### Functionele criteria + +| Criterium | Target | Meetmethode | +|-----------|--------|-------------| +| Multi-intent herkenning | "X en Y" zinnen correct gesplitst | Test dataset (50+ zinnen) | +| Pronoun resolution | "hij/zij/hem/haar" correct resolved | Test met actieve patiΓ«nt context | +| Reflex hit rate | >70% lokaal afgehandeld | Logging metrics | +| AI latency p95 | <800ms | Performance monitoring | +| Nudge trigger | Wondzorg β†’ suggestie getoond | Manual test | + +### UX criteria + +| Criterium | Target | +|-----------|--------| +| Geen "Ik begrijp het niet" | Altijd een poging tot begrip, eventueel met clarification | +| Processing feedback | Spinner bij AI-acties, geen "bevroren" scherm | +| Demo duur | Volledige flow demonstreerbaar in ≀5 minuten | + +### Technische criteria + +| Criterium | Target | +|-----------|--------| +| Reflex latency | <20ms | +| AI fallback werkt | Bij Anthropic 503 β†’ graceful degradation naar Reflex | +| Geen PII in logs | Input gesanitized voor productie logging | + +--- + +## 7. Risico's & Mitigatie + +| Risico | Impact | Kans | Mitigatie | +|--------|--------|------|-----------| +| **AI output inconsistent** | Hoog | Middel | Strikte JSON schema, temperature=0, fallback to unknown | +| **Multi-intent parsing faalt** | Hoog | Laag | Uitgebreide test dataset, fallback naar single intent | +| **Scope creep** | Middel | Hoog | Strikte MVP scope, 6 user stories max | +| **Privacy breach (logs)** | Hoog | Laag | Input sanitization, geen PII in production logs | +| **Anthropic API down** | Middel | Laag | Graceful degradation naar Reflex-only mode | +| **Performance degradatie** | Middel | Laag | Caching, monitoring, threshold tuning | +| **False positive Nudge** | Laag | Middel | Specifieke regex, word boundaries, test edge cases | + +--- + +## 8. Roadmap / Vervolg (Post-MVP) + +### Fase 1: MVP (Nu) +- Hybrid architecture (Reflex + Orchestrator) +- Multi-intent support +- Context awareness +- Basic Nudge (wondzorg) + +### Fase 2: Enhanced Nudge (Post-MVP) +- Meerdere protocol rules (medicatie, crisis) +- Admin UI voor rule management +- NLP/AI voor complexere matching + +### Fase 3: Productie-ready +- NEN7510 compliance +- Audit logging +- Advanced error handling (retry, circuit breaker) +- Rollback support + +### Fase 4: Intelligence +- Adaptive confidence (user-specific thresholds) +- Sentiment analysis +- Learning from corrections +- Predictive suggestions + +### Fase 5: Integraties +- ECD-koppelingen (PinkRoccade, Nedap) +- Teams/Slack integratie +- Voice-first mobile app + +--- + +## 9. Bijlagen & Referenties + +### Gerelateerde documenten + +| Document | Locatie | Beschrijving | +|----------|---------|--------------| +| FO Cortex V2 | `docs/intent/fo-cortex-intent-system-v2.md` | Functioneel ontwerp | +| TO Cortex V2 | `docs/intent/to-cortex-v2.md` | Technisch ontwerp | +| Architectuur V2 | `docs/intent/architecture-cortex-v2.md` | Uitgebreid architectuurplan | +| Haalbaarheidsanalyse | `docs/intent/haalbaarheidsanalyse-cortex-v2.md` | Gap analyse en effort schatting | +| MVP User Stories | `docs/intent/mvp-userstories-intent-system.md` | User stories en acceptatiecriteria | +| UX Evaluatie | `docs/intent/ux-evaluation-intent-scalability.md` | UX perspectief op architectuur | +| UX Simulatie | `docs/intent/ux-simulation-intent-next-level.md` | Brainstorm "Next Level" features | + +### Tech stack + +- **Frontend:** Next.js 15, React, TailwindCSS, shadcn/ui +- **State:** Zustand +- **Backend:** Next.js API Routes +- **Database:** Supabase (PostgreSQL) +- **AI:** Claude 3.5 Haiku (Anthropic) + +### Versie historie + +| Versie | Datum | Auteur | Wijzigingen | +|--------|-------|--------|-------------| +| 1.0 | 30-12-2025 | Colin Lit | Initieel document | diff --git a/docs/intent/review-swift-cortex-v2.md b/docs/intent/review-cortex-v2.md similarity index 93% rename from docs/intent/review-swift-cortex-v2.md rename to docs/intent/review-cortex-v2.md index 5ed6458..985746d 100644 --- a/docs/intent/review-swift-cortex-v2.md +++ b/docs/intent/review-cortex-v2.md @@ -1,13 +1,13 @@ -# Review Rapport: Swift Cortex & Intent System V2 +# Review Rapport: Cortex & Intent System V2 -**Datum:** 29-12-2025 -**Betreft:** Review van `architecture-swift-cortex-v2.md` en `fo-swift-intent-system-v2.md` +**Datum:** 29-12-2025 +**Betreft:** Review van `architecture-cortex-v2.md` en `fo-cortex-intent-system-v2.md` **Reviewers (Simulatie):** Architect, Backend Dev, Frontend Dev, UX Designer, QA Engineer --- ## 1. Algemene Conclusie -Het voorgestelde **Hyper-Hybrid model (Swift Cortex)** is een sterke, volwassen architectuur die de grootste pijnpunten van V1 (traagheid bij simpele taken, domheid bij complexe taken) effectief oplost. De opsplitsing in drie lagen (Reflex, Orchestrator, Nudge) is logisch en schaalbaar. +Het voorgestelde **Hyper-Hybrid model (Cortex)** is een sterke, volwassen architectuur die de grootste pijnpunten van V1 (traagheid bij simpele taken, domheid bij complexe taken) effectief oplost. De opsplitsing in drie lagen (Reflex, Orchestrator, Nudge) is logisch en schaalbaar. **Oordeel:** βœ… **Go for launch**, mits onderstaande punten in acht worden genomen. diff --git a/docs/intent/to-cortex-v2.md b/docs/intent/to-cortex-v2.md new file mode 100644 index 0000000..913e80e --- /dev/null +++ b/docs/intent/to-cortex-v2.md @@ -0,0 +1,1433 @@ +# Technisch Ontwerp (TO) – Cortex V2 + +**Projectnaam:** Cortex Intent System V2 +**Versie:** v1.1 +**Datum:** 30-12-2025 +**Auteur:** Colin Lit (Antigravity AI) + +--- + +## 1. Doel en relatie met PRD en FO + +**Doel van dit document:** +Dit Technisch Ontwerp (TO) beschrijft **hoe** het Cortex V2 systeem technisch wordt gebouwd. Het document vertaalt de functionele specificaties uit het FO naar concrete architectuur, techstack, datamodellen en implementatiedetails. + +**Relatie met andere documenten:** +- **FO:** `fo-cortex-intent-system-v2.md` - Beschrijft het *wat* en *waarom* +- **Architectuur:** `architecture-cortex-v2.md` - High-level architectuurvisie +- **MVP Scope:** `mvp-userstories-intent-system.md` - User stories en acceptatiecriteria +- **Haalbaarheid:** `haalbaarheidsanalyse-cortex-v2.md` - Gap analyse en effort schatting + +**Kernprincipe:** +> "We stoppen met optimaliseren voor milliseconden en starten met optimaliseren voor intelligentie." + +--- + +## 2. Technische Architectuur Overzicht + +### 2.1 The Three-Layer Cortex Model + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ USER INPUT β”‚ +β”‚ "Zeg Jan af en maak notitie: grieperig" β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ LAYER 1: REFLEX ARC [<20ms] β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ β€’ Local Regex Pattern Matching β”‚ β”‚ +β”‚ β”‚ β€’ High-confidence simple commands only (>= 0.7) β”‚ β”‚ +β”‚ β”‚ β€’ Examples: "agenda", "zoek jan", "notitie" β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ Decision: Confidence >= 0.7 AND no escalation triggers? β†’ EXECUTE β”‚ +β”‚ Otherwise β†’ Pass to Layer 2 β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + [Complex/Multi-intent/Low confidence/Ambiguous] + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ LAYER 2: INTENT ORCHESTRATOR (AI CORTEX) [~400ms] β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ β€’ Claude 3.5 Haiku (fast, cheap, smart) β”‚ β”‚ +β”‚ β”‚ β€’ Context injection: ActivePatient, CurrentView, Agenda, History β”‚ β”‚ +β”‚ β”‚ β€’ Multi-intent parsing: splits "X en Y" into action chain β”‚ β”‚ +β”‚ β”‚ β€’ Entity disambiguation: "hij" β†’ active patient β”‚ β”‚ +β”‚ β”‚ β€’ Clarification questions if truly ambiguous β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ Output: IntentChain { actions: [Action1, Action2, ...] } β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ EXECUTION ENGINE β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ β€’ Sequential or parallel action execution β”‚ β”‚ +β”‚ β”‚ β€’ Confirmation dialogs for destructive actions β”‚ β”‚ +β”‚ β”‚ β€’ Rollback support for failed chains β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + [Action Completed] + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ LAYER 3: NUDGE (POST-ACTION INTELLIGENCE) [async] β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ β€’ Protocol Rules Engine: medical domain knowledge β”‚ β”‚ +β”‚ β”‚ β€’ Trigger evaluation: "Does this action warrant a follow-up?" β”‚ β”‚ +β”‚ β”‚ β€’ Suggestion generation: "Wondcontrole inplannen?" β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ Output: Suggestion Toast / Follow-up Card β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### 2.2 Data Flow Diagram + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Speech │───►│ Input │───►│ Classify │───►│ Execute │───►│ Nudge β”‚ +β”‚ /Text β”‚ β”‚ Buffer β”‚ β”‚ (L1/L2) β”‚ β”‚ Chain β”‚ β”‚ Engine β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Cortex β”‚ β”‚ Artifact β”‚ β”‚ Suggestionβ”‚ + β”‚ Store │◄───│ Updates β”‚ β”‚ Toast β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## 3. Techstack Selectie + +| Component | Technologie | Argumentatie | Alternatieven | +|-----------|-------------|--------------|---------------| +| Frontend | Next.js 15 | React framework, App Router, TypeScript | SvelteKit, Remix | +| Backend | Next.js API Routes | Co-located met frontend, Server Actions | Express, FastAPI | +| Database | Supabase (PostgreSQL) | Realtime, RLS, auth included | Firebase, PlanetScale | +| AI Model | Claude 3.5 Haiku | Snel (~400ms), goedkoop, Nederlands | GPT-4o-mini, Gemini Flash | +| State Management | Zustand | Lightweight, devtools, persist | Redux, Jotai | +| Styling | TailwindCSS | Utility-first, shadcn/ui compatibel | styled-components | +| Hosting | Vercel | Zero-config Next.js, edge functions | Netlify, Railway | + +--- + +## 4. Datamodel + +### 4.1 Core Types (`lib/cortex/types.ts`) + +```typescript +// ============================================================================ +// THRESHOLDS & CONSTANTS +// ============================================================================ + +/** Minimum score om lokaal af te handelen (industry standard: 0.7) */ +export const CONFIDENCE_THRESHOLD = 0.7; + +/** Minimum verschil tussen top-2 scores om niet-ambigue te zijn */ +export const AMBIGUITY_THRESHOLD = 0.1; + +// ============================================================================ +// INTENT TYPES +// ============================================================================ + +export type CortexIntent = + | 'dagnotitie' + | 'zoeken' + | 'overdracht' + | 'agenda_query' + | 'create_appointment' + | 'cancel_appointment' + | 'reschedule_appointment' + | 'unknown'; + +export type EscalationReason = + | 'low_confidence' + | 'ambiguous' + | 'multi_intent_detected' + | 'needs_context' + | 'relative_time'; + +// ============================================================================ +// CONTEXT TYPES +// ============================================================================ + +export interface CortexContext { + activePatient: { + id: string; + name: string; + recentNotes?: string[]; + upcomingAppointments?: { + date: Date; + type: string; + }[]; + } | null; + + currentView: 'dashboard' | 'patient-detail' | 'agenda' | 'reports' | 'chat'; + shift: ShiftType; + currentTime: Date; + + agendaToday: { + time: string; + patientName: string; + patientId: string; + type: string; + }[]; + + recentIntents: { + intent: CortexIntent; + patientName?: string; + timestamp: Date; + }[]; + + userPreferences?: { + confirmationLevel: 'always' | 'destructive' | 'never'; + frequentIntents: CortexIntent[]; + }; +} + +// ============================================================================ +// CLASSIFICATION RESULT TYPES +// ============================================================================ + +export interface LocalClassificationResult { + intent: CortexIntent; + confidence: number; + + /** Op-één-na-beste match voor ambiguity detection */ + secondBestIntent?: CortexIntent; + secondBestConfidence?: number; + + matchedPattern?: string; + processingTimeMs: number; + + shouldEscalateToAI: boolean; + escalationReason?: EscalationReason; +} + +// ============================================================================ +// INTENT CHAIN (Multi-Intent Support) +// ============================================================================ + +export interface IntentChain { + id: string; + originalInput: string; + createdAt: Date; + + actions: IntentAction[]; + status: 'pending' | 'executing' | 'completed' | 'partial' | 'failed'; + + meta: { + source: 'local' | 'ai'; + processingTimeMs: number; + aiReasoning?: string; + }; +} + +export interface IntentAction { + id: string; + sequence: number; + + intent: CortexIntent; + confidence: number; + entities: ExtractedEntities; + + status: 'pending' | 'confirming' | 'executing' | 'success' | 'failed' | 'skipped'; + requiresConfirmation: boolean; + confirmationMessage?: string; + + error?: { + code: string; + message: string; + recoverable: boolean; + }; + + startedAt?: Date; + completedAt?: Date; +} + +// ============================================================================ +// ENTITY TYPES +// ============================================================================ + +export interface ExtractedEntities { + patientName?: string; + patientId?: string; + patientResolution?: 'explicit' | 'context' | 'pronoun'; + + category?: VerpleegkundigCategory; + content?: string; + severity?: 'low' | 'medium' | 'high'; + + query?: string; + + dateRange?: DateRange; + datetime?: { + date: Date; + time: string; + isRelative: boolean; + }; + appointmentType?: AppointmentType; + location?: 'praktijk' | 'online' | 'thuis'; + + identifier?: AppointmentIdentifier; + newDatetime?: { + date: Date; + time: string; + }; + + _raw?: Record; +} + +// ============================================================================ +// NUDGE TYPES +// ============================================================================ + +export interface NudgeSuggestion { + id: string; + + trigger: { + actionId: string; + intent: CortexIntent; + entities: ExtractedEntities; + }; + + suggestion: { + intent: CortexIntent; + entities: Partial; + message: string; + rationale: string; + }; + + status: 'pending' | 'accepted' | 'dismissed' | 'expired'; + priority: 'low' | 'medium' | 'high'; + expiresAt?: Date; + createdAt: Date; +} + +export interface ProtocolRule { + id: string; + name: string; + description: string; + + trigger: { + intent: CortexIntent; + conditions?: ProtocolCondition[]; + }; + + suggestion: { + intent: CortexIntent; + message: string; + prefillFrom: (source: ExtractedEntities) => Partial; + }; + + priority: 'low' | 'medium' | 'high'; + category: 'medicatie' | 'wondzorg' | 'veiligheid' | 'administratief'; + enabled: boolean; +} +``` + +### 4.2 Database Schema (Logging) + +```sql +-- Classification logs for analytics +CREATE TABLE classification_logs ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + session_id UUID NOT NULL, + + -- Input + input TEXT NOT NULL, + input_length INTEGER NOT NULL, + + -- Classification result + layer TEXT NOT NULL CHECK (layer IN ('reflex', 'cortex')), + intent TEXT NOT NULL, + confidence NUMERIC(3,2) NOT NULL, + + -- Reflex specifics + second_best_intent TEXT, + second_best_confidence NUMERIC(3,2), + matched_pattern TEXT, + + -- Escalation + escalated BOOLEAN NOT NULL DEFAULT false, + escalation_reason TEXT, + + -- Cortex specifics + tokens_used INTEGER, + ai_model TEXT, + ai_reasoning TEXT, + + -- Performance + processing_time_ms INTEGER NOT NULL, + + -- Context (geanonimiseerd) + has_active_patient BOOLEAN NOT NULL DEFAULT false, + current_view TEXT, + + -- Outcome + action_executed BOOLEAN, + user_corrected BOOLEAN, + corrected_intent TEXT, + + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +-- Index voor analytics queries +CREATE INDEX idx_classification_logs_layer ON classification_logs(layer); +CREATE INDEX idx_classification_logs_escalated ON classification_logs(escalated); +CREATE INDEX idx_classification_logs_created_at ON classification_logs(created_at); +``` + +--- + +## 5. API Ontwerp + +### 5.1 Intent Classification API + +**Endpoint:** `POST /api/cortex/classify` + +```typescript +// Request +interface ClassifyRequest { + input: string; + context: CortexContext; + options?: { + forceAI?: boolean; + skipLogging?: boolean; + }; +} + +// Response +interface ClassifyResponse { + chain: IntentChain; + handledBy: 'reflex' | 'orchestrator'; + + needsClarification?: boolean; + clarificationQuestion?: string; + clarificationOptions?: string[]; + + suggestions?: NudgeSuggestion[]; + + debug?: { + localResult?: LocalClassificationResult; + aiResult?: AIClassificationResult; + }; +} +``` + +### 5.2 Action Execution API + +**Endpoint:** `POST /api/cortex/execute` + +```typescript +interface ExecuteRequest { + chainId: string; + actionId: string; + confirmed?: boolean; +} + +interface ExecuteResponse { + success: boolean; + action: IntentAction; + suggestions?: NudgeSuggestion[]; + error?: string; +} +``` + +### 5.3 Context API + +**Endpoint:** `GET /api/cortex/context` + +Returns current context for AI classification: +- Active patient met recent notes +- Today's agenda +- Recent actions +- Current shift + +```typescript +interface ContextResponse { + context: CortexContext; + timestamp: Date; +} +``` + +### 5.4 API Response Codes + +| Code | Betekenis | Wanneer | +|------|-----------|---------| +| 200 | OK | Succesvolle classificatie/executie | +| 400 | Bad Request | Ongeldige input | +| 401 | Unauthorized | Niet ingelogd | +| 422 | Unprocessable | AI kon input niet verwerken | +| 429 | Too Many Requests | Rate limit (100 req/min) | +| 500 | Server Error | Interne fout | +| 503 | Service Unavailable | AI provider down | + +--- + +## 6. Security & Compliance + +### 6.1 Security Checklist + +- [x] **Authentication:** Supabase Auth (session-based) +- [x] **Authorization:** Row Level Security (RLS) policies +- [x] **Data Encryption:** At rest (PostgreSQL), in transit (HTTPS) +- [x] **Input Validation:** Zod schemas op alle endpoints +- [ ] **Rate Limiting:** Vercel Edge Functions (100 req/min) +- [x] **CORS:** Restrictive origins (alleen eigen domein) +- [x] **Secrets Management:** Environment variables + +### 6.2 Data Privacy (AVG/GDPR) + +- **Data minimalisatie:** Classification logs bevatten geen PII +- **Context anonimisatie:** Alleen boolean `has_active_patient`, geen namen +- **Audit trail:** Logging van alle classificaties voor debugging +- **Right to deletion:** Logs kunnen per sessie verwijderd worden + +### 6.3 NEN7510 Overwegingen + +- Toegangscontrole per rol (behandelaar, manager, admin) +- Medische dossier toegang gelogd +- AI-verwerking valt onder "verwerker" regels + +--- + +## 7. Layer 1: Reflex Arc + +### 7.1 Doel + +Razendsnelle (<20ms) afhandeling van **simpele, eenduidige commando's** met hoge confidence. + +### 7.2 Escalatie Criteria + +Layer 1 (Reflex) escaleert naar Layer 2 (Cortex) wanneer **één of meer** van de volgende triggers aanwezig is: + +#### 1. Lage Confidence +- **Trigger:** Beste match scoort < 0.7 +- **Reden:** Systeem is niet zeker genoeg +- **Voorbeeld:** "doe iets met de planning" β†’ score 0.45 + +#### 2. Ambigue Match +- **Trigger:** Verschil tussen #1 en #2 score < 0.1 +- **Reden:** Systeem twijfelt tussen twee intents +- **Voorbeeld:** "plan wondzorg" β†’ create_appointment (0.72) vs dagnotitie (0.68) + +#### 3. Multi-Intent Signaalwoorden +- **Trigger:** Input bevat conjuncties die meerdere acties suggereren +- **Detectie:** `/\b(en|daarna|ook|eerst|dan|vervolgens)\b/i` +- **Reden:** Waarschijnlijk meerdere intents in één zin +- **Voorbeeld:** "Zeg Jan af **en** maak notitie" + +#### 4. Context-Afhankelijke Woorden +- **Trigger:** Input bevat pronouns of verwijswoorden +- **Detectie:** `/\b(hij|zij|hem|haar|zijn|die|deze|dat|dezelfde)\b/i` +- **Reden:** AI moet context raadplegen om te resolven +- **Voorbeeld:** "Maak notitie voor **hem**" β†’ wie is "hem"? + +#### 5. Relatieve Tijdsaanduidingen +- **Trigger:** Input bevat relatieve tijd die berekening vereist +- **Detectie:** `/\b(morgen|overmorgen|volgende week|over \d+ dagen?|vanmiddag|vanavond)\b/i` +- **Reden:** Datum moet berekend worden op basis van huidige tijd +- **Voorbeeld:** "Plan afspraak **morgen** 14:00" + +### 7.3 Implementatie + +```typescript +// lib/cortex/reflex-classifier.ts + +import type { LocalClassificationResult, CortexIntent, EscalationReason } from './types'; +import { CONFIDENCE_THRESHOLD, AMBIGUITY_THRESHOLD } from './types'; + +// Multi-intent signaalwoorden +const MULTI_INTENT_SIGNALS = /\b(en|daarna|ook|eerst|dan|vervolgens)\b/i; + +// Context-afhankelijke woorden (pronouns, verwijzingen) +const CONTEXT_SIGNALS = /\b(hij|zij|hem|haar|zijn|die|deze|dat|dezelfde)\b/i; + +// Relatieve tijdsaanduidingen +const RELATIVE_TIME_SIGNALS = /\b(morgen|overmorgen|volgende week|over \d+ dagen?|vanmiddag|vanavond)\b/i; + +// Intent patterns met weights +const REFLEX_PATTERNS: Record> = { + dagnotitie: [ + { pattern: /^dagnotitie\b/i, weight: 1.0 }, + { pattern: /^notitie\s+\w+\s+(medicatie|adl|gedrag|incident|observatie)\b/i, weight: 0.95 }, + { pattern: /^notitie\s+\w+/i, weight: 0.85 }, + { pattern: /^(medicatie|adl|gedrag|incident|observatie)\s+\w+/i, weight: 0.8 }, + ], + + zoeken: [ + { pattern: /^zoek\s+\w+$/i, weight: 1.0 }, + { pattern: /^vind\s+\w+$/i, weight: 1.0 }, + { pattern: /^wie\s+is\s+\w+/i, weight: 0.95 }, + { pattern: /^dossier\s+\w+$/i, weight: 0.85 }, + ], + + agenda_query: [ + { pattern: /^agenda\s*(vandaag)?$/i, weight: 1.0 }, + { pattern: /^afspraken\s*(vandaag|deze week)?$/i, weight: 0.95 }, + { pattern: /^wat\s+staat\s+er\s+vandaag/i, weight: 0.85 }, + ], + + overdracht: [ + { pattern: /^overdracht$/i, weight: 1.0 }, + { pattern: /^dienst\s+afronden$/i, weight: 0.95 }, + ], + + create_appointment: [ + { pattern: /^maak\s+afspraak\b/i, weight: 0.8 }, + { pattern: /^plan\s+(intake|afspraak)\b/i, weight: 0.8 }, + ], + + cancel_appointment: [ + { pattern: /^annuleer\s+afspraak\b/i, weight: 0.85 }, + { pattern: /^zeg\s+\w+\s+af\b/i, weight: 0.8 }, + ], + + reschedule_appointment: [ + { pattern: /^verzet\s+afspraak\b/i, weight: 0.8 }, + { pattern: /^verplaats\s+\w+\s+naar\b/i, weight: 0.75 }, + ], + + unknown: [], +}; + +/** + * Detecteer escalatie triggers in de input + */ +function detectEscalationTriggers(input: string): { + shouldEscalate: boolean; + reasons: EscalationReason[]; +} { + const reasons: EscalationReason[] = []; + + if (MULTI_INTENT_SIGNALS.test(input)) { + reasons.push('multi_intent_detected'); + } + + if (CONTEXT_SIGNALS.test(input)) { + reasons.push('needs_context'); + } + + if (RELATIVE_TIME_SIGNALS.test(input)) { + reasons.push('relative_time'); + } + + return { + shouldEscalate: reasons.length > 0, + reasons + }; +} + +/** + * Classify input using local patterns + */ +export function classifyWithReflex(input: string): LocalClassificationResult { + const startTime = performance.now(); + const trimmedInput = input.trim(); + + // STAP 1: Check escalatie triggers + const triggers = detectEscalationTriggers(trimmedInput); + + if (triggers.shouldEscalate) { + return { + intent: 'unknown', + confidence: 0, + processingTimeMs: performance.now() - startTime, + shouldEscalateToAI: true, + escalationReason: triggers.reasons[0], + }; + } + + // STAP 2: Pattern matching - verzamel alle matches + const matches: Array<{ intent: CortexIntent; confidence: number; pattern: string }> = []; + + for (const [intent, patterns] of Object.entries(REFLEX_PATTERNS)) { + for (const { pattern, weight } of patterns) { + if (pattern.test(trimmedInput)) { + matches.push({ + intent: intent as CortexIntent, + confidence: weight, + pattern: pattern.source, + }); + } + } + } + + // Sorteer op confidence (hoogste eerst) + matches.sort((a, b) => b.confidence - a.confidence); + + const processingTimeMs = performance.now() - startTime; + const bestMatch = matches[0]; + const secondBestMatch = matches[1]; + + // STAP 3: Geen match gevonden + if (!bestMatch) { + return { + intent: 'unknown', + confidence: 0, + processingTimeMs, + shouldEscalateToAI: true, + escalationReason: 'low_confidence', + }; + } + + // STAP 4: Confidence check + if (bestMatch.confidence < CONFIDENCE_THRESHOLD) { + return { + intent: bestMatch.intent, + confidence: bestMatch.confidence, + matchedPattern: bestMatch.pattern, + processingTimeMs, + shouldEscalateToAI: true, + escalationReason: 'low_confidence', + }; + } + + // STAP 5: Ambiguity check + if (secondBestMatch && + bestMatch.confidence - secondBestMatch.confidence < AMBIGUITY_THRESHOLD) { + return { + intent: bestMatch.intent, + confidence: bestMatch.confidence, + secondBestIntent: secondBestMatch.intent, + secondBestConfidence: secondBestMatch.confidence, + matchedPattern: bestMatch.pattern, + processingTimeMs, + shouldEscalateToAI: true, + escalationReason: 'ambiguous', + }; + } + + // STAP 6: High confidence, unambiguous match - handle locally + return { + intent: bestMatch.intent, + confidence: bestMatch.confidence, + matchedPattern: bestMatch.pattern, + processingTimeMs, + shouldEscalateToAI: false, + }; +} +``` + +--- + +## 8. Layer 2: Intent Orchestrator + +### 8.1 Doel + +AI-gedreven analyse voor: +- **Complexe zinnen** met lage confidence +- **Multi-intents** ("X en Y") +- **Context-afhankelijke** verwijzingen ("hij", "die afspraak") +- **Disambiguation** bij twijfel + +### 8.2 AI Model Selectie + +| Criterium | Claude 3.5 Haiku | GPT-4o-mini | Gemini Flash | +|-----------|------------------|-------------|--------------| +| Latency | ~400ms | ~500ms | ~300ms | +| Cost/1K tokens | $0.25 | $0.15 | $0.075 | +| Dutch quality | Excellent | Good | Good | +| JSON reliability | Excellent | Good | Medium | + +**Keuze:** Claude 3.5 Haiku vanwege superieure Nederlandse taalverwerking en JSON output betrouwbaarheid. + +> **Model Versie Note:** We gebruiken `claude-3-5-haiku-20241022`. Check periodiek de [Anthropic model docs](https://docs.anthropic.com/en/docs/about-claude/models) voor nieuwere versies. + +### 8.3 System Prompt + +```typescript +const ORCHESTRATOR_SYSTEM_PROMPT = `Je bent de Intent Orchestrator voor Cortex, een Nederlands EPD systeem. + +## Je Taak +Analyseer de gebruikersinput en extraheer ALLE intenties, ook als er meerdere zijn. + +## Context die je krijgt +- Actieve patiΓ«nt: wie de gebruiker momenteel bekijkt +- Agenda vandaag: afspraken voor vandaag +- Recente acties: wat de gebruiker net deed +- Huidige weergave: waar in de app de gebruiker is + +## Intent Types +1. **dagnotitie** - Notitie/rapportage maken +2. **zoeken** - PatiΓ«nt zoeken +3. **overdracht** - Dienst overdracht +4. **agenda_query** - Agenda bekijken +5. **create_appointment** - Afspraak maken +6. **cancel_appointment** - Afspraak annuleren +7. **reschedule_appointment** - Afspraak verzetten + +## Multi-Intent Detectie +Let op woorden als: "en", "daarna", "ook", "eerst", "dan", "vervolgens" + +## Pronoun Resolution +Gebruik de context om "hij/zij/die" op te lossen: +- Als er een actieve patiΓ«nt is, verwijst "hij/zij" daar waarschijnlijk naar +- "Die afspraak" verwijst naar de meest recente genoemde afspraak + +## Output Format +Antwoord ALLEEN met valid JSON (geen markdown): +{ + "actions": [...], + "reasoning": "...", + "needsClarification": false +}`; +``` + +### 8.4 Implementatie + +```typescript +// lib/cortex/orchestrator.ts + +import { classifyWithReflex } from './reflex-classifier'; + +/** + * Classify with AI Orchestrator, with graceful fallback to Reflex on failure + */ +export async function classifyWithOrchestrator( + input: string, + context: CortexContext +): Promise { + const startTime = performance.now(); + + try { + const anthropic = new Anthropic({ + apiKey: process.env.ANTHROPIC_API_KEY, + }); + + const contextPrompt = formatContextForPrompt(context); + + const response = await anthropic.messages.create({ + model: 'claude-3-5-haiku-20241022', + max_tokens: 512, + temperature: 0, + system: ORCHESTRATOR_SYSTEM_PROMPT, + messages: [ + { + role: 'user', + content: `## Context +${contextPrompt} + +## Input +"${input}" + +Analyseer en extraheer alle intenties.`, + }, + ], + }); + + const processingTimeMs = performance.now() - startTime; + const rawText = response.content[0].type === 'text' ? response.content[0].text : ''; + const parsed = parseAIResponse(rawText); + + // Build IntentChain + const chain: IntentChain = { + id: crypto.randomUUID(), + originalInput: input, + createdAt: new Date(), + actions: parsed.actions.map((action, index) => ({ + id: crypto.randomUUID(), + sequence: index + 1, + intent: action.intent, + confidence: action.confidence, + entities: action.entities, + status: 'pending', + requiresConfirmation: action.requiresConfirmation ?? false, + confirmationMessage: action.confirmationMessage, + })), + status: 'pending', + meta: { + source: 'ai', + processingTimeMs, + aiReasoning: parsed.reasoning, + }, + }; + + return { + chain, + model: 'claude-3-5-haiku-20241022', + tokensUsed: response.usage.input_tokens + response.usage.output_tokens, + processingTimeMs, + needsClarification: parsed.needsClarification ?? false, + clarificationQuestion: parsed.clarificationQuestion, + clarificationOptions: parsed.clarificationOptions, + }; + + } catch (error) { + // Graceful degradation: fallback to Reflex-only + console.error('[Cortex] AI Orchestrator failed, falling back to Reflex:', error); + + const reflexResult = classifyWithReflex(input); + const processingTimeMs = performance.now() - startTime; + + // Build minimal chain from Reflex result + const fallbackChain: IntentChain = { + id: crypto.randomUUID(), + originalInput: input, + createdAt: new Date(), + actions: reflexResult.intent !== 'unknown' ? [{ + id: crypto.randomUUID(), + sequence: 1, + intent: reflexResult.intent, + confidence: reflexResult.confidence, + entities: {}, + status: 'pending', + requiresConfirmation: false, + }] : [], + status: reflexResult.intent !== 'unknown' ? 'pending' : 'failed', + meta: { + source: 'local', // Indicate fallback + processingTimeMs, + aiReasoning: 'AI unavailable - fallback to local classification', + }, + }; + + return { + chain: fallbackChain, + model: 'fallback-reflex', + tokensUsed: 0, + processingTimeMs, + needsClarification: false, + }; + } +} +``` + +--- + +## 9. Layer 3: Nudge Engine + +### 9.1 Doel + +Proactieve suggesties na succesvolle acties op basis van medische protocollen. + +### 9.2 Protocol Rules (MVP) + +```typescript +// lib/cortex/nudge.ts + +export const PROTOCOL_RULES: ProtocolRule[] = [ + // Wondzorg Protocol + { + id: 'wondzorg-controle', + name: 'Wondcontrole na verzorging', + description: 'Bij wondzorg hoort standaard een vervolgcontrole', + trigger: { + intent: 'dagnotitie', + conditions: [ + { field: 'category', operator: 'equals', value: 'adl' }, + { field: 'content', operator: 'contains', value: 'wond' }, + ], + }, + suggestion: { + intent: 'create_appointment', + message: 'Wondcontrole inplannen over 3 dagen?', + prefillFrom: (source) => ({ + patientName: source.patientName, + patientId: source.patientId, + appointmentType: 'follow-up', + content: 'Wondcontrole', + }), + }, + priority: 'medium', + category: 'wondzorg', + enabled: true, + }, + + // Medicatie Protocol + { + id: 'medicatie-evaluatie', + name: 'Evaluatie na medicatiestart', + description: 'Nieuwe medicatie vereist evaluatie na 2 weken', + trigger: { + intent: 'dagnotitie', + conditions: [ + { field: 'category', operator: 'equals', value: 'medicatie' }, + { field: 'content', operator: 'matches', value: /start|gestart|nieuw/i }, + ], + }, + suggestion: { + intent: 'create_appointment', + message: 'Medicatie-evaluatie inplannen over 2 weken?', + prefillFrom: (source) => ({ + patientName: source.patientName, + patientId: source.patientId, + appointmentType: 'follow-up', + content: 'Medicatie-evaluatie', + }), + }, + priority: 'medium', + category: 'medicatie', + enabled: true, + }, + + // Crisis Protocol + { + id: 'crisis-signalering', + name: 'SuΓ―cidaliteit signalering', + description: 'Bij signalen van suΓ―cidaliteit crisisprotocol checken', + trigger: { + intent: 'dagnotitie', + conditions: [ + { + field: 'content', + operator: 'matches', + // Specifiekere regex om false positives te voorkomen (bijv. "doodmoe") + // Matcht: suΓ―cide, zelfmoord, doodswens, wil dood, uitzichtloos, geen zin meer + // Matcht NIET: doodmoe, doodsaai, etc. + value: /suΓ―cid|zelfmoord|doodswens|\bwil\s+dood\b|levenseinde|uitzichtloos|geen\s+zin\s+(meer|in)/i, + }, + ], + }, + suggestion: { + intent: 'unknown', // Special action: show crisis protocol + message: 'Crisisprotocol raadplegen? Signaleringsplan updaten?', + prefillFrom: (source) => ({ + patientName: source.patientName, + patientId: source.patientId, + }), + }, + priority: 'high', + category: 'veiligheid', + enabled: true, + }, +]; + +/** + * Note: Protocol rules zijn hardcoded voor MVP. + * Post-MVP: overweeg een admin UI of database-driven rules. + * + * Regex validatie tips: + * - Test altijd met edge cases ("doodmoe", "doodsaai") + * - Gebruik word boundaries (\b) waar mogelijk + * - Overweeg NLP/AI voor complexere matching in productie + */ +``` + +--- + +## 10. Logging & Metrics + +### 10.1 Classification Log Structure + +Elke classificatie wordt gelogd voor analyse en verbetering: + +```typescript +// lib/cortex/logger.ts + +interface ClassificationLog { + // Identificatie + id: string; + timestamp: Date; + sessionId: string; + + // Input + input: string; + inputLength: number; + + // Classificatie resultaat + layer: 'reflex' | 'cortex'; + intent: CortexIntent; + confidence: number; + + // Bij Reflex + secondBestIntent?: CortexIntent; + secondBestConfidence?: number; + matchedPattern?: string; + + // Escalatie info + escalated: boolean; + escalationReason?: EscalationReason; + + // Bij Cortex (AI) + tokensUsed?: number; + aiModel?: string; + aiReasoning?: string; + + // Performance + processingTimeMs: number; + + // Context (geanonimiseerd) + hasActivePatient: boolean; + currentView: string; + + // Outcome (later in te vullen) + actionExecuted?: boolean; + userCorrected?: boolean; + correctedIntent?: CortexIntent; +} +``` + +### 10.2 Metrics om te monitoren + +| Metric | Doel | Actie bij afwijking | +|--------|------|---------------------| +| **Reflex hit rate** | >70% lokaal afgehandeld | Threshold tunen of regex uitbreiden | +| **Escalation reasons** | Verdeling monitoren | Veel 'ambiguous' β†’ patterns verbeteren | +| **AI latency p95** | <800ms | Model of prompt optimaliseren | +| **User corrections** | <5% | Intent definities of training verbeteren | + +### 10.3 Privacy: Input Sanitization + +> **Let op:** Raw input kan PII bevatten (bijv. "notitie voor Jan Jansen medicatie"). +> We sanitizen input voordat we loggen naar productie. + +```typescript +// lib/cortex/sanitize.ts + +/** + * Verwijdert potentiΓ«le PII uit input voor logging + * - Namen (2+ woorden met hoofdletters) + * - BSN-achtige nummers (9 cijfers) + * - Telefoonnummers + */ +export function sanitizeForLogging(input: string): string { + return input + // Vervang potentiΓ«le namen (Hoofdletter + woord patronen) + .replace(/\b[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+\b/g, '[NAAM]') + // Vervang BSN-achtige nummers + .replace(/\b\d{9}\b/g, '[BSN]') + // Vervang telefoonnummers + .replace(/\b(?:06|0\d{2})[-\s]?\d{7,8}\b/g, '[TELEFOON]') + // Vervang email adressen + .replace(/\b[\w.-]+@[\w.-]+\.\w+\b/g, '[EMAIL]'); +} +``` + +### 10.4 Log implementatie + +```typescript +// lib/cortex/logger.ts + +import { ClassificationLog } from './types'; +import { sanitizeForLogging } from './sanitize'; + +export function logClassification(log: ClassificationLog): void { + // Development: console (raw input OK voor debugging) + if (process.env.NODE_ENV === 'development') { + console.log('[Cortex Classification]', { + input: log.input.substring(0, 50), + layer: log.layer, + intent: log.intent, + confidence: log.confidence, + escalated: log.escalated, + escalationReason: log.escalationReason, + timeMs: log.processingTimeMs, + }); + } + + // Production: sanitize input voordat we loggen + if (process.env.NODE_ENV === 'production') { + const sanitizedLog = { + ...log, + input: sanitizeForLogging(log.input), + }; + + // Fire-and-forget naar Supabase + fetch('/api/cortex/log', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(sanitizedLog), + }).catch(console.error); + } +} +``` + +--- + +## 11. Frontend Components + +### 11.1 Component Hierarchy + +``` +CommandCenter (v3.0) +β”œβ”€β”€ ContextBar +β”œβ”€β”€ ChatPanel +β”‚ β”œβ”€β”€ ChatMessages +β”‚ β”‚ β”œβ”€β”€ UserMessage +β”‚ β”‚ β”œβ”€β”€ AssistantMessage +β”‚ β”‚ β”‚ └── ActionChainCard (NEW) +β”‚ β”‚ β”‚ β”œβ”€β”€ ActionItem +β”‚ β”‚ β”‚ β”œβ”€β”€ ActionItem +β”‚ β”‚ β”‚ └── ConfirmationDialog +β”‚ β”‚ └── ClarificationCard (NEW) +β”‚ └── ChatInput +β”œβ”€β”€ ArtifactArea +β”‚ β”œβ”€β”€ ArtifactTabs +β”‚ └── ArtifactContainer +└── NudgeToast (NEW - Layer 3) +``` + +### 11.2 ActionChainCard Component + +```tsx +// components/cortex/chat/action-chain-card.tsx + +interface ActionChainCardProps { + chain: IntentChain; + onConfirm: (actionId: string) => void; + onSkip: (actionId: string) => void; + onRetry: (actionId: string) => void; +} + +// Toont meerdere acties in één card met: +// - Sequence numbers (1, 2, 3...) +// - Status icons (pending, executing, success, failed) +// - Confidence badges +// - Confirmation buttons voor destructieve acties +// - Collapsible AI reasoning +``` + +### 11.3 NudgeToast Component + +```tsx +// components/cortex/command-center/nudge-toast.tsx + +interface NudgeToastProps { + suggestion: NudgeSuggestion; + onAccept: (suggestionId: string) => void; + onDismiss: (suggestionId: string) => void; +} + +// Toont proactieve suggestie met: +// - Progress bar countdown (5 minuten) +// - Priority-based styling (red/amber/blue) +// - Accept/Dismiss buttons +// - Rationale tekst +``` + +--- + +## 12. State Management + +### 12.1 Cortex Store Extensions + +```typescript +// stores/cortex-store.ts (V2 additions) + +interface CortexStoreV2 extends CortexStore { + // Context + context: CortexContext; + setContext: (context: Partial) => void; + + // Intent Chains + activeChain: IntentChain | null; + chainHistory: IntentChain[]; + + startChain: (chain: IntentChain) => void; + updateActionStatus: (chainId: string, actionId: string, status: IntentAction['status']) => void; + completeChain: (chainId: string) => void; + + // Nudge + suggestions: NudgeSuggestion[]; + + addSuggestion: (suggestion: NudgeSuggestion) => void; + acceptSuggestion: (suggestionId: string) => void; + dismissSuggestion: (suggestionId: string) => void; + + // Clarification + pendingClarification: { + question: string; + options: string[]; + originalInput: string; + } | null; + + setClarification: (clarification: ...) => void; + answerClarification: (answer: string) => void; +} +``` + +--- + +## 13. Performance & Scalability + +### 13.1 Performance Targets + +| Metric | Target | Gemeten | +|--------|--------|---------| +| Reflex classificatie | <20ms | ~5ms | +| AI classificatie | <800ms | ~400ms | +| Page load (FCP) | <2s | - | +| API response (excl. AI) | <500ms | - | + +### 13.2 Caching Strategie + +- **Context API:** 30 seconden cache (agenda wijzigt niet snel) +- **AI responses:** Geen cache (context-afhankelijk) +- **Protocol rules:** In-memory (statisch) + +### 13.3 Scalability + +- **Frontend:** Vercel Edge Network (CDN) +- **Backend:** Serverless functions (auto-scaling) +- **Database:** Supabase (vertical scaling) +- **AI:** Queue systeem voor batch processing (toekomst) + +--- + +## 14. Deployment & CI/CD + +### 14.1 Omgevingen + +| Omgeving | URL | Branch | Doel | +|----------|-----|--------|------| +| Development | localhost:3000 | - | Lokaal ontwikkelen | +| Preview | *.vercel.app | PR branches | Review builds | +| Production | app.example.com | main | Live applicatie | + +### 14.2 Feature Flags + +```typescript +// lib/config/feature-flags.ts + +export const FEATURE_FLAGS = { + CORTEX_V2_ENABLED: process.env.NEXT_PUBLIC_CORTEX_V2 === 'true', + CORTEX_MULTI_INTENT: process.env.NEXT_PUBLIC_CORTEX_MULTI_INTENT === 'true', + CORTEX_NUDGE: process.env.NEXT_PUBLIC_CORTEX_NUDGE === 'true', + CORTEX_LOGGING: process.env.NEXT_PUBLIC_CORTEX_LOGGING === 'true', +}; +``` + +### 14.3 Deployment Checklist + +- [ ] Environment variables set (Vercel dashboard) +- [ ] Feature flags configured +- [ ] Database migrations run +- [ ] Smoke tests passed +- [ ] Monitoring configured + +--- + +## 15. Testing Strategy + +### 15.1 Test CategorieΓ«n + +| Type | Scope | Tools | +|------|-------|-------| +| Unit | Reflex classifier, entity extractor | Vitest | +| Integration | API endpoints, AI responses | Vitest + MSW | +| E2E | Complete flows | Playwright | + +### 15.2 Test Zinnen Dataset + +```json +{ + "single_intent": [ + { "input": "notitie jan medicatie", "expected": ["dagnotitie"] }, + { "input": "zoek marie", "expected": ["zoeken"] }, + { "input": "agenda vandaag", "expected": ["agenda_query"] } + ], + "multi_intent": [ + { + "input": "Zeg Jan af en maak notitie dat hij griep heeft", + "expected": ["cancel_appointment", "dagnotitie"] + } + ], + "context_dependent": [ + { + "input": "Maak notitie voor hem", + "context": { "activePatient": { "name": "Piet" } }, + "expected": ["dagnotitie"], + "entities": [{ "patientResolution": "pronoun" }] + } + ], + "ambiguous": [ + { + "input": "Plan wondzorg", + "shouldEscalate": true + } + ] +} +``` + +--- + +## 16. Risico's & Technische Mitigatie + +| Risico | Impact | Kans | Mitigatie | +|--------|--------|------|-----------| +| AI API down | Hoog | Laag | Graceful degradation naar Reflex-only | +| Hallucinated intents | Middel | Middel | Strikte JSON schema, fallback to unknown | +| Performance degradatie | Middel | Laag | Monitoring, caching, threshold tuning | +| Privacy breach (logs) | Hoog | Laag | Anonimisatie, geen PII in logs | +| Cost overrun (AI) | Middel | Middel | Token limits, usage monitoring | + +--- + +## 17. Implementatie Roadmap + +### Fase 1: Foundation (3-4 dagen) + +| Task | Effort | Status | +|------|--------|--------| +| CortexContext types | S | Pending | +| GET /api/cortex/context endpoint | M | Pending | +| Reflex complexity detection | S | Pending | +| Feature flags setup | S | Pending | + +**Deliverable:** Context beschikbaar, backward compatible + +### Fase 2: Multi-Intent (4-5 dagen) + +| Task | Effort | Status | +|------|--------|--------| +| IntentChain types | M | Pending | +| Orchestrator AI prompt | M | Pending | +| ActionChainCard component | L | Pending | +| Store chain state | M | Pending | + +**Deliverable:** "Zeg Jan af en maak notitie" werkt + +### Fase 3: Nudge MVP (2-3 dagen) + +| Task | Effort | Status | +|------|--------|--------| +| Protocol rules (wondzorg) | S | Pending | +| evaluateNudge functie | M | Pending | +| NudgeToast component | M | Pending | + +**Deliverable:** Proactieve suggestie demo + +### Fase 4: Polish (2-3 dagen) + +| Task | Effort | Status | +|------|--------|--------| +| ClarificationCard | S | Pending | +| Error handling | M | Pending | +| Logging infrastructure | M | Pending | + +**Deliverable:** Demo-ready prototype + +**Totaal: 11-15 werkdagen** + +--- + +## 18. Bijlagen & Referenties + +### A. Gerelateerde Documenten + +| Document | Locatie | +|----------|---------| +| FO Intent System V2 | `docs/intent/fo-cortex-intent-system-v2.md` | +| Architectuur V2 | `docs/intent/architecture-cortex-v2.md` | +| MVP User Stories | `docs/intent/mvp-userstories-intent-system.md` | +| Haalbaarheidsanalyse | `docs/intent/haalbaarheidsanalyse-cortex-v2.md` | + +### B. Tech Documentatie + +- Next.js: https://nextjs.org/docs +- Supabase: https://supabase.com/docs +- Anthropic: https://docs.anthropic.com +- Zustand: https://docs.pmnd.rs/zustand + +### C. Versie Historie + +| Versie | Datum | Auteur | Wijzigingen | +|--------|-------|--------|-------------| +| 1.0 | 30-12-2025 | Colin Lit | Initieel document met sanity check aanbevelingen verwerkt | diff --git a/docs/intent/ux-simulation-intent-next-level.md b/docs/intent/ux-simulation-intent-next-level.md index 16fd315..1ecccde 100644 --- a/docs/intent/ux-simulation-intent-next-level.md +++ b/docs/intent/ux-simulation-intent-next-level.md @@ -1,3 +1,5 @@ +> **Note:** "Swift" is hernoemd naar "Cortex". Dit document bevat historische referenties naar de oude naam. + # UX Simulatie: Intent System "Next Level" **Betreft:** Brainstormsessie voor de volgende fase van de Swift Intent Architectuur.