diff --git a/docs/MVP.md b/docs/MVP.md
index 0decc5b..f863ee9 100644
--- a/docs/MVP.md
+++ b/docs/MVP.md
@@ -34,7 +34,9 @@ Demomanus för visning: [DEMO.md](DEMO.md). Knappen **Skapa demoärende** på st
| Dashboard | ✅ Enligt direktivet: räknare och filter för Alla/Pågående/Klara plus Starta nytt ärende. |
| Ärendestart via arbetsorder | ✅ Primärvägen när ett ärende startas: fota arbetsorderns framsida — orkesterns dokumenttolkning (Claude Sonnet 5, vision) läser kund-, fordons- och verkstadsuppgifter oavsett layout och sätter konfidens per fält. 🟢 ≥95 % godkänns automatiskt, 🟡 80–95 % markeras för genomläsning, 🔴 <80 % kräver aktiv bekräftelse — teknikern granskar bara osäkra fält. Visuell granskning med dokumentet bredvid fälten (klick markerar ungefärlig position), sedan skapas hela ärendet med ett tryck. Tolkningen loggas som organisationsintern händelse (`arbetsorder_skannad`) och delas aldrig i kund-/partnervyer. Manuell inmatning finns kvar som andrahandsväg; i lokalt läge visas en tydligt märkt demo-tolkning. Inloggade användare tillfrågas aldrig om namn — kontot vet redan. |
| Inställningar | ✅ Systemadministratören väljer vilka objekttyper och identifieringsmetoder som visas när ett ärende startas (`/felsokning/installningar`). På plattformen gäller valet hela organisationen (sparas på organisationen, endast admin får ändra — verifierat i integrationstestet); i lokalt läge gäller valet enheten. Okända värden filtreras och tomma listor faller tillbaka till standard. |
-| Evidensmotor (ECM) | ✅ Versionshanterat regelbibliotek ([moduler/evidensmotor.md](moduler/evidensmotor.md), `src/felsokning/ecm.ts`, ECM v1.0): evidensnivåer E0–E6 härledda ur loggen, fullbordansregeln *evidens eller dokumenterat undantag med obligatorisk orsak* ("Underlag kan inte tas fram" i guiden, flaggas ⚠ i brief/rapport), och **kvalitetsgrind före slutrapport** — utskrift spärrad tills objektidentifiering, kontroller, fotokrav och evidensnivå är gröna. Regeln "skriv aldrig OK/kontrollerad/inga fel utan evidens — skriv Evidens saknas" är kodad i orkesterns grundprompt. |
+| Evidensmotor (ECM) | ✅ Eget subsystem med sex motorer ([moduler/evidensmotor.md](moduler/evidensmotor.md), `src/felsokning/ecm.ts`, **ECM v2.0**): Evidence (evidensposter med nivå E0–E6, tekniker och innehållshash), Rule (dokumentationskrav + undantagsregeln med obligatorisk orsak), Compliance (ärendetypen — garanti/försäkring/reklamation m.fl. — styr extra krav), Validation ("Evidens saknas" i stället för antaganden, kodat i orkesterns grundprompt), Completion (kvalitetsgrind som spärrar slutrapporten) och Traceability (spårbarhetspaket med regelversion + hash i varje export). |
+| Pre-diagnostik | ✅ Ingen felsökning förrän grundkontrollerna är gjorda eller motiverade: fordonshistorik (Ja med ev. orsakskedja / Nej med obligatorisk orsak → kvalitetsvarning), **ingående mätarställning** (foto av instrumentpanelen, bildtolkningen föreslår värdet), kundens felbeskrivning verifierad och tidiga observationer hanterade. Metodiken låses upp först därefter. **Utgående mätarställning** fotograferas inför avslut och blir obligatorisk i grinden när ärendet stängs. |
+| Ärendeidentitet | ✅ Fordonsobjektet som röd tråd: identiteten (AO-nummer, claim-/garantinummer, skadenummer, regnr, VIN, miltal, kund) registreras en gång — normalt via arbetsorderskanningen — och återanvänds i identitetsraden i arbetsytan (med ärendetypsval), låst panel överst i Live Share, slutrapportens första sida (Ärendeinformation + Fordonsinformation) och exporten. |
| Instrumentavläsning (visual-first) | ✅ Kameran som universellt gränssnitt: `📷 Instrument` i Dokumentera-panelen fotograferar multimetrar, diagnosskärmar, batteritestare m.m. — bildtolkningen identifierar instrumenttyp och extraherar värden/enheter/felkoder med konfidens per värde; teknikern bekräftar innan något loggas. Originalbilden loggas alltid tillsammans med de strukturerade mätvärdena — strukturerad data ersätter aldrig originalevidensen. Ingen integration mot diagnossystem krävs. |
| Utskrift | ✅ Kundrapport och Live Share-vy skrivs ut svart på vitt; interaktiva element döljs automatiskt. Utskriften går genom ECM-kvalitetsgrinden. |
| Öppet API | ✅ Plattforms-API:t är dokumenterat med OpenAPI 3.0 (`services/plattform/openapi.yaml`) — auth, användare, ärenden/händelser (append-only), översikt, publik delning och AI-orkestern, med scheman för alla händelsetyper. Specen valideras maskinellt, paritetstestas mot serverns rutter och serveras live på `GET /api/openapi.yaml`. |
diff --git a/docs/moduler/evidensmotor.md b/docs/moduler/evidensmotor.md
index 8e7f64e..e30920c 100644
--- a/docs/moduler/evidensmotor.md
+++ b/docs/moduler/evidensmotor.md
@@ -1,22 +1,22 @@
# Modul: Evidensmotorn (ECM — Evidence & Compliance Matrix)
-**Version: ECM v1.0** · Regelbiblioteket är versionshanterat och skilt från
-applikationslogiken (`src/felsokning/ecm.ts`). Vyerna anropar bara motorns
-rena funktioner — regler kan uppdateras utan att applikationen byggs om.
+**Version: ECM v2.0** · ECM är ett eget subsystem — inte en tabell i
+databasen — och motorn som styr hela plattformen: den avgör vilken
+dokumentation som krävs, när dokumentation saknas, vilken bevisnivå som
+uppnåtts, vilka regler som gäller och om ett ärende kan avslutas.
+**Systemet kan aldrig skriva en slutsats som ECM inte har godkänt.**
-## Grundprincip
+Regelbiblioteket är versionshanterat och skilt från applikationslogiken
+(`src/felsokning/ecm.ts`); vyerna anropar bara motorns rena funktioner.
-**Inget underlag = ingen slutsats.**
+## De sex motorerna
-Systemet får aldrig anta att en kontroll är utförd eller påstå att
-dokumentation finns om den inte faktiskt är insamlad. Varje påstående i
-diagnos, brief och slutrapport ska kunna härledas till minst en
-evidenspost i händelseloggen. Systemet skriver aldrig "OK",
-"kontrollerad", "inga fel" eller "åtgärdad" utan evidens — i stället:
-**"Evidens saknas."** Regeln är kodad i orkesterns grundprompt och kan
-inte kringgås från klienten.
-
-## Evidensnivåer
+### 1. Evidence Engine
+Katalogiserar all bevisning ur händelseloggen. Varje evidenspost får
+id, tidpunkt, tekniker, kategori, evidensnivå, sammanfattning och
+**innehållshash** — samma post ger alltid samma hash, och den
+append-only-låsta loggen (databastriggers) gör varje ändringsförsök
+omöjligt.
| Nivå | Typ | Bevisvärde |
| --- | --- | --- |
@@ -25,70 +25,98 @@ inte kringgås från klienten.
| E2 | Foto | Medel |
| E3 | Video | Högt |
| E4 | Mätvärde | Högt |
-| E5 | Diagnosdata/dokument (t.ex. skannad arbetsorder) | Mycket högt |
+| E5 | Diagnosdata/dokument | Mycket högt |
| E6 | Flera oberoende källor | Högsta |
-Ärendets nivå härleds ur loggens faktiska innehåll (`evidensNiva`) och
-visas i kvalitetsgrinden.
+### 2. Rule Engine
+Dokumentationskraven: metodikens `krav`-fält per kontroll plus de
+automatiska reglerna — *kan det fotograferas → begär foto; låter det →
+video med ljud; rör det sig → video; mäts det → mätvärde; visar en
+display informationen → fota displayen; finns ett dokument → fota
+dokumentet.* Undantagsorsakerna ("Underlag kan inte tas fram") ligger
+här.
-## Fullbordansregler
+### 3. Compliance Engine
+Ärendetypen styr vilka regler som gäller utöver metodiken. Ärendetyp
+väljs i identitetsraden och loggas (`arendetyp_satt`):
-En kontrollpunkt kan bara slutföras när något av följande är sant:
+| Ärendetyp | Extra krav (v2.0) |
+| --- | --- |
+| Garanti | Miltal dokumenterat · servicehistorik kontrollerad · claim-/garantinummer |
+| Goodwill | Miltal · servicehistorik |
+| Försäkring | Skadenummer · bildbevis |
+| Reklamation | Historik och tidigare försök kontrollerade |
+| Begagnatgaranti | Miltal |
-1. **Krävd evidens är insamlad** — foto för det synliga, mätvärde för det
- som mäts, kommentar där inget bättre är möjligt (metodikens
- `krav`-fält per kontroll).
-2. **Teknikern dokumenterar ett undantag**: *"Underlag kan inte tas
- fram"* med **obligatorisk orsak** (komponenten oåtkomlig, fordonet kan
- inte lyftas säkert, kunden avböjde demontering, dålig sikt, utrustning
- saknas — eller fri text). Undantaget loggas i händelseloggen och
- flaggas ⚠ i brief, överlämning och rapport — det redovisas aldrig som
- "utförd".
+Här ansluter det framtida **ECM Knowledge Library**: serverdistribuerade,
+versionerade regelpaket (garantivillkor per tillverkare, försäkringsbolagens
+krav, reklamationslagstiftning, OEM-kontrollpunkter) som laddas dynamiskt
+utan appändring.
-## Kvalitetsgrind före slutrapport
+### 4. Validation Engine
+Inga påståenden utan underlag, i tre lager: (a) orkesterns grundprompt —
+aldrig "OK/kontrollerad/inga fel/åtgärdad" utan evidens, i stället
+"Evidens saknas" plus begäran om rätt underlag; (b) projektionerna —
+hypoteser kan aldrig bli konstaterade fel; (c) kvalitetsgrinden nedan.
-Slutrapporten kan inte genereras förrän grinden är godkänd
-(`kvalitetsgrind`/`grindGodkand`):
+### 5. Completion Engine
+Kvalitetsgrinden före slutrapport/avslut — utskriften är spärrad tills
+alla obligatoriska rader är gröna:
| Kontroll | Krav |
| --- | --- |
| Fordons-/objektidentifiering verifierad | Obligatorisk |
| Arbetsorder inläst | Rekommenderas |
+| Fordonshistorik kontrollerad eller motiverad | Obligatorisk |
+| Ingående mätarställning dokumenterad | Obligatorisk |
+| Kundens felbeskrivning verifierad | Rekommenderas |
+| Utgående mätarställning | Obligatorisk vid avslut |
| Metodikens kontroller: evidens eller dokumenterat undantag | Obligatorisk |
-| Foton finns för fotokrävande kontroller | Obligatorisk |
-| Hypoteser redovisas som ej verifierade | Informativ (alltid sant per konstruktion) |
+| Foton för fotokrävande kontroller | Obligatorisk |
+| Ärendetypens compliance-krav | Obligatoriska |
| Evidensnivå över E0 | Obligatorisk |
-Utskriftsknappen är spärrad tills varje obligatorisk rad är grön; varje
-röd rad visar exakt vad som saknas.
+### 6. Traceability Engine
+Varje export bär ett spårbarhetspaket: ECM-version, ärendetyp,
+evidensnivå, grindstatus per regel-id och samtliga evidensposter med
+hash. Tillsammans med loggen kan varje slutsats härledas: vilken bild →
+vilken mätning → vilken tekniker → vilken regel → vilken regelverksversion
+→ när.
-## Visual-first: kameran är integrationslagret
+## Pre-Diagnostic Validation
-Plattformen prioriterar visuell insamling framför systemintegrationer.
-När information redan visas på en skärm, ett instrument, en utskrift
-eller en etikett fotograferas den — bildtolkningen extraherar, validerar
-och strukturerar informationen automatiskt. Ingen specialintegration
-behövs mot Bosch, TEXA, Autel, Launch, Hella Gutmann m.fl. så länge en
-människa kan läsa informationen.
+Ingen felsökning påbörjas förrän grundkontrollerna är genomförda eller
+dokumenterat motiverade — metodiken låses upp först därefter:
-- **Arbetsorder** → ärendestartens dokumenttolkning (fält + konfidens).
-- **Instrument/diagnosskärmar** → `📷 Instrument` i Dokumentera-panelen:
- foto → typidentifiering (multimeter, diagnosdator, batteritestare,
- mätarkluster, manometer …) → värden med enhet och konfidens → teknikern
- bekräftar → **originalbilden loggas alltid tillsammans med de
- strukturerade värdena** — strukturerad data ersätter aldrig
- originalevidensen.
+1. **Fordonshistorik** — kontrollerad (tidigare arbeten, återkommande
+ fel, TSB, kampanjer; relevanta samband kan noteras som orsakskedja)
+ eller Nej med obligatorisk orsak → kvalitetsvarning.
+2. **Ingående mätarställning** — instrumentpanelen fotograferas;
+ bildtolkningen föreslår värdet, teknikern bekräftar. Fotot blir den
+ officiella ingående mätarställningen.
+3. **Kundens felbeskrivning verifierad** — ytterligare symptom
+ dokumenteras som separata observationer, aldrig hopblandade med
+ kundens beskrivning.
+4. **Tidiga observationer** — reparationsspår, modifieringar, skador,
+ läckage m.m. dokumenteras med foto/observation, eller kvitteras
+ "inga ytterligare".
-Värden med hög säkerhet godkänns automatiskt; osäkra markeras för
-granskning — samma konfidensmodell som arbetsorderskanningen
-(🟢 ≥95 %, 🟡 80–95 %, 🔴 <80 %).
+**Utgående mätarställning** fotograferas inför avslut och blir
+obligatorisk i grinden när ärendet stängs. Rapporten visar in/ut.
-## Spårbarhet
+## Ärendeidentitet (Case Identity & Vehicle Context)
-Varje evidenspost är en händelse i den append-only-loggen med tidpunkt,
-tekniker, ärende och innehåll — omöjlig att ändra i efterhand (triggers i
-databasen). Det ger varje slutsats juridiskt spårbart underlag för kund,
-försäkringsbolag eller domstol.
+Fordonsobjektet är den röda tråden: identiteten registreras **en gång**
+(normalt via arbetsorderskanningen, som nu även läser claim-/garantinummer
+och skadenummer) och återanvänds sedan överallt:
+
+- **Identitetsrad i arbetsytan** — AO, claim, skadenummer, fordon, regnr,
+ VIN, miltal, ansvarig tekniker + ärendetypsval.
+- **Live Share** — låst panel överst med fordon, referenser och status,
+ härledd ur det nivåfiltrerade underlaget.
+- **Slutrapportens första sida** — Ärendeinformation + Fordonsinformation
+ automatiskt.
+- **Exporten** — identitet + spårbarhetspaket i varje JSON.
## Terminologi
@@ -96,13 +124,4 @@ Produkten beskrivs aldrig som en "AI-app" utan som ett **evidensbaserat
diagnossystem** / **intelligent beslutsstöd**. I användargränssnitt och
dokument används *systemet, analysen, bedömningen, tolkningen,
bildtolkningen, beslutsstödet, regelmotorn* — inte "AI", om det inte är
-tekniskt nödvändigt (t.ex. i arkitekturdokumentation om modellorkestern).
-
-## Kommande (regelbibliotekets väg framåt)
-
-- Områdesregler per komponent (däck: fyra bilder + DOT + dimension;
- bromsar: närbild per ok; motorljud: video med ljud …) som
- serverdistribuerade, versionerade regelpaket.
-- Video- och ljudevidens (E3) med analys.
-- Garanti-/försäkrings-/reklamationsprofiler med egna obligatoriska
- fält i kvalitetsgrinden.
+tekniskt nödvändigt.
diff --git a/services/ai-orkester/server.mjs b/services/ai-orkester/server.mjs
index 739dec5..e6a6049 100644
--- a/services/ai-orkester/server.mjs
+++ b/services/ai-orkester/server.mjs
@@ -72,7 +72,7 @@ const ARBETSORDER_FALT_ID = [
"fordon_regnr", "fordon_vin", "fordon_marke", "fordon_modell",
"fordon_motor", "fordon_arsmodell", "fordon_matarstallning",
"fordon_motorkod", "fordon_vaxellada",
- "ao_nummer", "ao_referens", "ao_serviceradgivare", "ao_bokningsdatum",
+ "ao_nummer", "ao_claim", "ao_skadenummer", "ao_referens", "ao_serviceradgivare", "ao_bokningsdatum",
"felbeskrivning",
];
diff --git a/services/plattform/openapi.yaml b/services/plattform/openapi.yaml
index 7721fde..ab67b41 100644
--- a/services/plattform/openapi.yaml
+++ b/services/plattform/openapi.yaml
@@ -568,6 +568,9 @@ components:
- overlamning
- ansvarig_satt
- arbetsorder_skannad
+ - arendetyp_satt
+ - historik_kontrollerad
+ - matarstallning
- export_skapad
- ai_svar
- arende_avslutat
diff --git a/src/felsokning/DelatArendeVy.tsx b/src/felsokning/DelatArendeVy.tsx
index ffcc516..169bc0d 100644
--- a/src/felsokning/DelatArendeVy.tsx
+++ b/src/felsokning/DelatArendeVy.tsx
@@ -6,11 +6,39 @@
import type { Arende } from "./domain";
import { handelseRubrik } from "./domain";
-import { arAvslutat, brief, foton, tidsfordelningsRader } from "./projektioner";
+import { arAvslutat, arendeidentitet, brief, foton, tidsfordelningsRader } from "./projektioner";
import { metodikForArende } from "./store";
import { tidDatum, tidKlockslag } from "./format";
import { FelsokningSkal, Panel } from "./ui";
+function IdentitetsPanel({ arende, avslutat }: { arende: Arende; avslutat: boolean }) {
+ const idn = arendeidentitet(arende);
+ const falt: [string, string | undefined][] = [
+ ["Arbetsorder", idn.arbetsorder],
+ ["Claim", idn.claim],
+ ["Skadenr", idn.skadenummer],
+ ["Regnr", idn.identifierare],
+ ["VIN", idn.vin],
+ ["Miltal", idn.miltal],
+ ["Ansvarig tekniker", idn.ansvarig],
+ ["Status", avslutat ? "Avslutat" : "Felsökning pågår"],
+ ];
+ return (
+
+ Något ytterligare vid mottagandet? (reparationsspår, modifieringar, skador, läckage, korrosion …)
+
+
+ skicka({ typ: "kommentar", text: `${MARKOR_INGA_TIDIGA_OBSERVATIONER}.` })}>
+ Inga ytterligare observationer
+
+ skicka({ typ: "kommentar", text: `${MARKOR_TIDIGA_OBSERVATIONER_KLARA}.` })}
+ >
+ Observationerna är dokumenterade
+
+
+
+ Dokumentera med foto eller observation i panelen nedan — knappen låses upp när något loggats.
+
+
+ )}
+
+ );
+}
+
// Navigationsträd (vänsterkolumnen): ärendets vyer plus metodikens steg
// med status — som en mappstruktur i ett klassiskt verkstadssystem.
function VyTrad({
@@ -370,6 +619,18 @@ function GuideFlik({
);
}
+ // Pre-Diagnostic Validation: metodiken öppnas först när grund-
+ // kontrollerna är genomförda eller dokumenterat motiverade.
+ if (!preDiagnostik(arende).every((r) => r.klar)) {
+ return (
+ <>
+
+
+
+ >
+ );
+ }
+
return (
<>
@@ -422,6 +683,14 @@ function GuideFlik({
+ {/* Utgående mätarställning: obligatorisk för kvalitetsgrinden när
+ ärendet avslutas — erbjuds så fort metodiken är genomarbetad. */}
+ {!arende.handelser.some((p) => p.handelse.typ === "matarstallning" && p.handelse.lage === "utgaende") && (
+
+
+
+ )}
+
setVisaOverlamning(true)}>
Lämna över arbete
@@ -1174,6 +1443,17 @@ function RapportFlik({
const b = brief(arende, metodik, nu);
const bilder = foton(arende);
const fordelning = tidsfordelningsRader(arende, nu);
+ const idn = arendeidentitet(arende);
+ const typ = arendetyp(arende);
+ let matIn: string | undefined;
+ let matUt: string | undefined;
+ for (const p of arende.handelser) {
+ const h = p.handelse;
+ if (h.typ === "matarstallning" && !h.undantag) {
+ if (h.lage === "ingaende") matIn = h.varde;
+ else matUt = h.varde;
+ }
+ }
// Kategoribyten är interna; hypoteser och AI-dialogen är arbetsmaterial
// och ingår inte i det som delas med kund.
const kundposter = arende.handelser.filter(
@@ -1181,11 +1461,13 @@ function RapportFlik({
);
// Alla exporter bygger på samma händelselogg och versionsmärks:
- // version = antal händelser vid exporttillfället.
+ // version = antal händelser vid exporttillfället. Spårbarhetspaketet
+ // (ECM-version, evidensposter med hash, grindstatus) följer med.
const exporteraJson = () => {
const version = arende.handelser.length;
const data = {
export: { format: "JSON", version, exporteradAv: anvandare, tidpunkt: new Date().toISOString() },
+ ecm: sparbarhetspaket(arende, metodik),
arende,
};
const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
@@ -1262,13 +1544,30 @@ function RapportFlik({
Delningslänken kräver att ärendet är synkat mot molnet (inloggad användare).
-
- {b.objekt && (
-