c334786bb30347e49386c7223de613e3ee348b7e
25 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6665004ec7 |
Härdning: kedjesvep i drift — och svepets första egna fynd
KEDJESVEPET. Verifieringen fanns men anropades bara vid tvist: ett brott kunde stå oupptäckt i åratal och upptäckas i sämsta tänkbara ögonblick. Nu går driften igenom varje kedja och varje försegling i varje organisation — POST /api/kedjesvep för arbetsledaren, `node server.mjs --kedjesvep` för nattlig cron utan server, med felkod vid brott så att larmet är gratis. Endpoint och svep delar EN implementation (kedjestatus): två implementationer av "är kedjan hel?" kommer att svara olika den dag det betyder något — det var T-13/T-14:s rot, tillämpad i förebyggande syfte. SVEPETS FÖRSTA FYND VAR PÅ RIKTIGT. Första körningen mot integrationsmiljön rapporterade TRE brott där testerna saboterat två. Det tredje var en bugg: leverantörshändelser bär `enhet: undefined`, och den kanoniska formen serialiserade nyckeln som null medan databasens rundresa släpper den. Skriv-digest och läs-digest skilde sig — varje leverantörshändelse bröt sin egen kedjelänk. Klienthändelser gick fria av en slump: JSON.parse kan inte producera undefined. Fixat vid roten: kanonisk form är nu exakt den form som överlever rundresan, inte en nästan likadan. Mekanismen fungerade precis som avsett — dag ett, mot sina egna upphovsmän. TRANSPORTEN. Säkerhetshuvuden på varje API-svar: nosniff, no-store (ett API vars svar är personuppgifter får inte bli en cacheträff), frame-ancestors 'none', no-referrer, HSTS. För stor kropp svarar 413 i stället för ett intetsägande 500. Kroppstak 4 MiB och batchtak 500 verifierade som redan på plats — bokfört, inte antaget. En skriptläxa på vägen: cron-svepets felkod är själva poängen, men under `set -e` dödade den testskriptet vid tilldelningen — felkoden måste fångas i samma andetag. Utgåva 3.4. API-specen dokumenterar svepet. TÜV-2-rapporten har bilaga A med samma-dags-härdningen, inklusive svepets eget fynd. 768 enhetstester, 224 integrationskontroller mot riktig Postgres, återställningsprov, genomgång 4/4, portalspärr, typkontroll och lint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
c1c56e60b5 |
TÜV-revision 2: fyra nya fynd — två Major med samma rot
Uppföljning först: alla tolv fynd från första ronden omprövade utan regression. T-4 noteras med gillande — gallringen förstör nycklar, inte rader, och kolliderar därför varken med append-only-triggarna eller den nya kedjan. Mekanismerna komponerar utan specialfall. T-13, MAJOR. Säkerhetstaket räknade varje mätvärde med matdonId som spårbart. Registeruppslaget härleder kalibreringsdatumet men stämplade aldrig OM kalibreringen gällde vid mottagandet. Ett instrument vars kalibrering gick ut 2019 kunde alltså bära taket "hög" — samtidigt som evidensmodellen graderar samma mätning E1, "kalibrering saknas eller utgången". Systemets två omdömen om samma faktum motsade varandra, och det generösare styrde grinden. Den uppenbara fixen — jämföra datumet mot klockan vid grindprövning — är fel: samma logg ska ge samma utfall om tio år. Faktumet fryses i stället när det fortfarande är ett faktum: mätdonsFakta stämplar kalibreradVidMatning vid mottagandet, taket kräver stämpeln, och klientens eget påstående skrivs alltid över. Strikt bakåt: ett ostämplat mätvärde räknas inte — det som inte kan styrkas bär inte hög. T-14, MAJOR. Leverantörsprotokollet gick förbi mätdonsregistret. T-2 stängde teknikerns väg; en leverantörsprofil kunde fortfarande stämpla in vilket matdonId som helst — T-2 återuppstånden genom sidodörren, och efter T-13 hade det opverifierade påståendet dessutom matat taket. Granskarens mönsternotering: kontrollen infördes vid grinden där fyndet gjordes, inte vid resursen den skyddar — andra gången i kodbasen (grinden själv var en gång enbart klient). Åtgärd: varje protokollmätvärde passerar registret. Okänt instrument NEDGRADERAS i stället för att avvisas — en webhook kan inte registrera instrumentet på plats, och att kasta evidensen vore värre än att gradera den ärligt. Värdet behålls, matdonspåståendena stryks, nedgraderingen redovisas i svaret. T-15, minor. Oförseglad drift syntes bara som en loggrad per avslut. Nu varnar tjänsten vid start — en rad vid boot är ett beslut någon fattat, en rad per avslut är brus — och miljövariabeln är dokumenterad. T-16, minor. Återställningsprovet var skrivet före kedjan: det bevisade att rader överlever en dump, ingenting om sekvens, kedjehash eller försegling — en backup som tappar kedjan återställer en logg som aldrig mer verifierar. Provet var grönt medan det mätte fel sak, vilket första ronden två gånger utpekade som den farligaste sortens grönt. Utökat: länkar, ordning och försegling överlever, och omförsegling avvisas även i den återställda databasen. Under arbetet: en sökväg i patchskriptet matchade aldrig därför att avtryckets avskiljare är NUL-bytes — ersättningen rapporterade ok utan att ha gjort något, och bara integrationstestet avslöjade det. Fixen applicerades om med assert på träff. Samma läxa som T-16, i verktygen. 768 enhetstester, 213 integrationskontroller, återställningsprov, genomgång 4/4, typkontroll, lint gröna. docs/TUV-AUDIT-2.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
0941e53c50 |
Revision 3: härdningen granskad — fyra fynd i en dag gammal kod, alla åtgärdade
Revisionens föremål är hashkedjan, förseglingen och säkerhetstaket från igår. Skälet att granska det nyaste först: det farligaste ögonblicket för en skyddsmekanism är veckan efter att den byggts, när testerna är skrivna av samma person som skrev mekanismen och provar samma antaganden. K-1, KRITISK. Förseglingen larmade falskt i normal drift. Offline-synk kan lämna in händelser EFTER att ärendet stängts — en sen bild, ett sent kundbesked — och verifieringen jämförde förseglingens rot med kedjans NUVARANDE rot. Varje legitim efterhändelse gav OGILTIG. Reproducerad i integrationsmiljön innan den kallades fynd. En verifiering som larmar falskt avfärdas snart som trasig, och därefter avfärdas även de äkta larmen — falsklarmet är inte en mindre bugg i ett skydd, det är det som dödar skyddet. Åtgärd: förseglingen täcker sitt PREFIX. Den förseglade roten ska vara en länk i den omräknade kedjan; det som kom efter redovisas öppet i `efterForsegling` i stället för att smittas eller smitta. Motvikten är prövad: sabotage INUTI prefixet fäller fortfarande både kedjan och förseglingen — annars vore "täcker sitt prefix" bara ett artigare ord för "täcker ingenting". m-1. Kedjelänken vilade på ett tidsformat som garanterades tre filer bort. Inte utlösbart i dag — alla vägar går genom tillPost — men första nya skrivväg utan millisekunder hade gett en kedja som aldrig verifierar. Normaliseringen bor nu i skrivKedjat, i samma uttryck som länken och databasraden får den ur. m-2. Protokollvägens skrivna/dubbletter räknades med två count(*) runt anropet; en samtidig skrivning från någon annan hamnade i vår siffra. skrivKedjat returnerar nu räkningen ur transaktionen som gjorde jobbet. m-3. Läsordning och kedjeordning var två ordningar. Kedjan ordnas av sekvens; GET, grinden och delningsvyn sorterade på tidpunkt och id — inom en batch kunde id:ts bokstavsordning avgöra vilken händelse som var "senast". Alla läsvägar sorterar nu i kedjeordning. Granskat utan anmärkning, bokfört så nästa revision vet att "hittade inget" betyder "letade": numerisk rundresa genom jsonb (provad med 1e-7 och 0.10000000000000009, inte antagen), dubbletter flyttar inte kedjan, krypto-shredding mot kedjan, signaturens serverägdhet, takets monotoni. Mönstret i alla fyra fynd är detsamma och står i rapporten: testerna som skrevs med mekanismen provade manipulation, som är det man tänker på när man bygger ett skydd. Det som gick sönder var normal drift — sen synk, samtidiga grannar, en batch i samma millisekund. Skydd fallerar oftare genom att larma falskt än genom att missa angrepp. 766 tester, 206 integrationskontroller, genomgång 4/4, portalspärr, typkontroll, lint och artefaktmätning gröna. API-specen dokumenterar prefixsemantiken och efterForsegling. docs/QUALITY-AUDIT-3.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
1ba5aaaefa |
Härdning efter panelgranskningen: kedjad logg, förseglat avslut, härledd säkerhetsnivå
Fyra av granskningens fynd åtgärdade, i bevisvärdesordning. HASHKEDJAN (ALVA-SPEC-070). Triggrar skyddar loggen mot applikationen, inte mot den som äger databasen — det var granskningens allvarligaste invändning mot ett system vars hela värde är bevisvärde. Varje händelse bär nu en hash av sitt innehåll och föregående händelses hash, beräknad av servern vid insättningen. All skrivning går genom en enda kedjande funktion; en händelse vid sidan av kedjan är ett hål i beviset, så den bekväma vägen förbi finns inte. Digest tas över den LAGRADE händelsen, efter kryptering: verifieringen ska kunna räkna om den ur databasen för all framtid, och krypto-shredding förstör nycklar, inte rader, så kedjan överlever en radering. Radlås per ärende hindrar att två samtidiga batchar forkar kedjan — en falsk larmande verifiering avfärdas snart som trasig, och då är den värdelös. Integrationstestet provar hotmodellen ordagrant: triggern släpps, en rad ändras med full databasbehörighet, triggern återskapas. Verifieringen pekar ut raden — inte bara att något är fel, utan vilken. FÖRSEGLINGEN. Avslut skriver kedjans rot och en HMAC med en nyckel som aldrig finns i databasen, i samma transaktion som avslutshändelsen. Den som räknar om hela kedjan efter sin ändring stoppas av att förseglingen inte går att räkna om utan nyckeln. Engångs: triggern vägrar ändra en satt försegling. Svaret säger vad det bevisar och inte — innehållet är oförändrat sedan mottagandet, ingenting om tiden före, ingenting om sanningshalten. Den texten följer med in i varje rapport som citerar svaret, för det är precis den skillnad en motpartsjurist annars hittar. SIGNATUREN. Fältet hette signatur men var teknikerns egen text — det inbjöd en jurist att tro något som inte gällde. Det skrivs nu ur verifierad token som övriga härkomstfält och intygar exakt vad det kan intyga: vem som var inloggad när avslutet togs emot. SÄKERHETSNIVÅN (ALVA-SPEC-071). Var teknikerns fria val — ett självskattat värde som ser ut som en mätning. Nu ett tak härlett ur underlaget: hög kräver reproducerat symptom OCH spårbart mätvärde ur mätdonsregistret; enbart observationer bär inte ens medel. Teknikern kan sänka men aldrig höja — asymmetrin är poängen, ärlig osäkerhet är information. Grinden spärrar påståenden över taket på alla tio språken, och gränssnittet visar taket medan arbetet pågår i stället för att spara beskedet till avslutsknappen. "Delvis reproducerat" bär inte hög: delvis är ett annat ord för att felet inte är förstått. Taket bet direkt i två av våra egna testfixturer som påstod hög utan spårbart mätdon — vilket är regeln som fungerar, inte testet som är fel. Genomgången avslöjade följdkravet: vid medel/låg kräver panelen att teknikern anger vilka ytterligare kontroller som skulle stärka bedömningen, och det fältet fylls nu i som en tekniker skulle. Kvar ur granskningens lista, medvetet: extern förankring (RFC 3161), klienthashat foto vid upptagning, gränsvärden som data, OIDC/SAML. 766 tester, 200 integrationskontroller mot riktig Postgres — inklusive sabotage som databasägare — genomgång 4/4, portalspärr, typkontroll, lint och artefaktmätning gröna. Utgåva 3.3, API-specen uppdaterad, åtgärderna bokförda i panelrapportens bilaga A. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
93780894d6 |
Panelgranskning: extern stresstest av ALVA 3.2
En simulerad expertpanel — femton säten från tillverkare, verkstad, garanti, försäkring, besiktning, konsument, forskning, HMI, säkerhet och utbildning — har granskat produkten mot åtta kriterier och lämnat betyg och slutrapport. Varje fynd är kontrollerat mot koden innan det skrevs ned. Det ändrade tre av dem: härkomsten är starkare än panelen antog (`anvandare` och `tidpunkt` är serverägda fält, inte klientens påstående), fotot bär avsiktligt ingen metadata alls (EXIF-borttagningen är en provad säkerhetsegenskap, inte ett förbiseende), och kalibreringen härleds ur mätdonsregistret i stället för att påstås. De fyra tyngsta fynden: SIGNATUREN ÄR ETT NAMN. `arende_avslutat` bär `signatur: anvandare` — teknikerns egen text. Händelsens härkomst är serverbunden och håller, men ett fält som HETER signatur och inte är en signatur inbjuder en jurist att tro något som inte gäller. Mellanläget är sämre än att inte ha fältet. INGEN KRYPTOGRAFISK KEDJA. Manipulationsskyddet vilar på databastriggrar. De skyddar mot applikationen, inte mot den som äger databasen. För ett system vars hela värde är bevisvärde är det den allvarligaste bristen. INGA GRÄNSVÄRDEN. `matvarde` bär beskrivning, värde och enhet. Ingenting jämförs mot ett börvärde. "38 g mot gränsen 10 g" är fritext teknikern skrivit — systemet vet inte vad gränsen är och kan inte upptäcka att teknikern har fel om den. FOTOT BEVISAR INTE UPPTAGNINGEN. `capture="environment"` är en hint, inte en spärr, och metadata tas bort. Kravet att mätarställningen ska fotograferas — produktens skarpaste enskilda regel — vilar därmed på hederlighet, inte på bevisning. Panelen enades om lösningen: hasha i klienten, låt servern signera hash och mottagningstid. Integritet bevaras, och rapporten säger vad förseglingen faktiskt bevisar. Slutsatsen om standardisering är den viktigaste och den är obekväm: produkten är en IMPLEMENTATION, inte en SPECIFIKATION. Specdokumenten lever inne i kodbasen och är inte separerbara från just den här koden. En standard kräver ett normativt dokument, en konformanstestsvit som en tredje part kan köra mot sin egen implementation, och minst två oberoende implementationer. Det som däremot ÄR standardiserbart är evidensmodellen E0–E6 och ALVA-RULE-200:s fyra fält — alltså en standard för bevisningen, inte för diagnostiken. Metodikinnehållet hör hemma hos tillverkaren och bör uttryckligen hållas utanför. Betygen: utbildningsvärde 8,5 högst, OEM-anpassning 3,8 lägst. Samma observation från två håll — produkten är stark där den handlar om hur man tänker och svag där den handlar om vad man ska göra med en viss bil. Dokumentet är märkt som en intern övning. Sätena är rollbeskrivningar och ingen namngiven organisation har deltagit; det står först i filen så att den inte kan spridas som ett branschutlåtande. 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 |
||
|
|
86558120e4 |
Systembeskrivning: vad ALVA är, vad som finns, vad som inte finns
Underlag för att resonera vidare utan att ha varit med när det byggdes. Siffrorna är räknade ur källkoden, inte uppskattade: 17 metodiker, 48 händelsetyper, 39 API-vägar, 18 tabeller, 24 testfiler, radantal per del. Mognadsavsnittet skiljer på bevisat och öppet, och listar det öppna i klartext — abonnemangsmodellen finns inte, Terraform är beskrivet men inte applicerat, Impressum har sin struktur men inga uppgifter, T-3:s backupfönster är inte stängt. En beskrivning som utelämnade det vore säljmaterial, inte underlag. 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
|
||
|
|
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 |
||
|
|
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
|
||
|
|
86d553b639 |
Kör ALVA:s tester i CI, och genomgången som incheckat test
CI körde `npm test` i roten, som delegerar till workspaces. Listan är apps/mobile, services/api och infra — felsokning/app står inte där. Pipelinen körde alltså 30 tester från en orelaterad tjänst och inte ett enda av ALVA:s 311. Varken lint eller typkontroll nådde produkten heller. Det är inte att testerna föll. Det är att ingenting upprätthöll dem. Varje garanti som de två revisionerna skrivit som "låst av ett test" — härkomsten, kvalitetsgrinden, raderingen, mätdonsspårbarheten, högvoltsspärren, det stängda schemat, driftskydden mellan klient och grind — låstes av tester som ingen pipeline körde. De höll därför att en person körde dem för hand före varje commit. Det är en person, inte en spärr. Två nya jobb. `alva` kör produktens lint, typkontroll och hela sviten mot sin egen lockfil. `genomgang` installerar Chromium och kör fyra ärenden genom det byggda gränssnittet. Genomgången kontrollerar tre saker: att varje ärende når avslutat läge, att varje händelse klienten faktiskt producerar passerar det stängda schemat, och att interaktionerna per ärende håller sig under 90. Bägge felvägarna är provade, inte antagna — sänkt budget fäller tre fall, och ett schemafilter som avvisar allt fäller fyra. En kontroll som inte kan falla är dekoration. Skriptet bygger appen själv med de två miljövariabler bygget kräver. Lämnas det åt den som startar kommandot testar genomgången tyst en annan applikation: utan hash-routing matchar ingen route, och utan platshållare för den gamla butiksklienten kastar den innan routern monteras så att sidan blir tom. 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 |
||
|
|
e6b57d59e5 |
Leverantörsrevision 2 av ALVA
Granskar det som byggts sedan revision 1 stängdes: ALVA-metoden och designsystemet, slutsatsen (ALVA-RULE-200), driftmåtten (ALVA-REP-0100), den härledda sammanfattningen (ALVA-PROC-0030) och integrationsytan (ALVA-SPEC-020/021). Ett kritiskt fynd. Händelseschemat är öppet — granskaHändelse itererar schemats nycklar, aldrig händelsens — så okända fält accepteras och sparas ordagrant. Två garantier som revision 1 stängde vilar på motsatsen: personuppgifter på en vanlig observation krypteras aldrig och överlever därför raderingen, och delningsfiltret är typnivå, inte fältnivå, så fälten når kundens delningslänk. Reproducerat mot de delade modulerna, inte påstått. Komplikationen är att öppenheten är bärande: protokollinläsningen hänger `kalla` på varje händelse, och `kalla` finns inte i schemat. Tre allvarliga. Klientens avslutsvillkor har glidit från grinden två gånger sedan C-2 stängdes, och ingen av gångerna fångades av 293 tester — bara av att köra tio ärenden hela vägen. Protokollinläsningen tappar händelser tyst på tre sätt. Genererade webhookhemligheter går aldrig att få ut, så leveranssignaturen kan aldrig verifieras. Tre mindre, varav ett är mitt eget från i dag: ett mätvärde som kommer ur en kontroll redovisas två gånger i rapporten. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
03fbea8fac |
Revisionen: m-4 och m-6 — de två som bara går att stänga delvis
m-6 · Tillgänglighetstester med axe på verkstadsgränssnittets grundkomponenter: knapp, textfält, panel och bild. Gränssnittet var genomtänkt för handskar, buller och solljus men obevisat — ingenting kontrollerade att en knapp har ett tillgängligt namn eller att ett formulärfält har en etikett. Att bilder bär alternativtext är i den här produkten inte bara ett tillgänglighetskrav: bilden *är* bevisningen, och beskrivningen är det som säger vad den visar. Ungefär en tredjedel av WCAG går att kontrollera maskinellt. Testet säger det rakt ut, och den manuella granskningen står kvar som öppen — automatik hittar inte om ett gränssnitt är användbart, bara om det är felformat. m-4 · Paritetstestet mellan orkesterkopiorna jämför nu innehåll i stället för att kontrollera att strängar förekommer: grundreglerna ord för ord, metodikkatalogens id i ordning, och modellvalet per uppgift. Ett substrängtest hade inte fångat att en grundregel ändrats i ena kopian. Den riktiga åtgärden är att avveckla Supabase-vägen. Det är ett driftbeslut, inte en kodändring, och står kvar som öppet. Revisionsdokumentet har fått en avdelning med utfall per fynd, så att en omgranskning kan verifiera i stället för att lita på ordet. Två punkter är ärligt öppna och ingen av dem är kod: personuppgiftsbiträdesavtalet med konsekvensbedömning, och avvecklingen av den äldre orkestern. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
cdb3320c4a |
Kvalitetsrevision ur en OEM-kunds perspektiv
En genomgång av koden — inte av dokumentationens påståenden — med den granskning en fordonstillverkares leverantörskvalitet skulle göra. Dokumentet säger uttryckligen att det är en intern övning med Volkswagen AG som referenskund, inte en revision utförd av eller på uppdrag av dem. Fyra kritiska fynd, varav två underminerar produktens kärnlöfte: Servern tar emot anvandare och tidpunkt från klienten och kontrollerar bara att de är strängar respektive sanningsvärda. JWT:n bär redan den verifierade identiteten men används inte på den vägen. En append-only logg vars författare och tidpunkt sätts av anroparen är inte en revisionskedja. Kvalitetsgrinden finns bara i webbläsaren. Ett ärende kan avslutas utan evidens genom ett anrop till API:t, och rapporten presenterar det som komplett. Dokumentationen säger att systemet aldrig kan skriva en slutsats ECM inte godkänt; det stämmer inte vid API-gränsen. De två övriga är rättsliga: append-only utan raderingsväg går inte att förena med dataskyddsförordningens artikel 17, och överföringen av kunduppgifter och VIN till modell-API:t saknar dokumenterad grund. Sex allvarliga fynd, bland dem att mätvärden rankas som hög evidens utan att bära vilket instrument som mätte eller om det var kalibrerat, och att högvoltsteget går att svara nej på och ändå fortsätta. Dokumentet listar också det som håller — och varför det bör skyddas i åtgärdsarbetet. En revision som bara räknar fel ger en falsk bild. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
031d6d5a3d |
All produktdokumentation på engelska som källa
De återstående dokumenten — VISION, MVP, DEMO, DRIFT och MASTER-PROMPT — får engelska versioner, och de svenska blir översättningar med samma notis som systembeskrivningen redan hade. DRIFT.md heter nu OPERATIONS.md; ett svenskt filnamn på ett engelskt dokument hade varit inkonsekvent. Dokumentationen är därmed 33 filer: sexton dokument med engelska som källa, sexton svenska syskon, och systembeskrivningen dessutom på tyska, danska och norska. Två fel hittades under översättningen, båda rättade i bägge språken: DRIFT.md pekade ut .github/workflows/ci.yml som Guidad Felsöknings CI och sa tre rader längre ned att samma fil tillhör Semantika och inte rörs. Det stämde innan CI flyttades till egen Gitea; rätt fil är .gitea/workflows/felsokning.yml. MVP.md kallade styrdokumentet Master Prompt v1.0 men länkade till v2.0. Att översätta ett dokument är den grundligaste läsning det får. Båda felen hade överlevt flera genomgångar av samma text på svenska. Kodidentifierare, miljövariabler, sökvägar och UI-etiketter står oöversatta i de engelska versionerna. Att skriva "Create demo case" i demomanuset hade gjort manuset obrukbart — knappen heter "Skapa demoärende". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
86efbaaca5 |
Moduldokumenten på engelska som källa
De åtta moduldokumenten och exempelflödet får engelska versioner. Kataloger och filnamn följer med: moduler/ → modules/, exempel/ → examples/, och de svenska filnamnen ersätts av engelska. Ett engelskt dokument i moduler/arendebrief.md hade varit inkonsekvent. Bytet gjordes med git mv så historiken följer med, och interna länkar i de svenska versionerna pekar nu på svenska syskon i stället för på filnamn som inte längre finns. Kodidentifierare och JSON-exempel står oöversatta även i de engelska versionerna — falt, hemlig, uppslag och svarsfalt är fältnamn i integrationer.json, inte prosa. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
9035dfebc9 |
Engelska är nu systembeskrivningens källa
Filerna byter namn så att basnamnet är den engelska versionen: SYSTEM-DESCRIPTION.md är dokumentet, övriga språk är suffixade. Bytet gjordes med git mv så historiken följer med. Auktoritetskedjan vänds: engelskan säger att den är gällande version och räknar upp översättningarna; svenska, tyska, danska och norska pekar nu på engelskan i stället för på svenskan. Två dokument som båda påstår sig gälla blir i praktiken två sanningar, så exakt ett måste vara källan. Svenskan blir därmed en översättning bland de andra. Den behåller en egen not: kodidentifierarna är oöversatta även där, men där syns det inte eftersom koden är svensk — värt att veta för den som jämför med en annan språkversion. Engelskans ingress säger uttryckligen att dokumentets språk inte ändrar vad koden heter. Det är den missuppfattning som annars uppstår när ett engelskt dokument beskriver ett svenskt kodbas: läsaren börjar söka på översatta namn och hittar ingenting. Alla 48 numrerade avsnitt finns kvar i varje version, verifierat maskinellt, och inga länkar pekar på de gamla filnamnen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
3c5752898b |
Systembeskrivningen på engelska, tyska, danska och norska
Fyra översättningar av hela dokumentet — inte sammanfattningar. Alla 48 numrerade avsnitt finns i varje språkversion, verifierat maskinellt. Kodidentifierare är inte översatta. Händelsetyper, funktionsnamn, fältnamn, filsökvägar och konfigurationsnycklar är svenska i själva koden; ett dokument som döper om dem till engelska blir oanvändbart mot repot. De står därför ordagrant, med förklaring på målspråket där betydelsen inte är uppenbar. Ett skript kontrollerar att 38 sådana identifierare överlevde översättningen i alla fem filer. Varje översättning säger i ingressen att den svenska versionen är källan och gäller vid avvikelse. Två dokument som påstår sig vara lika auktoritativa blir i praktiken två sanningar. Avsnittet om nyckelordsstammar har fått ett tillägg per språk: att "partikelfilter" inte matchar "partikelfiltret" är en egenskap hos svensk böjning, och tyska sammansättningar respektive dansk och norsk bestämd form ger samma klass av problem. Ett lokaliserat nyckelordsset måste valideras mot samma test, inte översättas ord för ord. Ordlistan går från svenska till målspråket och är därmed mer användbar i översättning än i originalet — den blir nyckeln mellan koden och läsaren. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
e90cbf99e9 |
Fullständig systembeskrivning i ett dokument
Ett självständigt referensdokument som beskriver hela systemet utan att repot behöver vara tillgängligt: principer, domänmodell, metodikmotor, ECM, tjänster, säkerhet, infrastruktur, testning och repostruktur. Innehållet är hämtat ur koden, inte ur planer. Där något inte finns står det uttryckligen — inklusive ett avsnitt om kända begränsningar och öppna punkter, eftersom ett dokument som bara beskriver det som fungerar är svårare att resonera kring än ett som säger var kanterna går. Ett eget avsnitt samlar designbesluten med sina motiv. Motivet är oftare det som behövs vid en diskussion än beslutet i sig. 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 |
||
|
|
e94a97715a |
Kartan och driftshandboken stämmer med AWS igen
Infrastrukturen byttes ut men dokumentationen beskrev fortfarande den gamla världen: kustomize, Argo CD, nginx-ingress, Postgres i klustret, GHCR och tre databaslägen. En inaktuell karta är sämre än ingen — den lurar den som litar på den. Infrakartan är omritad mot AWS: tjänsterna och var de ligger, den egna bygg- och driftkedjan från commit till kluster, gränserna inklusive IRSA-bindningen, nätets tre lager och de fyra sakerna som återstår innan skarp drift. Ärendets flöde är oförändrat — produkten är densamma, det är grunden under den som bytts. DRIFT.md beskriver nu de två Terraform-lagren och varför de är två, Aurora med PITR i ett subnätlager utan routing ut, hemligheterna i Secrets Manager där Terraform aldrig ser värdena, och CD-kedjan över Gitea med egna runners. MVP.md har fått en rad för AWS-driften. Kartan säger också rakt ut vad som INTE verifierats: terraform validate kunde inte köras eftersom registry.terraform.io var blockerad, så det som kontrollerats är formatering och statisk referenskontroll. Det står först i listan över vad som ska göras innan skarp drift. Verifierat: 96 vitest-tester, rotens lint och format:check. 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
|