4dea6d2818dab56bca63935622d14e6f4adac9ea
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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
|
||
|
|
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 |
||
|
|
66762629df |
Bäddad typografi, tätare spärrning, räta hörn och ritningsstämpel
Fyra saker som alla svarar på samma sak: ALVA såg fortfarande inte ut som det den påstår sig vara. Snittet som fil. Fallkedjan säkrade ordningen men inte utfallet — utan DIN installerad föll ytan ned till vad enheten råkade ha, Helvetica på en iPhone och Roboto på en Android. Ett system som beskriver sig som en standard får inte se olika ut beroende på var det öppnas. IBM Plex Sans, specens tredje tillåtna snitt, bakas därför in: latinsk delmängd, tre textvikter och två för monospace, drygt 100 kB. Licensen följer med. Vite bakar in woff2 som data-URI. Det är inte en optimering utan ett krav: ALVA publiceras bland annat som en självbärande sida bakom en CSP där varje extern begäran blockeras, och en @font-face mot en assetfil hade tyst fallit tillbaka till enhetens eget snitt — alltså precis det inbäddningen ska avskaffa. Bara woff2; värdapplikationens bilder är megabyte stora och förblir egna filer. Spärrningen ett steg tätare genomgående. DIN-satta OEM-dokument är tätare än vad ytan var, och med rätt bokstavsform tål den det. Räta hörn i felsökningen. 69 förekomster av rundad radie, alla ur Lovable-arvet. Ett verkstadssystem har räta hörn. Ritningsstämpel sist i rapporten: beteckning, regelpaket, evidensmodell, plattformsversion, status och utgåvedatum. En granskare måste kunna se vilka versioner som gällde när ärendet stängdes, inte vilka som gäller den dag rapporten läses. Fyra tester låser inbäddningen, inklusive att ingen @font-face pekar mot en extern värd. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt |
||
|
|
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 |
||
|
|
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 |
||
|
|
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
|