Commit Graph

19 Commits

Author SHA1 Message Date
Claude 3b83fc94e9 Portalen är stängd på riktigt — m-9 stängd
Anmärkningen var att en inloggning som SER ut att autentisera ger
portalen bakom den en auktoritet den inte har. Rättelsen är inte att ta
bort skylten utan att göra spärren verklig där det finns något att
spärra mot.

Med plattformen konfigurerad autentiserar inloggningen mot
/api/auth/logga-in, varje portalväg går genom Portalvakt, och
fakturavyn läser organisationens egna fakturor ur GET /api/fakturor.
Misslyckas hämtningen visas felet — inte exemplet: data som ser äkta ut
men inte är det är värre än ett synligt fel. Utloggningen finns i
portalhuvudet och rensar sessionen på riktigt.

Utan konfigurerad plattform finns ingen session att kräva, och
demonstrationsmärkningen visas exakt i det läget.

---- Varför garantin inte är ett källkodstest ------------------------

Sviten kan bara läsa koden och se att vakten är inkopplad. Släpper den
igenom ändå — fel villkor, fel ordning, ett <Navigate> som aldrig hinner
rendera — ser koden likadan ut. Och en spärr som inte spärrar är precis
det m-9 handlade om.

e2e/portalsparr.mjs bygger därför med plattformen konfigurerad och
tittar var besökaren faktiskt hamnar: fem vägar spärrade utan session,
fem öppna med, utloggning som rensar token och stänger portalen igen.
Mutationstestad — att plocka bort vakten från en enda route fäller den.

Bevisad: 374 enhetstester, typkontroll, genomgången 4/4 ärenden,
portalspärren 14/14.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 12:08:18 +00:00
Claude b457543ede Fakturering i systemet — och ingen betalleverantör
ALVA säljs inte över disk. Aktiveringssekvensen på webbplatsen har hela
tiden sagt det: ansökan granskas, faktura utfärdas, betalning
registreras, organisationen aktiveras. Ändå laddade sidan Stripe.

Stripe. `@stripe/stripe-js` injicerar sitt skript redan vid import, inte
när någon ska betala, så ALVA hämtade en betalleverantör vid varje
sidvisning trots att produkten aldrig tar emot en betalning. Bakom
artefaktens CSP blockerades anropet och syntes som ett fel i konsolen på
ett system som inte har en kassa. Importen går nu mot `/pure`, som är
samma modul utan sidoeffekten. Butikens kassa fungerar som förut, men
bara när någon faktiskt öppnar den. Externa begäranden på ALVA-ytan:
noll.

Faktureringen. Beloppet måste komma någonstans ifrån, och det enda
hållbara stället är organisationens faktiska tillstånd: aktiva konton,
licensperiod, påslagna moduler. En summa någon skriver in kan säga emot
verkligheten — en härledd kan inte det. Samma resonemang som
sammanfattningen. Varje rad bär sitt underlag, så en granskare ser varför
summan blev den den blev utan att fråga någon.

Beloppen räknas i öre, momsen på nettot och inte per rad, och en utfärdad
faktura ändras aldrig: en felaktig faktura krediteras med en post som
pekar tillbaka och kräver ett skäl. Samma regel som för händelseloggen.

Prislistan ligger på ett ställe och är märkt som platshållare — den ska
sättas per marknad. Mekanismen är oberoende av siffrorna.

Ingen betalningshantering, inga kortuppgifter, ingen extern tjänst.
Betalning registreras av en administratör när pengarna kommit in;
systemet påstår aldrig att något är betalt utan att en människa sagt det.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 09:38:52 +00:00
Claude 9533a90b7b Skriv om demonstrationsmärkningen så den inte går att missförstå
Första formuleringen sa "Applications are handled outside this
demonstration". Det läses lika gärna som att ansökningar tas emot någon
annanstans, av ett riktigt system. Det gör de inte — det finns ingen
mottagning alls. En läsare frågade vad meningen betydde, vilket är
svaret på om den var tydlig.

