- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
28 KiB
AMOS Development Workcamp 2026
Volume 6: Lessons Learned and Continuous Improvement
Period: 2026-06-04 – 2026-06-07 (intensiv fas)
Genererat: 2026-06-07 | Klassifikation: INTERN – KONFIDENTIELL
INLEDNING
Denna volym dokumenterar incidenter, rotorsaksanalyser (5 Why), förbättringar (Kaizen-register) och lärdomar från AMOS Workcamp 2026. Målet är att nästa workcamp inte upprepar samma misstag.
Claude × Siemens-linsen gäller för detta dokument: var incident dokumenteras ärligt, inklusive obekväma fynd. "Surface:a verkliga fynd (även obekväma)" – Claude-sidan av beslutslinsen.
AVSNITT 1: INCIDENTANALYS – 5 WHY
INCIDENT 1: LandveX = bostad-incidenten
Symptom: ESLM (ALETHEIA i test) och produktionschatten (/api/aamos/chat) svarade att LandveX
säljer bostäder. Gravt faktafel med potentiell kundpåverkan om det gått live.
Tidpunkt: Upptäckt 2026-06-06 under systematisk systemkunskaps-härdning.
5 Why-analys:
| Nivå | Varför? | Svar |
|---|---|---|
| 1 | Varför svarade AI att LandveX säljer bostäder? | Produktionschatten hade ingen aktuell LandveX-definition. |
| 2 | Varför saknade chatten korrekt definition? | /api/aamos/chat anropade getEnrichedPrompt() → getFactsContext() → hårdkodad wavult-facts.mjs. Den filen hade LandveX-def som proptech/fastighet. |
| 3 | Varför hade wavult-facts.mjs fel definition? |
Ingen process för att hålla filen synkad med kanonisk AAMOS_CANON.md. Filen skrevs manuellt vid ett tidigt skede och uppdaterades aldrig. |
| 4 | Varför fanns det 39 konkurrerande truth-filer? | Ingen utsedd kanonisk sanningskälla. Varje session/feature kunde skapa en ny "truth"-fil. |
| 5 | Varför saknade RAG en kanonisk källa? | RAG-index skapades ad-hoc, läste bara 3 filer, och RAG-stubs svarade ok:true även när index var tomt – felet doldes. |
Rotorsak: Avsaknad av en enda kanonisk sanningskälla + stubs som dolde att systemet var trasigt.
Åtgärder vidtagna:
- Skapade
/opt/amos/data/AAMOS_CANON.md(ENDA kanoniska sanningskällan, E4-klassad) - Patchade
rag.mjs(CANON tier-1, alltid läst) - Byggde om RAG-index (94 chunks)
- Rättade
wavult-facts.mjsmed korrekt LandveX-definition - Ändrade
LOCKED RULESi produktionschatten (fakta alltid-injicerad) - Neutraliserade bostad-orphan (
landvex-landing.html→ redirect) - Arkiverade 8 dubblett-truth-filer
Verifierat resultat: "Säljer LandveX bostäder?" → AI: "Nej... infrastrukturkontroll." HTTP 200.
Lärdom för nästa workcamp:
En enda CANON-fil är bättre än tio semi-korrekta truth-filer. Stubs ska ALDRIG svara
ok:truepå tomma svar – det döljer att systemet är trasigt.
INCIDENT 2: OOM-kraschen via SocialAuto restart-storm (2026-06-05)
Symptom: Alla domäner mot port 3100 gav timeout (000). amos-core nådde 5.2GB/6.0GB RAM, 1850 aktiva tasks, NATS 503-flood. Systemet var i praktiken nere.
Tidpunkt: 2026-06-05 (exakt tid ej loggad i dagbok, men under nattens arbete).
5 Why-analys:
| Nivå | Varför? | Svar |
|---|---|---|
| 1 | Varför kraschade amos-core med OOM? | 5.2GB RAM → 6.0GB limit. Systemet hade 1850 tasks. |
| 2 | Varför var det 1850 tasks? | 137 parallella Chromium-instanser (stealth-mode) körde simultaneously, vardera ~100MB. |
| 3 | Varför körde 137 Chromium-instanser? | SocialAuto (apifly job-posting, social-account-automation.mjs) relanserade ALLA queued/failed-jobb vid varje omstart – utan concurrency-tak. |
| 4 | Varför relanserades alla jobb vid omstart? | Kod saknade global semafor/concurrency-limit. Vid restart = ny storm av parallella Chromium-launches. |
| 5 | Varför fanns ingen concurrency-limit? | Funktionen byggdes utan att ta hänsyn till restart-scenariot. Ingen review av resursförbrukning per job. |
Rotorsak: SocialAuto's restart-beteende (amplifiering: varje omstart = ny storm) kombinerat med avsaknad av global concurrency-begränsning.
Åtgärder vidtagna:
- Cancellerade 274 skenande jobb i
/opt/amos/data/social-account-jobs.json - PATCH: global semafor
SOCIALAUTO_MAX_CONCURRENT=3runtrunAutomation(), wrapper_runAutomationCore
Verifierat resultat: amos-core 200, 1.7GB RAM, load 2.0. Stabilt.
Diagnostisk lärdom:
Vid amos-core-strul: kolla ALLTID
pgrep -fc chromeochsocial-account-jobs.jsonstatus-counts FÖRST. Restart utan att cancellera jobb förvärrar situationen.
INCIDENT 3: Provider-kredithaveri (xAI/Grok, 2026-06-04)
Symptom: Grok/xAI tog slut på krediter mitt i en orkestrering. Erik beskrev det som "generalhaveri". Orkestreringen kunde inte slutföras. Allt som förlitade sig på Grok som provider blockerades.
Tidpunkt: 2026-06-04 under dagsarbete.
5 Why-analys:
| Nivå | Varför? | Svar |
|---|---|---|
| 1 | Varför havererade orkestreringen? | Grok/xAI-kontot var tomt på krediter. |
| 2 | Varför var kontot tomt utan förvarning? | Ingen kredit-monitor för xAI-kontot. |
| 3 | Varför saknades kredit-monitor? | Varje provider behandlades manuellt. Ingen systemisk kreditövervakning. |
| 4 | Varför saknades systemisk kreditövervakning? | AI-gateway (som byggdes natten efter) existerade inte ännu. |
| 5 | Varför byggdes inte AI-gateway tidigare? | Multi-provider failover var inte prioriterat tills haveriet bevisade behovet. |
Rotorsak: Avsaknad av proaktiv kreditövervakning och automatisk failover.
Åtgärder vidtagna (natten 2026-06-04 → 06-05):
- Byggde AI-gateway (
/opt/amos/data/ai-gateway/gateway.mjs, port 3270, PM2) - 6 providers med auto-failover + circuit-breaker
- FAILOVER BEVISAD LIVE (trasig provider → groq, 1 hopp)
- Provider-monitor (
monitor.mjs, PM2): pollar 7 providers var 5:e min - Auto-larm CRITICAL till Winston (kredit) och Johan (nedtid) via HomoDeus
- Tickets utfärdade: Johan PROV-001..006, Winston PROV-W1..6
- Grok exkluderades från gateway tills påfylld
Absolut regel (Erik, CAPS):
"ALDRIG I PRODUKTION. VARJE PROVIDER: PRIMÄRT REVOLUT + FALLBACK ANNAN BANK + AUTO-TOPUP + BUFFERT."
Ansvarig framåt:
- Johan/Sven: teknisk setup/monitor/failover
- Winston/Rufus: kort/konton/påfyllning
INCIDENT 4: Leon/Vincento-kontaminering av träningsdata (2026-06-06)
Symptom: v3 och v4 av ESLM-träningsdata innehöll 90+129 Leon/Vincento-referenser (train) och 17+18 (validation). Modellen lärde sig en simulerad persona som aldrig existerat. Träningen stoppades.
Tidpunkt: Upptäckt 2026-06-06 22:18 efter Eriks klargörande att Leon = simulering.
5 Why-analys:
| Nivå | Varför? | Svar |
|---|---|---|
| 1 | Varför var träningsdata kontaminerad med Leon/Vincento? | Varje träningsexempel hade AAMOS-systemets kontext i system-prompten, inklusive team-mappning med Leon. |
| 2 | Varför fanns Leon i system-prompten? | Leon behandlades som verklig anställd i alla systemfiler. Ingen markering som simulering. |
| 3 | Varför behandlades Leon som verklig? | Ingen kontroll av personas mot HR-register. Leon hade e-post, agent-mappning, payroll-post (EMP-004) och kodade roller. |
| 4 | Varför hade en simulering alla verkliga attribut? | Simuleringen designades för realism – men ingen distinktion skapades mellan "simulerad test-persona" och "verklig anställd". |
| 5 | Varför saknades distinktionen? | Systemet hade ingen metadata-tagg för simulerade vs. verkliga entiteter. |
Rotorsak: Avsaknad av entitetstyp-distinktion (simulerad vs. verklig) i systemet, kombinerat med att Leon hade alla attribut av en verklig anställd (e-post, payroll, kod-routing, agent).
Åtgärder vidtagna:
- v3 och v4 kasserades omedelbart
- v5 skapades: droppade 12 371 train + 1 357 val företagsspecifika exempel
- ALLA system-prompts byttes mot neutral generell ("evidensbaserad assistent för verksamhetsdrift")
- 3 parallella purge-agenter kördes (purge1_api, purge2_data, purge3_scripts)
- EMP-004 "Leon Magnusson" (alias för Leon Russo, samma syntetiska pnr) raderades ur payroll/HR
- Slutkoll: Leon Russo=0, Leon Magnusson=0, vincento=0, 900510-3456=0 i aktiv kod
Effekt på arkitektur: Incidenten ledde direkt till principen Separation of weights & facts (SD-003):
"Modellen bär ALDRIG företagsdetalj. Fakta injiceras via MNEMOSYNE vid runtime."
INCIDENT 5: JWT Algorithm Confusion (CVSS 10.0) – Identifierad och åtgärdad 2026-05-08
Symptom: Alla authMiddleware-instanser använde jwt.decode() istället för jwt.verify().
Vem som helst kunde förfalska admin-JWT utan att känna till secret.
Tidpunkt: 2026-05-08 under red-team/hardening-arbete.
5 Why-analys:
| Nivå | Varför? | Svar |
|---|---|---|
| 1 | Varför kunde JWT:er förfalskas? | jwt.decode() verifierar INTE signaturen – bara decodes base64. |
| 2 | Varför användes jwt.decode() istället för jwt.verify()? |
Förväxling av metodnamn/syfte vid initial implementation. |
| 3 | Varför spreds felet till 6 filer? | Copy-paste av auth-middleware utan review. Ingen centraliserad auth-hjälpfunktion. |
| 4 | Varför fångades det inte i review? | Ingen security review-process eller automatiserad SAST (static analysis). |
| 5 | Varför saknades security review? | Arbetstempon under byggfasen prioriterade features före säkerhetsreviews. |
Rotorsak: Copy-paste + avsaknad av centraliserad auth-hjälpfunktion + ingen security review.
Åtgärder: Fixad i 6 filer. alg:none-attack blockerad. Rate limiting, security headers, input validation tillagda.
INCIDENT 6: Kafka-backbone degraderad i 8 dagar (2026-06-07)
Symptom: Kafka-klustret (3-broker KRaft StatefulSet) körde i degraderat läge med 2/3 brokers i 8 dagar utan att det uppmärksammades. kafka-1 saknades.
Tidpunkt: Upptäckt 2026-06-07 14:45 under infrastrukturinventering.
5 Why-analys:
| Nivå | Varför? | Svar |
|---|---|---|
| 1 | Varför körde Kafka med 2/3 brokers? | kafka-1 kunde ej skapas pga ResourceQuota-blockering och borttagen EBS-volym. |
| 2 | Varför blockerade ResourceQuota? | init-container fix-volume saknade resource limits → wavult-quota blockerade (FailedCreate ×721 över 8 dagar). |
| 3 | Varför var EBS-volymen borttagen? | kafka-1:s PVC var bunden till vol-0891ca1531dc90def som raderats (InvalidVolume.NotFound). |
| 4 | Varför uppmärksammades det inte? | Ingen monitoring av Kafka broker-hälsa. Degraderat läge genererade inga larm. |
| 5 | Varför saknades Kafka-monitoring? | Observability-gap. Fokus på app-hälsa, ej backbone-hälsa. |
Rotorsak: Avsaknad av Kafka broker-hälsoövervakning. 8 dagar = oacceptabelt för produktionsbackbone.
Åtgärder:
- Patchade init-container med resource limits (25m/64Mi requests, 100m/128Mi limits)
- Raderade orphaned PVC → EBS-CSI provisionerade ny 20Gi gp3
- Broker rejoinade via replikation (RF=3 tålde det)
- Rolling restart av hela STS
- RESULTAT: 3/3 brokers Running, 0 under-replicated partitions, ISR fullständig
INCIDENT 7: host-2 DNS-beroende på Tailscale MagicDNS
Symptom: host-2 (AMI-klon av server-2) kunde inte resolva RDS-DNS och gav ENOTFOUND.
/health/ready = DEGRADED. Hade registrerats i target group (tur att djup health-check stoppade det).
Tidpunkt: 2026-06-05 02:38–03:09 UTC.
5 Why-analys:
| Nivå | Varför? | Svar |
|---|---|---|
| 1 | Varför kunde inte host-2 resolva RDS? | /etc/resolv.conf pekade på 100.100.100.100 (Tailscale MagicDNS). host-2 hade ingen Tailscale. |
| 2 | Varför pekade resolv.conf på Tailscale? | AMI skapades från server-2 som kör Tailscale. Statisk resolv.conf kopierades. |
| 3 | Varför använder server-2 Tailscale som primär DNS? | Tailscale MagicDNS installerades tidigt för dev-convenience och ersatte VPC-resolver. |
| 4 | Varför byggdes ingen DNS-resiliens in? | Ingen policy för DNS-konfiguration på prod-hostar. |
| 5 | Varför saknades DNS-policy? | Det fungerade på server-2 – problemet syntes bara vid skalning till ytterligare host. |
Rotorsak: Prod-DB-resolution beroende av Tailscale. Ej synligt på en host, kritiskt på två.
Åtgärder:
- host-2 v2: user-data skriver
/etc/resolv.conf→ nameserver 172.31.0.2 (VPC-resolver) +chattr +i - server-2: systemd-resolved drop-in
/etc/systemd/resolved.conf.d/99-vpc-fallback.conf(FallbackDNS=172.31.0.2) - ALB-lärdom: Deep health-check (
/health/readymed DB-check) förhindrade att degraderad host fick trafik.
AVSNITT 2: KAIZEN-REGISTER
Kaizen = kontinuerliga förbättringar som identifierades och genomfördes under workcampet.
K-001: env-preload.mjs löser ESM-import-ordningsproblematik
Problem: Stripe och APNS lästes vid ESM-import-tid (rad 11) FÖRE env-loadern (rad 34+) → låstes i MOCK_MODE.
Förbättring: env-preload.mjs importeras som ALLRA FÖRSTA rad i index.mjs – laddas hela env-filen innan någon route-import.
Effekt: End-to-end Stripe-session skapad (cs_test_…). Inga kodändringar vid sk_live_-switch.
K-002: ALB health-check → /health/ready (djup, DB-check)
Problem: ALB health-check mot /health (liveness) = process up men ej DB. En degraderad host fick trafik.
Förbättring: Health-check ändrad till /health/ready som gör faktisk DB-round-trip.
Effekt: host-2 (ENOTFOUND på RDS) hölls automatiskt utanför rotation. Self-protecting arkitektur.
K-003: Idempotent Stripe-webhook med processed_stripe_events-tabell
Problem: Dubbel webhook (Stripe-retry ELLER 2 hosts) → dubbel kreditering möjlig.
Förbättring: Ny tabell quixzoom.processed_stripe_events (event_id PK), INSERT ON CONFLICT DO NOTHING + atomisk balance = balance + credits.
Effekt: Dubbel-kreditering matematiskt omöjlig oavsett antal hostar eller Stripe-retries.
K-004: Concurrent-tak för SocialAuto (SOCIALAUTO_MAX_CONCURRENT=3)
Problem: SocialAuto relanserade alla queued jobs vid restart utan tak → OOM.
Förbättring: Global semafor runt runAutomation(), wrapper _runAutomationCore.
Effekt: Max 3 Chromium-instanser simultant. Restart = ingen storm.
K-005: AI-gateway med auto-failover (circuit-breaker)
Problem: En provider (Grok) tar slut → hela orkestreringen havererar. Förbättring: AI-gateway med 6 providers, task-kedjor (reasoning/fast/search/creative/financial/default), circuit-breaker. Effekt: FAILOVER BEVISAD LIVE: trasig provider → groq, 1 hopp, 0 avbrott i orkestrering.
K-006: Provider-monitor var 5:e minut med auto-larm
Problem: Ingen visste att xAI/Grok var tomt förrän orkestrering havererade.
Förbättring: monitor.mjs (PM2) pollar 7 providers var 5:e min. Auto-larm CRITICAL till Winston (kredit) och Johan (nedtid) via HomoDeus.
Effekt: Reaktiv → proaktiv kreditövervakning.
K-007: AAMOS_CANON.md som enda kanonisk sanningskälla
Problem: 39 konkurrerande truth-filer → LandveX=bostad-incidenten. Förbättring: En enda CANON-fil (E4), tier-1 i RAG, alltid-injicerad i produktionschat. Effekt: Systemet svarar korrekt om LandveX. Fakta uppdateras på ett ställe.
K-008: Stub-transparens (X-AAMOS-Stub header + Warning + _stub:true)
Problem: 432 stubs svarade ok:true på tomma svar → dolde att subsystem var döda.
Förbättring: Varje stub-träff loggas + X-AAMOS-Stub:true + Warning-header + _stub:true i body + ny /api/_stub-report.
Effekt: Konfigurerad förmåga som ej är ansluten syns nu i instrumenteringen.
K-009: SSM Run Command för root-operationer (nginx/systemd utan sudo-beroende)
Problem: nginx-filer ägdes av root/ec2-user → bernt kunde ej skriva → blockerade nginx-tickets till Johan.
Förbättring: AWS SSM Run Command via IAM-roll platform-ec2-ssm-role. Mönster: aws ssm send-command --document AWS-RunShellScript, base64-encoda komplexa script.
Effekt: Kan nu ändra nginx, systemd, certs via SSM. Inga fler "väntar på Johan för root"-blockeringar.
K-010: LLM-as-judge med 4-lagers fallback
Problem: Keyword-matchning för svenska för trubbig. Qwen-32B som domare för svag (trodde "PASS" = EU-direktiv). Förbättring: Judge-v2: Bedrock-Opus-4-6 → Sonnet-4-5 → direkt-Opus-4-8 → Qwen-235B. LLM-schema-agnostisk parser. Effekt: En poliskontroll är nu aldrig svagare än det den vaktar.
K-011: Separation of weights & facts (arkitekturprincip)
Problem: Företagsdetaljer inbränt i modellvikter = säkerhetsrisk, kräver omträning vid ändring. Förbättring: ALETHEIA (modellvikter) = generell evidensmotor. MNEMOSYNE (CANON/RAG) = runtime-fakta. Effekt: Ingen faktaläcka via vikter. Fakta ändras utan omträning. ESLM säljbar generellt.
K-012: POS→Ledger automatisk bokföring (idempotent)
Problem: Restaurangförsäljning postades ej automatiskt till aamos-ledger → SIE4 var tom.
Förbättring: POST /pos/ledger/post-day {fecha} + cron 03:15 Europe/Madrid. Tracking-tabell restaurant_ledger_postings (UNIQUE tenant+datum). Idempotent.
Effekt: "Säljer jag en paella, hamnar den i böckerna?" = JA. Automatiskt, utan handpåläggning.
K-013: Ticket-system för felrapportering (aamos-restaurant-tickets:3318)
Problem: Ingen strukturerad väg för restaurangtjänster att rapportera integrationsproblem. Förbättring: Ny Rust/axum-tjänst med severity (low/medium/high/critical), status-flöde, källa (staff/system/customer/agent), HTML-dashboard. Effekt: POS auto-skapar high-severity accounting-ticket när ledger-postning failar. Systemintelligens istället för stum kraschtystnad.
K-014: Webhook-idempotens som förutsättning för multi-host
Problem: Multi-host (host-2) blockerades av att Stripe-webhooks ej var idempotenta. Förbättring: Löstes som prerequisite för RES-004. Multi-host + idempotens = sann redundans. Effekt: Systemet är nu multi-host-redo utan risk för ekonomisk data-korruption.
K-015: Jurisdiktionsmedveten onboarding (ES/SE och fler)
Problem: Onboarding-tjänst hårdkodad för Sverige → spansk CIF och IVA-satser avvisades.
Förbättring: country (ISO-3166, default "SE") i register + DB-kolumn. ES→CIF/NIF + IVA {4,10,21}, SE→orgnr + moms {12,25}.
Effekt: Spansk chiringuito kan slutföra alla 7 onboarding-steg. Global skalning möjlig.
K-016: Gravation arm64/Graviton-only för EKS (deterministisk flotta)
Problem: Preferred (80/20 arm64/x86-fallback) lämnar en variabel som kan överraska i prod.
Förbättring: Required arm64-only (nodeSelector + requiredDuringScheduling). Alla images: --platform linux/arm64.
Effekt: Homogen flotta, reproducerbart beteende, ~20% billigare. Inga edge-cases från mixed architectures.
K-017: Django E2E-simuleringen (986 orders, €146.5k, 24/24 OK)
Problem: Restaurang-stacken hade 6 oupptäckta integrationsbuggar (VAT overflow, analytics-paths, decimal-parsing, etc.). Förbättring: Fullständig månads-driftsimulering med 986 orders, 15 tjänster, ~130 endpoints, 14 verifieringsfaser. Effekt: Alla 6 buggar hittades och fixades. SIE4-kedjeavstämning POS→Modelo303→Ledger→SIE4 perfekt.
AVSNITT 3: TEKNISKA LÄRDOMAR
TL-001: Verifiera ALLTID den körande filen, inte filen på disk
Källa: Produktionschat-fix (2026-06-06)
Körande
amos-core=services/amos-core/server.mjs.scripts/server.mjsKÖRS INTE. Hade nära håll på att fixa fel fil. Kontrollera alltid medps auxellersystemctl status.
TL-002: Stubs som svarar ok:true döljer döda subsystem
Källa: LandveX-incidenten + 432 stubs-audit (2026-06-06)
Instrumentering ska visa sanningen, inte dölja den. En stub som svarar
ok:truepå tom respons är aktivt skadlig – det ger en falsk bild av systemhälsan.
TL-003: ESM import-ordning är deterministisk och kan bita
Källa: Stripe env-preload.mjs fix (2026-06-05)
I ES modules körs importerade moduler vid import-tid, inte vid runtime. Variabler som läses tidigt (t.ex. env-variabler) måste finnas INNAN importen. Lösning: preload-modul som allra första import.
TL-004: AMI-kloning kopierar statisk konfiguration inklusive resolver
Källa: host-2 DNS-incidenten (2026-06-05)
AMI-snapshot fryser in all konfiguration inklusive
/etc/resolv.conf. Om produktionsmiljön beror på ett sidoverktyg (Tailscale) som inte finns på alla hostar, sprids beroendet vid kloning. Lösning: user-data-script som skriver DNS-konfiguration vid boot.
TL-005: pgrep -fc chrome är första diagnostiksteg vid amos-core-strul
Källa: OOM-incidenten (2026-06-05)
Kolla antalet Chromium-instanser och social-account-jobs.json status-counts INNAN restart. Restart utan job-avbrottning förvärrar storm-beteende exponentiellt.
TL-006: LLM-as-judge måste vara starkare än det den poliskontrollerar
Källa: ESLM red-team, judge-evolution (2026-06-06)
Qwen-32B som domare klassade "PASS" som ett EU-direktiv och godkände felaktiga svar. En poliskontroll som är svagare än systemet den granskar ger falsk säkerhet. Regel: judge-modellen ska ALLTID vara starkare än production-modellen.
TL-007: Keyword-matchning för svenska är för trubbig som red-team
Källa: ESLM red-team v1 vs v2 (2026-06-06)
Keyword-matchning fångade inte subtila felaktigheter i svenska svar. Ersattes av LLM-as-judge (v2). Lärdom: för komplexa domäner krävs semantisk bedömning, inte mönstermatchning.
TL-008: gpt-5.5-pro kräver /v1/responses, ej /chat/completions
Källa: Infra-fakta 2026-06-05
OpenAI:s nya API-endpoint är inte bakåtkompatibel. Mycket långsam (>20 min öppna promptar). Undvik för tidskänsliga körningar.
TL-009: sqlx compile-time-makron (query!) kräver live DATABASE_URL vid build-tid
Källa: EKS-migration compliance-tjänst (2026-06-07)
14/15 Rust-tjänster byggde direkt. Compliance: enda med
query!-makron → krasch utan DATABASE_URL. Lösning:--build-arg DATABASE_URLvid Docker build. Alternativt: användquery()(runtime) istället.
TL-010: ResourceQuota blockerar pod-skapande tyst (FailedCreate-events)
Källa: Kafka-degraderingen (2026-06-07)
kafka-1 fick FailedCreate ×721 utan larm. ResourceQuota stoppade init-containern pga saknade resource limits. Lärdom: Resource limits ska finnas på ALLA init-containers. Övervaka FailedCreate-events.
TL-011: RDS SSL-konfiguration krävs i Node.js-connections mot AWS RDS
Källa: tool-registry SSL-fix (2026-06-05)
new Pool({connectionString: AMOS_DB_URL})utan SSL-config → RDS avvisade med "no pg_hba.conf entry". Lösning:ssl: {rejectUnauthorized: false}i Pool-konfiguration.
TL-012: Providermodellnamn förändras – håll dem uppdaterade
Källa: Gemini 2.0→2.5 fix (2026-06-05)
Gamla modellnamn (Gemini 2.0, gammal Haiku) kraschade tyst. Orsakade dold instabilitet i orkestrering. Lärdom: API-modellnamn är ej stabila – håll en provider-modell-förteckning uppdaterad.
AVSNITT 4: PROCESSLÄRDOMAR
PL-001: Parallellisering med tickets och subagenter är kraftfullt
Källa: 2026-06-06 parallellbygge (14 tickets, 4 epics, 8 subagenter)
90/100 tickets lösta på en session. Erikmönstret: "gör tickets, starta agenter." Fungerar för parallella epics som inte delar state. Kräver tydlig tickets-struktur och agent-scope.
PL-002: Red-team FÖRE promotion är inte valfritt
Källa: ESLM-processen (2026-06-06)
ALETHEIA-baslinjen: 33% passerade, 5 kritiska brister. Utan red-team hade modellen gått live med LandveX=bostad och hallucinerande org-nr. Red-team är minimikravet, inte ett bonus-steg.
PL-003: Ekonomifunktionen måste ha proaktiv förvarning
Källa: xAI/Grok-haveriet (2026-06-04)
Reaktiv hantering (Erik ringer Winston när Grok är tomt) är oacceptabelt. Systemet måste larma INNAN kontot är tomt. Auto-topup + buffert + 5-min kreditkoll är miniminivå.
PL-004: Kör simuleringen INNAN du berättar för kunden att det är redo
Källa: Restaurang-plattformens 6-buggars-fynd (2026-06-07)
Erik trodde restaurang-stacken var "100% redo för onboarding". E2E-test avslöjade BLOCKER (spansk CIF). Lärdom: "100% redo" valideras av systemet, inte av en persons uppskattning. Kör alltid simulering.
PL-005: Behörighetshierarkier ska tydliggöras i agentmailboxen
Källa: Beroende av Johan för nginx (2026-06-04/05)
Bernt (bernt-user) kan ej skriva nginx-filer (root/ec2-user). Blockade i veckor tills SSM-mönstret upptäcktes. Lärdom: dokumentera åtkomstgränser och eskaleringsvägar tydligt från start.
PL-006: Kanoniska namn ska låsas tidigt, inte sent
Källa: Hermes→Hephaistos-omdöpning (2026-06-07)
Hermes behövde döpas om (76 filer) pga namnkollision med externa bibliotek i träningsdata. Lärdom: namnkonflikter med populära bibliotek är dyrare att fixa sent. Välj ovanliga egennamn.
AVSNITT 5: ARKITEKTURLÄRDOMAR
AL-001: Separation of concerns gäller även AI-modeller
Källa: ESLM-arkitektur, SD-003 (2026-06-06)
Modellvikter (ALETHEIA) och faktabas (MNEMOSYNE) är separata ansvarsområden, precis som kod och konfiguration. En modell som bär konfiguration (företagsfakta) är svår att uppdatera.
AL-002: Event-backbone (Kafka) ska väljas och övervaka från dag 1
Källa: Kafka-degraderingen 8 dagar (2026-06-07)
Tre parallella event-mekanismer (Kafka, aamos-event-bus, NATS/Redis) skapade oklarheter. Kafka var productionstanken men 2/3 brokers – utan larm i 8 dagar. Välj en backbone, övervaka den.
AL-003: Gitops + EKS + ExternalSecrets är rätt mönster (Siemens-standard)
Källa: EKS-migration referensmönster (2026-06-07)
ArgoCD + external-secrets + ClusterSecretStore + AWS SSM = reproducerbar, auditbar deploy. Varje workload: ExternalSecret → Deployment → Service → Kong-route. Mönstret verifierades end-to-end.
AL-004: Single point of truth gäller all systemkunskap
Källa: LandveX-incidenten (2026-06-06)
39 competing truth-filer → inkonsistens. AAMOS_CANON.md som enda E4-fil löste grundproblemet. Samma princip gäller all systemkunskap: en CANON, alla vet var de hittar sanningen.
AL-005: Health-check-djup avgör om redundansen fungerar på riktigt
Källa: host-2 DNS-incidenten (2026-06-05)
/health(liveness) = process up, men ej nödvändigtvis fungerande./health/ready(readiness) med faktisk DB-round-trip är minimikravet för ALB-integrering. Ytlig health = falsk trygghet.
AL-006: Multi-AZ är grundkrav, inte lyx
Källa: RES-001/003 (2026-06-05)
Single-AZ RDS: RTO = timmar. Multi-AZ: RTO 60–120s. Diff = $700/mån. Erik: "Vi har inte alternativ." Lärdom: bygg multi-AZ från start. Eftermontage är dyrare (maintenance window, DNS-propagation).
AL-007: Idempotens är förutsättning för horisontell skalning
Källa: Stripe-webhook-idempotens som Fas-2-prerequisite (2026-06-05)
Kan inte lägga till fler hostar utan idempotenta webhooks. Idempotens är inte ett nice-to-have – det är det som gör horisontell skalning säker.
AVSNITT 6: ERKÄNDANDEN
Vad gick riktigt bra?
- Parallellisering med subagenter – 90/100 tickets på en session bevisar att multi-agent-koordination fungerar.
- Deep health-check räddade produktionen – host-2 med trasig DNS-resolution fick aldrig trafik tack vare
/health/ready. - Red-team-grinden fångade kritiska brister – utan red-team hade LandveX=bostad gått live.
- SSM-mönstret löste root-beroendet – månaders blockering av nginx-filer löst på en timme.
- EKS-migrationen gick smidigt – 17 tjänster, 34 pods, alla på Graviton/arm64, alla friska.
- DDP-träningen fungerade – från ~8h på A10G till ~1h på 8x A100. Ny hastighetstandard.
- Restaurang E2E-simulering – hittade 6 riktiga integrationsbuggar och kvantifierade dem till öret.
Vad var svårast?
- Leon/Vincento-purgen – kräver precision (behåll andra Leons, radera bara rätt entiteter). 3 agenter parallellt krävdes.
- Kafka-degraderingen – 8 dagar utan larm är ett allvarligt observability-gap. Fixades men borde ha fångats dag 1.
- Judge-modell-valet – det tog tre iterationer (keyword → Qwen-32B → Opus-direkt) för att hitta rätt domar-nivå.
- Providermodell-avvecklingen – gamla modellnamn kraschade tyst. Svårt att spåra utan centraliserad provider-förteckning.
Volym 6 av 7 | AMOS Workcamp 2026 | Klassifikation: INTERN – KONFIDENTIELL Nästa: VOL7-AMOS-Operating-System.md