322d228c80ff7e9b534e6d0de00adf205a04e40a
20 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
322d228c80 |
ALVA-RULE-200 gällde bara på svenska — nu på tio språk
Slutsatsgranskningen avvisar icke-svar med en ordlista: "klart", "ok", "trasig". Listan var enbart svensk. En tysk tekniker som skrev "erledigt" i motiveringsfältet passerade filtret — inte därför att texten dög, utan därför att filtret bara kände igen "klart". Grinden släppte igenom avslutet och rapporten såg fullständig ut. Det var alltså inte en översättningsbrist utan ett hål i den regel som är hela produktens värde, och hålet fanns på varje marknad utom en. Samma sak åt andra hållet: orsaksorden som visar att en text innehåller ett resonemang var svenska, liksom evidensorden. Engelskans "photo" innehåller inte "foto", så "the photo shows the arcing at pin 14" räknades inte som en hänvisning till underlag. Följden hade varit värre än ett släppt avslut — en korrekt skriven motivering hade nekats, och en spärr som nekar rätt svar är en spärr man lär sig kringgå. Listorna ligger nu i sprak/ord.mjs, per språk, och slås ihop till en union i stället för att väljas efter inställning. Ett icke-svar är ett icke-svar oavsett språk — jämförelsen görs mot hela fältet, så en tekniker som skriver på ett annat språk än organisationens ska inte kunna passera på den vägen. Orsaks- och evidensorden går åt motsatt håll: unionen gör kontrollen mer tillåtande, aldrig strängare, och det är rätt riktning att fela åt. Medvetet utanför listorna: "inget", "keine", "none". Att ingenting kvarstår osäkert är ett giltigt och ofta korrekt svar; att göra det till ett icke-svar hade tvingat fram utfyllnad, och utfyllnad är sämre än ett kort sant svar. Ett test låser det. Bristernas texter kommer nu ur katalogen och bär sin nyckel, precis som grindens hinder. Fältnamnet översätts med resten av meningen — "Begründung fehlt.", inte "Motivering fehlt.". Mutationsprövat: med listan återställd till enbart svenska föll nio tester, ett per språk. Svenska och engelska är genomgångna; övriga listor är en första uppsättning och står som ogranskade i filhuvudet, av samma skäl som `granskat` i SPRAK — de är metodik, inte gränssnitt. 597 tester, 186 integrationskontroller, typkontroll, lint och genomgång gröna. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
be10704349 |
Grinden talar organisationens språk — engelska som standard
Kvalitetsgrinden formulerade sina hinder på svenska, hårdkodat. I en produkt där engelska är standardspråket betyder det att en spärr kan neka ett avslut på ett språk teknikern inte läser. Det är en spärr utan väg förbi: teknikern ser att systemet vägrar men inte varför, och den enda utvägen blir att ringa någon. Det är då regeln slutar vara en regel och blir ett hinder man lär sig kringgå. Varje hinder bär nu både nyckel och färdig text. Nyckeln därför att en klient som byter språk ska kunna rendera om utan att fråga servern; texten därför att ett hinder som hamnar i en logg eller en PDF måste gå att läsa utan katalogen. Hindrets id och nyckel är språkoberoende — det är bara texten som byter. Språket är organisationens, inte användarens. En verkstad i Tyskland med en polsk tekniker ska ha ett gemensamt dokumentationsspråk; rapporten ska inte byta språk beroende på vem som råkade stänga ärendet. Det lagras i organisationens inställningar, och en felstavad landskod blir engelska i stället för ett fel — språkinställningen är en etikett och ska inte hindra någon från att spara sina objekttyper. SPARRFRAGOR bär nu nycklar i stället för svensk text. Testet som jämför serverns lista med klientens jämför nycklar, så listorna kan fortfarande inte glida isär. Två tester prövade svenska ord i grindens utdata och gick sönder, vilket var rätt av dem. De prövar nu nyckeln — texten är översatt och byter språk med organisationen, och att pröva svenska ord hade gjort dem till tester av vilket språk som råkar vara standard. Ett nytt test prövar det som faktiskt betyder något: samma id, samma nyckel, olika text. Integrationstestet följer språket hela vägen — organisationens inställning, genom servern, ut i det 409-svar som nekar avslutet: engelska som standard, tyska efter byte, engelska igen vid okänd kod. 582 tester, 186 integrationskontroller mot riktig Postgres, genomgång och portalspärr gröna. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
995858174d |
Språk: engelska som källa, tio EU-språk, och en struktur som inte får översättas
Engelska är standard- och källspråk. Nio översättningar till: tyska,
franska, spanska, italienska, polska, nederländska, portugisiska,
rumänska och svenska.
Två sorters text, behandlade olika. GRÄNSSNITTSTEXT faller tillbaka på
engelska tyst — en engelsk knapp hos en tysk användare är irriterande
men ofarlig. METODIKINNEHÅLL gör det aldrig tyst: det märks som
ogranskat, med språket namngivet. Skälet står i modulhuvudet och är hela
poängen med uppdelningen: engelska SYNS som ett annat språk, medan en
felaktig översättning ser ut som en instruktion. En maskinöversatt
säkerhetsanvisning som ingen fackman läst är därför sämre än en engelsk.
Bara engelska och svenska är `granskat: true`.
Strukturen översätts inte. ALVA-SPEC-001 §2 slår fast att fasnamn och
statusord skrivs likadant i varje land — en revisor ska kunna läsa en
rumänsk och en tysk rapport utan att veta vilket språk verkstaden
arbetar på. Det hade gått att skriva in dem oöversatta i varje katalog
och låsa dem med ett test; det är svagare, för en översättare som ser
"Passed" i den polska filen översätter den, och testet blir en tvist i
stället för en regel. Nycklarna saknas i stället helt i
översättningarna och `t()` hämtar dem alltid ur engelskan. Då finns
ingenting att översätta fel.
Testet räknar inte bara nycklar — det går att få grönt genom att
kopiera engelskan till tio filer. Det prövar fyra saker: att katalogen
är komplett, att strukturen inte är översatt, att inget språk är
engelska i förklädnad (tak på 25 % identiska strängar), och att
variabelhållarna överlevde. {procent} som blir {percent} i den franska
filen ger inget fel — den ger "{percent} % de l'interface" på skärmen,
för alltid.
Mutationsprövat: en borttagen nyckel, en översatt statussträng, en
trasig variabelhållare och en polsk fil som var en kopia av engelskan
gav sex röda tester. Polskan har dessutom en egen anmärkning i
filhuvudet: {sprak} sätter in "Polski" i nominativ, och "w języku
Polski" är fel — meningarna är därför omskrivna så att namnet står som
etikett i parentes.
581 tester, typkontroll och lint rena.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
|
||
|
|
5579006e79 |
Abonnemang: gratis start, månadsfaktura, och en låsning som aldrig rör historiken
Kontot startar på Free och stannar där tills någon väljer annat. En provperiod som tyst börjar kosta är samma sorts fälla produkten finns för att undvika. Fakturan skapas ändå vid registreringen — på noll kronor — därför att den etablerar serien och visar kunden exakt vad den inte betalar för. Fyra nivåer: Free (hela metoden, två konton), Standard, Premium, Enterprise. Enterprise har inget listpris i stället för ett påhittat. Basavgift plus per aktiv användare, och nivån är en HÄNDELSE — vilken nivå som gällde när en faktura utfärdades måste gå att svara på i efterhand, och en kolumn som skrivits över kan inte svara. Månadsjobbet är idempotent på perioden: kör det två gånger samma dygn och den andra körningen fakturerar ingenting. Ett fakturajobb som dubbelfakturerar vid en omstart är värre än ett som inte kör alls. Perioden räknas från registreringsdagen, inte från den första i månaden — den som registrerar sig den 20:e ska inte få en faktura på elva dagar som sin första upplevelse av produkten. PDF utan beroenden. Kravet var inga beroenden, och ett PDF-bibliotek drar in fem till för att rita text i två spalter. PDF är ett textformat; generatorn är tvåhundra rader som går att läsa. Renderad och verifierad i Chromium. Kunden hämtar fakturan själv eller anger en adress — bägge vägar leder till samma dokument, och e-post är ett tillägg, inte den enda vägen till sitt eget underlag. ---- Låsningen och dess gräns ------------------------------------------ Vi litar på kunden: inget kort, ingen förskottsbetalning, ingen spärr innan någon fått veta. Förfallen faktura ger synlig nedräkning i 14 dagar och sedan stopp för nya ärenden. Men läsning och export är sanna i ALLA tillstånd, och det är inte generositet. Ärendeloggen är verkstadens underlag i en garanti- eller försäkringstvist som gäller DERAS kund — en tredje part utan del i vår obetalda faktura. Att göra det oåtkomligt vore att använda någon annans rättsliga ställning som påtryckningsmedel. Prövat från flera håll, eftersom det är en regel som är lätt att tumma på under press. En nollfaktura kan aldrig låsa någon. Free fakturerar noll, och en obetald nollfaktura är en bokföringspost, inte en skuld. ---- Tre fynd som testerna grävde fram ---------------------------------- 1. En kuverterad nyckel gjorde HELA organisationens övriga ärenden oläsbara när huvudnyckeln saknades — nycklarFor laddar alla nycklar, och en enda som inte gick att öppna kastade. En delvis migrerad organisation blev alltså helt stum av ett fel som gällde ett ärende. Nu hoppas den över, med varning i loggen, och fälten maskeras — vilket dessutom är rätt utfall i sak: det är precis vad krypto-shredding lämnar efter sig. 2. Integrationstestet försökte backdatera abonnemangets registrering och stoppades av min egen trigger. Att testet fick böja sig för regeln och inte tvärtom är poängen med regeln. 3. Palettestet räknade upp färgerna som en andra lista — samma dubblering som M-7 handlade om. Det läser dem nu ur FARG, med ett tak på åtta värden som motvikt: en palett som växer förbi det är en färglåda. 491 enhetstester · 179 integrationskontroller · genomgången 4/4 · portalspärren 18/18. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
ae5acbed92 |
Fotograferad mätarställning, versionshistorik och tysk kravbild i foten
---- Mätarställningen ska fotograferas ---------------------------------- Klienten krävde redan fotot: värdefältet visas först efter bilden. Men GRINDEN gjorde det inte, och en regel som bara finns i gränssnittet är en vana — inte en spärr. Det är samma förhållande som QUALITET C-2 gällde, fast åt andra hållet: här var servern svagare, vilket är värre, eftersom servern är den auktoritativa. Skillnaden är hela uppgiftens bevisvärde. En inskriven siffra är teknikerns påstående om vad som stod på mätaren; ett foto visar vad som stod där. Mätarställningen avgör garanti- och försäkringsfrågor i efterhand och är den enda uppgift i ärendet någon kan ha ett intresse av att skriva fel. Evidensgraderingen följer nu med: fotograferad ger E2, inskriven ger E1 och märks som inskriven i rapporten. Undantag finns och måste finnas — slocknad display, oåtkomlig timräknare — men kräver motivering, som det nekade historiksvaret. ---- Versionen räknades aldrig upp -------------------------------------- Systemet påstod "ALVA 1.0" efter tre revisioner, en fakturamodul och en stängd portal. Versionen sa alltså ingenting om vad man fick. Historiken är HÄRLEDD UR VAD SOM FAKTISKT LEVERERATS och varje post pekar på sin commit. En utgåva som inte går att peka på hör inte hemma i listan — en påhittad ändringslogg är samma obefogade säkerhet som produkten finns för att undvika. Första siffran höjs bara när GARANTIERNA ändras, vilket hänt två gånger: 2.0 när fakturan blev ett härlett dokument, 3.0 när TÜV-härdningen ändrade vad loggen garanterar. Nuvarande: 3.1. Och ett fynd på vägen: ritningsstämpeln läste versionen ur den AKTUELLA konstanten, så ett ärende stängt under 1.0 visade 3.1 — precis det stämpelns egen beskrivning säger att den inte ska göra. Avslutshändelsen bär numera versionen, och stämpeln läser den därifrån. Äldre ärenden säger uttryckligen "ej registrerad" i stället för att låna dagens siffra. ---- Tysk kravbild i foten ---------------------------------------------- Listan är tysk därför att § 5 DDG är den strängaste och mest utkrävbara i EU: klarar man den klarar man de andra marknaderna på köpet. Två fällor som är aktuella just nu, och bägge ser fortfarande ut som upplysningar: ODR-LÄNKEN SKA BORT. Förordning 524/2013 upphävdes genom förordning (EU) 2024/3228 och plattformen stängdes 20 juli 2025. Länken har legat i tiotusentals fotnoter sedan 2016 och pekar numera ingenstans. Foten saknar den medvetet. § 5 TMG HETER § 5 DDG sedan 14 maj 2024. Modulen hittar inte på uppgifter. Ett Impressum med påhittad adress är inte ett halvfärdigt Impressum utan ett vilseledande, och skadan större än den tomma rutans. Osatta fält redovisas som en åtgärdslista med rättslig grund, så driften kan spärra en driftsättning på listan i stället för att upptäcka bristen när brevet kommer. 460 enhetstester · genomgången 4/4 · typkontroll ren. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
a94c228cab |
Garantiregimer, försäkringsvillkor och felanmälan i ärendet
---- Garantier (ALVA-SPEC-040) ----------------------------------------- Skiljelinjen mellan LAGSTADGAT och AVTALAT bär allt annat, och den förväxlas dagligen åt bägge håll. Överraskande lite av det verkstaden kallar garanti är lagstadgat: nybilsgaranti avtalad. Ingen lag i EU eller USA kräver den. rostskyddsgaranti avtalad. Ingen lag kräver den, någonstans. lackgaranti avtalad. drivlinegaranti avtalad. avgasgaranti LAGSTADGAD i bägge, och den enda som är det. Att kalla rostskyddet lagstadgat är fel; att kalla avgasgarantin en tillverkarutfästelse är fel åt andra hållet, och det andra felet kostar kunden pengar — en katalysator på en sexårig bil offereras rutinmässigt som en betald reparation när den inte är det. Varje lagstadgad post bär källa och kontrolldatum: 2019/771 (2 år, säljaren — inte tillverkaren), MVBER 461/2010 förlängd till 2028, 715/2007 (5 år/100 000 km), 2024/1257 (8 år/160 000 km, batteri 80 % vid 5 år och 72 % vid 8), CAA § 207 (2/24 000 och 8/80 000 miles), Magnuson–Moss § 2302(c), CARB (3/50 000 och 7/70 000), ACC II (70 % SoH vid 8 år/100 000 miles). Bedömningen skiljer INOM, UTANFÖR och OKLART. Saknas underlag blir det oklart, aldrig utanför — att påstå att en garanti gått ut när underlaget inte räcker är det enda felet här som kostar kunden pengar. ---- Försäkring (ALVA-SPEC-041) ---------------------------------------- Modulen avgör ingenting och kan inte avgöra något. Vad som gäller bestäms av kundens eget försäkringsbrev och villkoren vid tecknandet — inte av vad ett bolag skriver i dag och inte av vad vi noterat. Testerna låser att resultatet inte innehåller något fält som liknar ett utfall, och att ett fordon utanför samtliga noterade gränser ändå inte får ett nej: registret kan vara ofullständigt och produkten en annan. Det som står överst är de sju villkoren som avgör en maskinskadefråga. Ålder och sträcka är två av dem; de fem andra avgör oftare. Registret med If, Folksam, Trygg-Hansa, Svedea, WaterCircles och Hedvig ligger under, med källa och avläsningsdatum per post, och märks som föråldrat efter 180 dagar i stället för att se aktuellt ut. ---- Felanmälan i ärendet (ALVA-PROC-0050) ----------------------------- En anmälningsknapp som bara finns i en portalvy nås aldrig av den som står med händerna i en bil. Den ligger därför i varje ärende, och tar med sitt sammanhang självt: ärende, metodik, plattformsversion och spår-id. Teknikern minns inte plattformsversionen, och att fråga efter den är att lägga över vårt problem på verkstaden. Sammanhanget HÄRLEDS och kan inte smugglas: ett regnr i anropet släpps inte igenom. En supportanmälan är inte ett skäl att flytta personuppgifter till ett annat system. Bevisat i integrationstestet. Anmälan är oföränderlig och statusen en projektion av inläggen — samma skäl som för fakturan: en anmälan vars historia kan skrivas om är inte ett underlag när någon frågar hur länge felet var känt. Verkstaden svarar i sitt eget ärende; status sätts av supporten med egen nyckel. ---- Historikkontrollen ------------------------------------------------- Kravet fanns redan: klienten öppnar inte metodiken förrän pre-diagnostiken är besvarad, och ett nej kräver skriven motivering. Det var dock aldrig BEVISAT att spärren håller. Genomgången prövar nu att metodiken inte går att nå medan historikfrågan står obesvarad — i det enda ögonblick det går att pröva, eftersom svaret därefter redan är avgivet. 429 enhetstester · 157 integrationskontroller mot riktig Postgres · genomgången 4/4 · portalspärren 16/16. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
b147694e31 |
Härdning av hela TÜV-revisionen
Tio av tolv fynd stängda, två reducerade med skälen utskrivna. Varje
stängning prövas av integrationssviten mot riktig Postgres — 144
kontroller, upp från 100.
T-1 Händelsenyckeln är nu (arende_id, id). Det finns inget delat
namnrum kvar att ockupera, så attacken saknar yta i stället för att
vara mildrad. Inom ett ärende bedöms en kollision på klientens
avtryck — en hash av det kanoniserade innehåll klienten skickade,
taget före serverns egna fält och före krypteringen, eftersom
varken raden eller nyttolasten går att jämföra. Identiskt innehåll
är fortfarande idempotent; samma id med annat innehåll ger 409 och
skriver ingenting alls, inte heller resten av satsen. Samma attack
en nivå upp — ärende-id är lika förutsägbart — stängs separat: ett
id som ägs av en annan organisation ger 409 i stället för att tyst
låta bli, vilket tidigare lämnade offrets ärende oskapat och varje
senare synk svarande 404.
T-2 Mätdonet slås upp i registret. Beteckning och kalibrering HÄRLEDS
därifrån och skriver över det klienten skickade. Okänt mätdon ger
400. Utgånget avvisas inte — mätningen gjordes — men registrets
datum följer med, så graderingen faller på registrets uppgift. Ett
mätvärde utan mätdon får sina påstådda uppgifter borttagna.
T-3 Reducerad, inte stängd. Personnycklarna kuverteras under en
huvudnyckel utanför databasen. En återställd dump ger nycklar som
inte öppnas — verifierat genom att starta om utan huvudnyckeln. Vad
som återstår står utskrivet: en backup tagen FÖRE en radering, plus
huvudnyckeln, återställer fortfarande uppgifterna.
Därtill: gallringen verkställs nu av ett eget jobb och grupperar på det
blindade fordonsindexet så att en delad nyckel inte gallras för tidigt
(T-4) · AI-avlästa mätvärden bär härkomst (T-5) · bcrypt kostnad 12
(T-6) · åtkomstloggen och raderingsregistret är append-only, med en
smalare regel för personnycklarna som måste kunna förstöras (T-7) ·
åtkomstloggen dokumenterad (T-8) · ett externt regelpaket utan signatur
spärrar avslut (T-9) · CORS faller inte längre öppet (T-10) · exp krävs
i token (T-11) · react-router 7 (T-12, med den kvarvarande avvikelsen
motiverad).
Den motspelande hyresgästen som revisionen efterlyste finns nu som
testform och körs i CI.
---- Vad härdningen själv avslöjade -----------------------------------
Två av rättelserna var kortvarigt fel på samma sätt som fynden, och
bägge fångades bara av att jag försökte bevisa dem:
T-7-testet var grönt mot en TOM tabell. En radnivåtrigger har inga
rader att fyra på, så delete lyckades och kontrollen mätte ingenting.
T-6-testet påstod anropet, inte kostnaden. toContain("gen_salt('bf')")
hade accepterat kostnad 6 för evigt — och gjorde det, så länge det
fanns.
Bägge är mönstret revisionen namngav: en kontroll som är riktig i sina
egna termer och oprövad vid sin gräns. Det gäller tester lika mycket som
kod.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
|
||
|
|
0833a573e0 |
TÜV-revision: bred granskning av hela systemet
Frågan var inte om mekanismerna fungerar — de gör det — utan om ett
underlag från systemet skulle överleva en granskning. Svaret är nej, av
tre skäl, och inget av dem är ett fel i det som de två föregående
revisionerna härdade.
T-1 En organisation kan tyst hindra en annan från att skriva historik.
Händelse-id sätts av klienten och är förutsägbart, primärnyckeln är
global, och insert sker med `on conflict do nothing`. Org B kan
ockupera id på SITT EGET ärende som org A senare kommer att använda.
Reproducerat: org A:s felorsak försvann, servern svarade 200.
Append-only skyddar det som skrivs. Ingenting skyddar det som
hindras från att skrivas.
T-2 Mätkedjan är självpåstådd. Mätdonsregistret finns, är välbyggt och
konsulteras aldrig. Reproducerat: en organisation utan ett enda
registrerat mätdon skickar matdonId "finns-inte-i-registret" och
kalibrering 2099-12-31 — lagras oprövat, och evidensen graderas E4.
T-3 Raderingen är inte varaktig. Krypto-shreddingens nyckel ligger i
samma databas som chiffertexten, och återställningstestet slår
uttryckligen fast att nycklarna följer med en återställning. Testet
har rätt för katastrofåterställning — det är samma faktum läst åt
andra hållet som bryter raderingslöftet.
Därtill fyra allvarliga: gallringsdatumet skrivs men läses aldrig av
någon, AI-avlästa mätvärden saknar härkomst, lösenordshashen är bcrypt
kostnad 6 (pgcrypto-standard, verifierat), och åtkomstloggen och
raderingsregistret är de enda underlagen UTAN append-only-skydd.
Gemensamt för de tre kritiska: var och en är osynlig för en grön svit,
och av tre olika skäl. Det är revisionens egentliga utfall, och därför
föreslås en motspelande hyresgäst som testform.
Varje fynd reproducerat mot riktig Postgres och en riktig serverprocess.
Inget rapporteras som inte gick att återskapa.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
|
||
|
|
d1b361573e |
Faktureringens serverdel — och två fel den grävde fram
Fakturering fanns som modell, vy och tester men aldrig som något en
server kunde utfärda. Nu finns tabellerna, vägarna och gränsen mellan
kund och utfärdare.
Beloppet tas aldrig emot. Det härleds ur organisationens faktiska
tillstånd — de konton som verkligen kan logga in, de moduler som
verkligen är påslagna — och ett anrop som ändå skickar rader eller
totalt avvisas med 400 i stället för att tigas ihjäl. Samma hållning som
mot okända fält i händelseschemat.
Fakturaraden är oföränderlig, skyddad av samma trigger som loggen. Det
får en följd som är lätt att missa: "betald" kan då inte vara en kolumn
som uppdateras. Betalningen är en egen händelse och statusen en
projektion av händelserna. En felaktig faktura rättas inte heller — den
bemöts av en kreditfaktura med omvänt tecken och ett granskbart skäl.
Utfärdaren är inte en användare. Ingen av rollerna i en verkstad är
motpart i avtalet, så en kunds administratör kan varken utfärda sin egen
faktura eller bokföra den som betald; utfärdandet kräver en egen nyckel,
och utan den i miljön utfärdas ingenting alls. Nummerserien är utan
luckor — en sequence hade varit billigare men lämnar hål vid rollback,
och ett underlag med hål i är en lista.
---- Vad som föll ut när sviten faktiskt kördes ------------------------
integrationstest.sh fanns men låg utanför CI, och den föll på andra
raden — i kod som inte hade med fakturering att göra:
C-7 Append-only-triggern på felsokning_arenden förbjöd ALL update. Två
av radens kolumner är härledda efteråt: gallringsdatumet vid avslut
och det blindade fordonsindexet. Alltså föll varje avslut med 500,
efter att kvalitetsgrinden redan godkänt ärendet. Skyddet är nu
kolumnvis: identitet och ursprung är fortfarande låsta, radering
fortfarande omöjlig, men de fält systemet självt härleder får
skrivas.
C-8 Fordonshistoriken sökte i klartext efter en identifierare som
krypteras i vila. Jämförelsen kunde aldrig träffa: historiken
svarade tomt på varje fordon, med 200. Det blindade indexet fanns
just för den frågan och var aldrig inkopplat.
Bägge ligger i backenden till produktens centrala löfte — att ett
avslutat ärende är ett varaktigt underlag — och ingen av dem kunde synas
i en grön enhetssvit, eftersom ingen av dem kan falla utan en databas.
Sviten är därför ett eget CI-jobb nu.
Bevisad: 364 enhetstester, 100+ integrationskontroller mot riktig
Postgres, genomgången 4/4 ärenden. Spärren mot angivet belopp
mutationstestad — borttagen ger den 201 i stället för 400.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
|
||
|
|
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 |
||
|
|
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 |
||
|
|
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 |
||
|
|
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
|
||
|
|
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
|
||
|
|
610bb9eca6 |
ALVA: metoden i kod — faser, nomenklatur, statusspråk, komponenter
ALVA är inte en omdöpning utan en annan produktklass. Skillnaden mellan en assistent och en metod är att metoden går att granska, och därför ligger den i kod och i test, inte i marknadsföringen. Språkgränsen är den bärande avgränsningen: ALVA:s STRUKTUR är engelsk och oföränderlig — fasnamn, statusord, dokumenttyper, identifierare skrivs likadant i varje land, precis som DIN 2014 heter DIN 2014 på svenska. ALVA:s INNEHÅLL är på arbetsspråket: frågan till teknikern och kontrollpunktens text är svenska i en svensk verkstad. Att översätta VERIFICATION till Verifiering hade gjort ALVA till ett ord för samma sak i varje land i stället för samma sak i varje land. Faserna är tillämpade på metodikbiblioteket, inte påklistrade: alla 31 steg-id i de 16 metodikerna är klassificerade i data. Gränsen mellan L och V är den enda svåra och bär hela metoden — att mäta spänning vid en komponent avgränsar var felet finns, att mäta spänningsfall under last fastställer varför. Regeln: ett steg är Verification när det kan avfärda en kandidatorsak. Ett test kräver att faserna kommer i ALVA-ordning inom varje metodik. Ett annat slår fast att en metodik inte behöver innehålla alla fyra — läckagemetodiken slutar med lokalisering, och att fylla ut modellen med ett konstruerat Action-steg hade varit att tillämpa den slarvigt. Statusspråket är en uttömmande katalog, låst av test: inga utropstecken, inget tilltal, varje rad slutar med punkt. Bedömning uttrycks som ett tal — Confidence level: 92% — aldrig som Jag tror. Skillnaden är produktens existensberättigande: det ena är en person som gissar, det andra ett mätvärde som går att ifrågasätta. Komponentbiblioteket är ett, för både webbplats och portal. 8 px-rutnät utan undantag, nästan monokromt, ALVA Blue bara för aktivt steg och verifierad status. Fyra ikoner: ✓ ○ □ →. Ingen animation — rörelse som inte bär information är brus i ett utrymme där teknikern redan har för mycket. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
fbc034a280 |
Revisionen: C-3, C-4, M-1, M-4, M-5, M-6, m-3, m-5 och m-7 åtgärdade
C-3 · Dataskydd genom krypto-shredding. Identifierande fält krypteras med en nyckel per ärende; radering sker genom att nyckeln förstörs. Loggen förblir intakt och hashverifierbar — det som blir oåtkomligt är identifieringen, inte protokollet över vad som kontrollerades. Ett raderat ärende visar fortfarande att lufttrycket mättes till 2,4 bar klockan 08:42, bara inte längre vems bil det gällde. Vad som inte krypteras är lika viktigt: mätvärden, observationer och kontrollresultat är verksamhetsdata. Krypteras allt raderas beviset tillsammans med personuppgiften. En raderingsbegäran gäller ett fordon, inte ett ärende — men identifieraren är krypterad och går inte att söka på. Därför ett blindat index: HMAC av den normaliserade identifieraren, samma fordon ger alltid samma värde, värdet går inte att vända tillbaka utan nyckeln. Gallringsdatum sätts vid avslut utifrån ärendetypen. Ett ärende utan datum gallras aldrig — för tidig gallring går inte att ångra. C-4 · Modellanropen kan stängas av per organisation. Flaggan bärs i token så orkestern kan neka utan databasåtkomst. Metodikmotorn fungerar ensam; en verkstad som inte kan acceptera överföringen till modelleverantören kan ändå använda produkten. M-1 · Mätvärden bär vilket mätdon som användes och när det var kalibrerat. Utan spårbart instrument nedgraderas värdet från E4 till E1 — det är teknikerns observation av en siffra, inte en mätning. Kalibreringen bedöms vid mättillfället, inte i dag. Demoärendet fick kalibrerade instrument: det ska visa den praxis produkten kräver. M-4 · Läslogg. Varje skrivning loggades redan; ingen läsning gjorde det. M-5 · Återställningstest i CI. Larmet visade att backup sker, inte att den går att återställa. Testet kontrollerar det som faktiskt brukar tappas: att append-only-triggarna följde med och fortfarande biter. M-6 · Regelpaketet verifieras mot HMAC. Ogiltig signatur spärrar avslut; saknad nyckel ger granskningsläge i stället för driftavbrott — det är så säkerhetsfunktioner blir avstängda. m-3 · EXIF-borttagningen är nu avsiktlig och låst av test. Den höll av en slump, och en ändring i stil med "bevara originalkvaliteten" hade tyst börjat publicera var kundens bil stod. m-5 · SBOM och sårbarhetsskanning i CI. m-7 · Promptversionen binds till varje svar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
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 |
||
|
|
1bb40319d8 |
Metodikbiblioteket: 16 metodiker som täcker fordonets system
Tre metodiker räckte för att visa principen men inte för att arbeta.
Biblioteket flyttas till en egen fil och växer till sexton: vibration,
bromsar, styrning/fjädring, elsystem, start & laddning, motorgång,
kylsystem, drivlina, avgas & emission, klimat, högvolt, felkoder &
kommunikation, läckage, missljud, ADAS — plus generisk.
Att "täcka allt" går inte att lova. Det som går är att täcka systemen
systematiskt och låta generisk vara ett strukturellt komplett skyddsnät
för det ingen förutsett.
Tre regler gäller alla metodiker, och alla tre är låsta av test:
1. Varje kontroll har ett minimikrav — mätvärde, foto eller
observation. En kryssruta är inte evidens.
2. Varje metodik börjar med att verifiera symptomet, aldrig med att
åtgärda. Kundens ord blir ett symptom först när det reproducerats.
3. Där arbetet kan skada någon ligger säkerhetssteget först.
Högvoltsmetodiken kan inte påbörjas utan dokumenterad
spänningsfrihet, urtagen servicebrytare och skyddsutrustning —
det arbetet kan döda, och en kryssruta duger inte.
Motorn och innehållet skiljs åt: metodik.ts äger typer, val och
härledningen av nästa steg, metodiker.ts äger metodikerna. Biblioteket
kan växa utan att motorn ändras.
Valet av metodik är inte längre en regexkedja utan poängsatt på
nyckelord, där det längre — mer specifika — ordet väger tyngre:
"traktionsbatteri" slår "batteri". Korta ord matchas som helt ord,
längre som ordstam, annars hade "ac" träffat "acceleration" och en
vibration hamnat i klimatanläggningen. Nyckelorden är stammar, inte
färdigböjda ord: svensk böjning kapar ofta ett e (filter → filtret), så
"partikelfilter" hade aldrig matchat texten teknikern faktiskt skriver.
Valet är en frågeordning, inte en diagnos. Träffar inget blir det
generisk — ett ärligt "vi vet inte var vi ska börja" i stället för en
gissning — varefter orkesterns klassificerare får försöka.
Orkesterns metodikkatalog byggs nu ur en lista i stället för att räknas
upp i både schema och prompt, i båda kopiorna (ai-orkester och
edge-funktionen). Ett test jämför den mot klientens: glider listorna
isär returnerar klassificeraren ett id klienten inte känner igen, och
valet faller tyst tillbaka på generisk.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
|
||
|
|
69a519be75 |
Observation: se var tiden går, utan ett enda nytt beroende
CloudWatch gav loggar och mätvärden men svarade inte på frågan man faktiskt har när något är långsamt: var tog tiden vägen. Tjänsterna har medvetet nästan inga beroenden — plattformen har pg-drivrutinen, orkestern har Claude-klienten. Att dra in ett OpenTelemetry-SDK med trettio paket för att mäta fyra saker vore fel avvägning. I stället två standarder som båda bara är text på stdout: W3C Trace Context. Klienten startar spåret och traceparent följer med genom plattformen till orkestern, så en teknikers handling går att följa hela vägen till modellsvaret i stället för att bli två orelaterade spår. CloudWatch EMF. Strukturerad JSON som CloudWatch själv extraherar mätvärden ur — ingen agent, ingen SDK, inget som kan sluta fungera tyst. Varje anrop ger en loggrad med nedbrytning av tiden per del: databasen, modellanropet, objektlagringen, kundens leverantör. Det svarar direkt på om ett långsamt ärende beror på S3 eller på Opus-granskningen, i stället för att någon ska korrelera fem loggrader. Vägen normaliseras innan den blir dimension, och organisation, ärende-id och spår-id blir aldrig dimensioner — varje unik kombination är en egen tidsserie som kostar. De ligger som vanliga fält, sökbara i Logs Insights. Ett test låser det, eftersom det är precis den sortens sak som smyger in senare. Tre larm på det teknikern märker: svarstid p95 över tre sekunder (medelvärdet döljer att var tjugonde tekniker väntar orimligt länge), serverfel med spår-id i loggraden, och att modellen avböjer — det senare tyder på att underlaget innehåller något oväntat, inte på ett driftfel. Modulen är delad mellan tjänsterna i stället för duplicerad. Byggkontexten flyttas därför till felsokning/services, och en symlänk gör att testerna och integrationstestet kör mot samma fil som bilderna. Verifierat: 106 vitest-tester (10 nya för spårning, EMF-format och att dimensionerna hålls få), typkontroll, eslint på klient och tjänster, rotens CI, terraform fmt och referenskontroll på båda lagren, samt integrationstest mot riktig Postgres där spårraderna syns live. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
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
|