Värre var att produktens beskrivning av avsedd handläggning stod direkt
under: två meningar bredvid varandra där den ena säger att ingenting
händer och den andra beskriver en granskningsprocess. De upphävde
varandra. Den senare är nu märkt "Intended operation:".

Inloggningens ruta hänvisade till att den riktiga autentiseringen finns
i plattformstjänsten, vilket inte hjälper någon som står på sidan. Den
säger nu vad besökaren ska göra: skriv vad som helst, lösenordet
kontrolleras inte, inget konto behövs.

En märkning som inte går att missförstå säger två saker — att ingenting
sker, och vad läsaren ska göra i stället. Fyra tester låser båda.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 04:31:16 +00:00
Claude 3ffedcd78e Märk de ytor som inte gör något (QUALITY-AUDIT-2 · m-9)
Inloggningen autentiserar ingenting: vilken organisation och vilket
användarnamn som helst släpps in, och lösenordet kontrolleras inte.
Kontoansökan skickar ingenting, och referensen på kvittenssidan bildas i
webbläsaren. Portalens siffror är fasta exempelvärden.

Bägge ser ändå ut som att de gör något, och två personer i rad har
försökt använda dem på riktigt innan de frågade. Det är precis vad
fyndet förutsade: en yta som ser färdig ut planerar man efter.

Integrationssidan tillämpar redan den här måttstocken på sig själv — en
profil står `draft` tills den körts mot leverantören, med motiveringen
att en lista där allt ser färdigt ut är den snabbaste vägen till ett
misslyckat införande. Samma regel gäller nu resten av ytan.

Rutan säger vad som INTE sker, inte vad som ska komma. Ett löfte om
framtida funktion vore samma fel i ny form, och ett test avvisar
formuleringar av den sorten.

Det här stänger inte m-9 helt. Den ärliga slutfixen är att låsa
portalrutten bakom den riktiga plattformssessionen, vilket är ett beslut
om vad portalen ska vara — men tills dess vilseleder den inte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 04:24:20 +00:00
Claude 66762629df Bäddad typografi, tätare spärrning, räta hörn och ritningsstämpel
Fyra saker som alla svarar på samma sak: ALVA såg fortfarande inte ut som
det den påstår sig vara.

Snittet som fil. Fallkedjan säkrade ordningen men inte utfallet — utan
DIN installerad föll ytan ned till vad enheten råkade ha, Helvetica på en
iPhone och Roboto på en Android. Ett system som beskriver sig som en
standard får inte se olika ut beroende på var det öppnas. IBM Plex Sans,
specens tredje tillåtna snitt, bakas därför in: latinsk delmängd, tre
textvikter och två för monospace, drygt 100 kB. Licensen följer med.

Vite bakar in woff2 som data-URI. Det är inte en optimering utan ett
krav: ALVA publiceras bland annat som en självbärande sida bakom en CSP
där varje extern begäran blockeras, och en @font-face mot en assetfil
hade tyst fallit tillbaka till enhetens eget snitt — alltså precis det
inbäddningen ska avskaffa. Bara woff2; värdapplikationens bilder är
megabyte stora och förblir egna filer.

Spärrningen ett steg tätare genomgående. DIN-satta OEM-dokument är tätare
än vad ytan var, och med rätt bokstavsform tål den det.

Räta hörn i felsökningen. 69 förekomster av rundad radie, alla ur
Lovable-arvet. Ett verkstadssystem har räta hörn.

Ritningsstämpel sist i rapporten: beteckning, regelpaket, evidensmodell,
plattformsversion, status och utgåvedatum. En granskare måste kunna se
vilka versioner som gällde när ärendet stängdes, inte vilka som gäller
den dag rapporten läses.

Fyra tester låser inbäddningen, inklusive att ingen @font-face pekar mot
en extern värd.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 03:08:30 +00:00
Claude 9668cc256b Ge ALVA-ytan sin egen typografi enligt ALVA-SPEC-001
ALVA satte inget eget snitt och ärvde därför värdapplikationens
`Crimson Text` — en antikva. Specens paragraf 6 föreskriver DIN 2014,
med FF DIN och IBM Plex Sans som tillåtna alternativ.

Skillnaden är inte kosmetisk. Bokstavsformen är det första som säger
vilken tradition ett verktyg tillhör, och dokumentet beskrev ett tyskt
industrisystem medan skärmen visade en bokstavsform ur en helt annan.
På en telefon, där ingenting annat konkurrerar om intrycket, var det i
praktiken allt man såg.

Fallkedjan är därför inte godtycklig: en organisation som licensierat DIN
får DIN, övriga faller ned genom grotesker som delar dess karaktär, och
aldrig till en antikva. Beteckningar och mätvärden sätts med fast
teckenbredd och tabellsiffror — en beteckning jämförs oftare än den läses.

Reglerna gäller bara ALVA-ytan; butiken lämnas som den är. Fyra tester
låser snittet, kaskaden och siffrorna, inklusive att fallkedjan aldrig
slutar i en antikva.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 21:21:45 +00:00
Claude 07b6713245 Gör ALVA läsbart på telefon
Portalens tabeller sköt ut dokumentet till 842 px på en 390 px-skärm.
Sidan gick att dra i sidled och texten kapades i högerkanten.

Tre orsaker, tre olika svar.

Tabellerna. En sexkolumnstabell på en telefon har två utfall och bägge är
dåliga: antingen tvingas hela sidan i sidled, eller så scrollar tabellen
inuti sig själv och läsaren ser tre tecken av varje kolumn. Under 640 px
blir varje rad därför en grupp namngivna fält — kolumnrubriken som
etikett, cellen som värde. Samma form som Falt redan använder, och samma
princip som resten av ytan: ett instrumentpanelsblad läses uppifrån och
ner. Bägge formerna renderas och växlas med bredd, inte med JavaScript.

Navigationen. Portalens fem länkar bröts inte utan breddade dokumentet.
Raden bryts nu, med tätare mellanrum på smal skärm.

Fasindikatorn. Kolumnerna saknade min-w-0 och kunde därför inte krympa
under sitt innehåll. Ett första försök lät namnen brytas, men
"LOCALIZA/TION" mitt i ordet är inte tydligare än inget namn. Under
640 px bär bokstaven och statussymbolen informationen — vilket är precis
vad A·L·V·A är till för — medan raden ovanför namnger den aktiva fasen
och dess syfte i klartext. Namnet finns kvar för skärmläsare.

Mätt vid 390 och 360 px: samtliga sju ALVA-vyer, ansökans kvittens,
ärendelistan och ärendesidans tre flikar håller sig nu inom skärmbredden.
Fyra tester låser konstruktionerna. Designtestet fångade förresten mitt
eget brott mot 8-px-rutnätet på vägen — py-1 — och koden rättades, inte
testet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 20:24:46 +00:00
Claude 31727a4ea0 Härda enligt revision 2: stäng schemat, ta bort dubbelregeln
C-5. granskaHändelse itererade schemats nycklar och aldrig händelsens,
så okända fält accepterades och sparades ordagrant. Två garantier vilade
på motsatsen: krypto-shreddingen skyddar en fast lista av fältnamn, så
personuppgifter på en vanlig observation krypterades aldrig och överlevde
raderingen — och delningsfiltret är typnivå, så samma fält gick ut i
kundens delningslänk. Schemat är nu stängt, med varje valfritt fält
deklarerat. Det gäller även `kalla`: protokollinläsningen fungerade bara
därför att schemat var öppet. Avslaget är hårt, inte en tyst strykning.
Verifierat mot riktig trafik — samtliga händelser som klienten faktiskt
producerar passerar.

M-7. Klienten upprepar inte längre grindens regel utan anropar grinda()
och visar dess egna hinder. Villkoret hade glidit isär två gånger utan
att något test märkte det.

Det avslöjade omedelbart ett verkligt fel i grinden: den krävde
textresultat även på kontroller vars krav är foto — trots att
gränssnittet märker fältet "Observation (valfritt)". Servern hade alltså
nekat avslut på nästan varje riktigt ärende, och det syntes inte så länge
klienten hade ett eget och mildare villkor. Evidens graderas nu efter
kontrollens eget krav.

M-8. Protokollinläsningen svarar med utfall per händelse i stället för en
siffra, 207 vid delvis lyckad inläsning, innehållshärledda id:n i stället
för klockan, och en transaktion runt hela importen.

M-9. En genererad webhookhemlighet lämnas ut en gång vid skapandet.

m-8. Profilens vägslagning begränsas till egna egenskaper.
m-10. Ett mätvärde som kommer ur en kontroll redovisas en gång.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 18:19:11 +00:00
Claude 45967d086e Lås inte in ärenden där åtgärden dokumenterades före förslaget
När kundbeskedet blev ett avslutsvillkor i klienten uppstod en fälla:
knappen "Lämna åtgärdsförslag till kund" visades bara när ingen åtgärd
var dokumenterad, och beskedsrutan bara när ett förslag fanns. En
tekniker som skrev åtgärden först hade därmed ingen väg att registrera
beskedet, och ärendet gick inte att stänga.

Grinden avvisade redan sådana ärenden vid synk — villkoret i klienten
flyttade bara upptäckten. Men ett spärrvillkor utan väg ut är ett fel
även när spärren i sig är riktig.

Förslagsknappen står kvar tills ett förslag faktiskt lämnats. Ordningen
förslag → besked → arbete är fortfarande den panelen föreskriver, och
loggen är append-only med tidsstämplar, så ett besked som registreras i
efterhand syns som just det.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 17:44:26 +00:00
Claude 8daeb41ba1 Kräv kundens besked även i klienten innan avslut
Grinden på servern har alltid krävt kundbeskedet när arbete faktiskt
utförts. Klientens kanAvslutas gjorde inte det, och glappet syntes först
när tio ärenden av olika karaktär kördes hela vägen genom gränssnittet:
samtliga tio gick att stänga på skärmen med utfört arbete och utan att
kunden hade sagt ja.

Det är samma sorts fel som slutsatsen hade, på ett annat villkor — och
det värre av de två, eftersom ett utfört arbete utan registrerat besked
är precis vad en tvist handlar om.

Hindertexten namnger nu kundbeskedet, och ett test speglar klientens
avslutsvillkor mot grindens hela åtgärdskedja så att nästa villkor som
läggs till i grinden inte kan glömmas i klienten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 17:41:45 +00:00
Claude 6fa7953012 Logga metodikens mätkontroller som mätvärden
En kontroll vars krav är "matvarde" loggade bara kontroll_utford. Det
gällde 56 av metodikernas 153 kontroller — drygt en tredjedel — och fick
två följder som bägge upptäcktes när tio ärenden kördes igenom
gränssnittet:

Felorsaksanalysen nekade "Mätresultat" som underlag med motiveringen att
underlaget inte finns i loggen, trots att teknikern just hade matat in
mätvärdet som kontrollen krävde. Enda vägen förbi var att mata in samma
siffra en gång till via dokumentationspanelen.

Evidensprofilen i analysvyn underskattade systematiskt hur mycket som
faktiskt mäts, eftersom mätningarna aldrig fanns som mätvärden.

Mätningen loggas nu som det den är. Utan känt mätdon graderas den E1 och
inte E4 (QUALITY-AUDIT M-1) — ett avläst tal utan spårbart instrument är
inte en spårbar mätning.

Tre tester låser förhållandet mellan metodikernas kravtyper och den
evidens de producerar, så att en ny kravtyp inte kan införas utan att
någon tar ställning till vad den ska ge för evidens.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 17:35:26 +00:00
Claude 590fab3a70 Spärra avslut utan slutsats även i klienten (ALVA-RULE-200)
Kvalitetsgrinden på servern krävde en slutsats, men klientens
avslutsknapp gjorde inte det. Ett ärende gick därför att stänga på
skärmen utan ett varför, och teknikern fick beskedet först vid synk —
den sämsta tänkbara tidpunkten, eftersom bilen då har lämnat verkstaden.

Klienten anropar nu granskaSlutsats() — samma funktion som grinden, inte
en klientkopia av regeln — och avslutsknappen är spärrad tills den är
ren. Slutsatspanelen visas så fort underlaget är helt, inte bara när
metodikens sista steg är avbockat, så att frågan kommer när den går att
besvara och inte som ett hinder efteråt.

Hindret säger vad som fattas i stället för att bara konstatera att kraven
inte är uppfyllda: först underlaget, sedan de enskilda bristerna i
slutsatsen.

Fyra tester jämför verdikt mellan klient och grind för samma logg, så att
de två ändarna inte kan glida isär igen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 16:20:27 +00:00
Claude cd6b2caca5 Sammanfattning och slutsats i rapport och Live Share; API dokumenterat
Sammanfattningen ligger först i både kundrapporten och Live Share.
Mottagaren är oftast inte tekniker — det är kunden, en
försäkringshandläggare eller en flottansvarig — och de ska få bilden på
fem sekunder och sedan kunna gå djupare, inte tvärtom.

I Live Share härleds den ur det NIVÅFILTRERADE underlaget. Det betyder
att sammanfattningen aldrig kan avslöja något som delningsnivån döljer:
filtret ligger före projektionen, inte efter.

Slutsatsen visas som ett eget avsnitt före underlaget. En handläggare
läser skälet först och kontrollerar det sedan — den ordningen är hela
poängen med att fältet finns.

Sju nya vägar dokumenterade i OpenAPI och låsta av paritetstestet:
sammanfattning, protokollinläsning, statistik, integrationskategorier,
prenumerationer, radering och mätdon. Ett API som inte är dokumenterat
är inte ett API någon kan koppla in sig mot — och specen valideras
maskinellt så dokumentationen inte kan glida från servern.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 15:55:31 +00:00
Claude 3ec25dea9c ALVA: analysvy, sammanfattning och integrationsgränssnitt
---- Statistiken är ett produktbeslut ----------------------------------

Vilka siffror som visas avgör vad organisationen optimerar, så tre mått
är uteslutna med avsikt och låsta av test: ärenden per tekniker,
genomsnittlig ledtid och aktivitet. Alla tre belönar den som hoppar över
kontroller, och ett svårt fel SKA ta längre tid.

Medtagna, var och en handlingsbar:

  VERIFIERINGSGRAD   Andel avslut med fastställd orsak. Det enda mått
                     ett försäkringsbolag egentligen bryr sig om. Att
                     den inte är 100 % är friskt.
  REPRODUKTIONSGRAD  Låg siffra förutsäger återkommande fordon — man kan
                     inte åtgärda det man inte sett.
  OMARBETNING        Samma fordon tillbaka med samma orsakskategori inom
                     ett fönster. Det dyraste felet i en verkstad och det
                     enda ingen mäter, eftersom det kräver att två
                     ärenden kopplas ihop. Här är kopplingen gratis.
  UNDANTAGSFREKVENS  Vilka kontroller som hoppas över, per steg och fas.
                     Ett steg högt i listan är antingen felskrivet eller
                     kräver utrustning som saknas — bägge åtgärdbara.

Ett mått utan underlag visas som NOT APPLICABLE, aldrig som noll.
Skillnaden avgör om någon fattar beslut på en siffra som inte finns.

---- Sammanfattningen är härledd, inte genererad -----------------------

Frestelsen är att låta modellen skriva den. Det vore fel av tre skäl:
den blir en del av ett beslutsunderlag och måste därför gå att lita på
utan att granskas mot loggen varje gång; samma ärende måste ge samma
text om två år; och verkstadsgolvet har dålig täckning.

Den är alltså en projektion som briefen och rapporten. Den innehåller
inget som inte står i loggen och säger uttryckligen när något saknas i
stället för att utelämna det. Ett test kräver att den aldrig skriver
"felet konstaterat" när orsaken inte fastställts.

---- Integration utan påhittade endpoints ------------------------------

Jag känner inte Beonodes, ServiceCams eller CABAS faktiska gränssnitt.
En uppfunnen endpoint som ser färdig ut är sämre än en tom: den ser ut
att fungera tills någon försöker.

Därför ett profildrivet gränssnitt. En profil beskriver vad en KATEGORI
av system förväntar sig, och märks validated först efter att den körts
mot leverantören. Tills dess står den som draft, och det syns i
gränssnittet — en integrationslista där allt ser färdigt ut är den
snabbaste vägen till ett misslyckat införande, eftersom verkstaden
planerar efter den.

Kategorier: diagnosprotokoll, DMS, videooffert, fordonsdata,
skadekalkyl (CABAS är nordisk standard), garanti och försäkring.

Skadekalkyl går åt båda håll. Det ALVA tillför en kalkyl är inte fler
poster utan beviskedjan bakom dem: vad som kontrollerades, vad som
uteslöts och varför. Det är den enda del av en kalkyl som i dag inte går
att granska i efterhand.

Inkommande protokoll blir evidens, inte bilagor, med härkomsten bevarad
i varje post — ett värde som kommit utifrån får aldrig se ut som något
teknikern själv mätt. Saknas instrumentets identitet nedgraderas värdet
till E1 enligt samma regel som gäller manuella mätningar.

Utgående leveranser signeras med HMAC över tidsstämpel och kropp;
tidsstämpeln ligger inne i signaturen så en fångad leverans inte går att
spela upp i morgon. Verifieringsfunktionen exporteras så mottagaren kan
använda exakt samma kod — de flesta integrationsfel uppstår i glappet
mellan två implementationer av samma signatur.

Prenumerationer går genom samma SSRF-gräns som leverantörsuppslagen, och
leverans sker efter att loggen skrivits: en mottagare ska aldrig kunna
se en händelse som inte finns i loggen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 15:51:30 +00:00
Claude 01189ae42a ALVA-RULE-200: ett ärende stängs aldrig utan ett varför
Kravet är enkelt att formulera och lätt att bygga fel. En obligatorisk
fritextruta blir "klart" på tredje ärendet, och då har vi bara gjort
dokumentationen långsammare utan att göra den bättre.

Därför fyra frågor med olika adressat i stället för ett fält:

  MOTIVERING   Varför följer slutsatsen av evidensen? Detta är raden som
               saknas i varje verkstadsprotokoll. Underlaget säger vad
               som mättes, slutsatsen vad som är fel — ingenting säger
               varför det ena medför det andra, och det är precis det
               steget en försäkringsbedömare granskar.
  UTESLUTET    Vad övervägdes och varför föll det bort?
  ÅTGÄRDSVAL   Varför denna åtgärd och inte en annan?
  KVARSTÅENDE  Vad är fortfarande osäkert? Får vara "inget" — men aktivt.

Kvalitetsgranskningen är riktad mot hur någon med bråttom faktiskt
skriver: en katalog över icke-svar (klart, åtgärdat, trasig, se ovan,
vet ej), minsta längd, och kravet att texten bär ett orsakssamband eller
refererar konkret evidens. Den som skriver "12,4 V vid stift 14"
hänvisar till en mätning utan att säga ordet — regeln får inte tvinga
fram ett språkbruk som inte är teknikerns.

Den regel som gör underlaget användbart för ett försäkringsbolag härleds
ur loggen: en hypotes som dokumenterats och inte blivit slutsatsen MÅSTE
bemötas. Utan den är en felsökning en gissning som råkade stämma.

Den ärliga vägen finns: orsaken kunde inte fastställas är ett giltigt
utfall, ofta mer användbart än en påhittad orsak — men varför den inte
kunde det är fortfarande ett varför.

Slutsatsen är kunddelbar. Den besvarar "varför kostade det här vad det
kostade" och är den enda rad en bedömare behöver. Att bygga funktionen
och sedan hålla den intern vore att bygga den förgäves.

I gränssnittet granskas fälten medan man skriver, inte efter Spara, och
obemötta hypoteser listas — teknikern ska aldrig behöva gissa vad som
fattas. Det är skillnaden mellan ett krav som respekteras och ett som
kringgås.

---

Typkontrollen avslöjade under arbetet en riktig bugg i mitt eget
grindarbete: schemat och grinden skrevs mot antagna fältnamn i stället
för mot domänmodellen. atgard_utford heter beskrivning och utford, inte
text. Följden var värre än ett typfel — grinden såg utförd åtgärd som
utebliven och krävde därför aldrig kundbesked eller kvalitetskontroll.
Det syntes inte, eftersom testfixturerna hade samma antagande.

Rättat i schema, grind och fixturer, och låst av två nya test: varje
fält i schemat måste finnas i domänmodellen, och varje händelse
demoärendet producerar måste passera serverns validering. Ett schema som
avvisar riktig trafik är värre än inget schema.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 15:20:27 +00:00
Claude baa5288add ALVA-modellen synlig i guiden
Fasindikatorn ovanför metodikpanelen: var i metoden arbetet befinner
sig, vilken fas det aktuella steget hör till, och vad fasen uttryckligen
inte gör.

Fasen härleds ur steget via den delade klassificeringen, så indikatorn
kan aldrig visa något annat än vad metodiken faktiskt gör. En indikator
som sätts separat blir förr eller senare fel, och då är den värre än
ingen — den påstår att arbetet är i verifiering när det fortfarande
lokaliserar.

Ärendets beteckning står i samma rad. Ett id ur loggen är en
ogenomskinlig sträng; ALVA-CASE-00007 är det som sägs i telefon och
skrivs i ett protokoll.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 14:59:45 +00:00
Claude a8fdc9ebcc ALVA: webbplats, portal och kunskapskällor
Webbplatsen och plattformen är ett system. Samma komponentbibliotek,
samma rutnät, samma ord — besökaren lämnar aldrig marknadswebben när den
loggar in, eftersom den inte gör det. När apparna kommer återanvänder de
samma bibliotek.

Det som saknas på startsidan är lika avsiktligt som det som finns: ingen
hjältebild, ingen gradient, ingen animation, inga kundlogotyper, ingen
uppmaning att boka demo. En sida som försöker övertyga läser som
marknadsföring; en sida som redovisar läser som dokumentation. Den
senare är vad en teknisk chef fattar beslut utifrån.

Kunskapskällorna är byggda som Operational Knowledge Infrastructure:
leverantörsoberoende gränssnitt där organisationen ansluter det den har
licens till. Det gör att produkten aldrig behöver marknadsföras med "vi
stödjer X". En betainstallation fungerar på enbart egna dokument.

Livscykeln har fem tillstånd med avsikt. Configured och Connected är
inte samma sak — en nyckel kan vara ifylld och ändå fel — och Validated
skiljer sig från Connected: anslutningen svarar, men har den data för de
fordon organisationen faktiskt arbetar med? Det är den frågan som avgör
om källan är till nytta.

Portalens nyckeltal visas som NOT APPLICABLE i stället för som tomma
grafer. Att visa noll vore att lova något som inte finns; att dölja
raderna vore att dölja riktningen.

Ett test läser den faktiska källkoden och låser disciplinen: inga
gradienter, ingen animation, inga emojier utanför ✓ ○ □ →, ingen färg
utanför paletten, inga marknadsföringsord. Ett designsystem som bara
finns i ett dokument blir urvattnat på tredje sidan någon lägger till.

Testet avslöjade att min egen kod använde py-3 — 12 px — och alltså bröt
8 px-rutnätet på sju ställen. Jag rättade koden, inte testet. Ett rutnät
med undantag är inget rutnät.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 14:01:24 +00:00
Claude e73decd3f5 Revisionen: C-1, C-2, M-2, M-3, m-1 och m-2 åtgärdade
De fyra fynd som underminerade bevisvärdet sitter i samma kodväg och
åtgärdas därför tillsammans.

C-1 · Härkomsten sätts av servern. anvandare kommer ur den verifierade
token och tidpunkt ur serverns klocka. Klientens tidsstämpel kastas inte
— vid offline-arbete är den det enda som finns — utan bevaras som
registrerad_tidpunkt bredvid mottagningstiden, så glappet blir synligt i
stället för osynligt.

C-2 · Kvalitetsgrinden flyttad till services/gemensam/grind.mjs och
utvärderas nu på servern vid arende_avslutat. Ett avslut som inte
passerar får 409 med de faktiska hindren. Metodikdatan flyttades till
services/gemensam/metodiker.mjs och klientens metodiker.ts är en typad
återexport, så det finns fortfarande exakt en sanning.

M-2 · Högvoltsspärren är ett hinder. Ett nekande svar på behörighets-
eller spänningsfrihetsfrågan stoppar metodiken i stället för att räknas
som besvarad, och spärrar avslutet på servern. Ett obesvarat
säkerhetskrav spärrar också — tystnad är inte ett ja. Reglerna ligger i
data så nästa farliga metodik bara behöver en rad.

M-3 · Händelser valideras mot schema före skrivning. Loggen är
append-only, så en felaktig post kan aldrig rättas — kontrollen måste
ske innan, efteråt är det för sent för alltid. Okänd typ avvisas.

m-1 · Delningskoden använder förkastningsurval i stället för modulo.
m-2 · Id-kollisioner räknas i stället för att passera tyst.

21 nya tester låser varje regel. Ett skräddarsytt test kräver dessutom
att varje typ i händelseschemat är klassificerad i delningslistan — en
ny typ kan alltså varken läcka eller tappas bort.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 13:32:00 +00:00
Claude 301c477e25 Merge main: Guidad Felsökning flyttar ur roten till felsokning/
Main är sedan den här grenen skapades en helt annan produkt — Semantika,
en mobilapp med egen CDK-infrastruktur. Den äger nu repots rot: en
npm-workspaces-monorepo med apps/mobile, services/api och infra.

För att båda ska rymmas i samma repo flyttar Guidad Felsökning in i en
egen katalog i stället för att göra anspråk på roten:

  felsokning/app        webbklienten (Vite, egen package.json och
                        eslint-/vitest-konfiguration)
  felsokning/services   plattformstjänsten och AI-orkestern
  felsokning/infra      Terraform och databasschemat
  felsokning/docs       vision, moduler, drift
  felsokning/supabase   edge-funktion och migrationer

Merge:n hade tagit bort 128 filer som Guidad Felsökning bygger på —
värdapplikationens komponenter, Supabase-klienten, tillgångar — eftersom
main raderat dem och den här grenen inte råkat ändra just dem. De är
återställda på sin nya plats. Utan dem gick varken bygget eller
testerna: ai.ts och synk.ts importerar Supabase-klienten.

Semantikas rotfiler är orörda: package.json, eslint.config.js och
.github/workflows/ är deras. Guidad Felsökning har egna motsvarigheter i
sin katalog.

CI flyttar samtidigt från GitHub Actions till .gitea/workflows — samma
syntax, egna runners. .github/workflows/ tillhör Semantika härefter.

Verifierat på den nya platsen: 96 vitest-tester, typkontroll, eslint på
både klient och tjänster, bygge, och integrationstest mot riktig Postgres.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-04 12:22:49 +00:00