# Robusthet og fallback ## Lagmodell ``` Lag 1: LLM-leverandør (Claude API, OpenAI, etc.) → utenfor vår kontroll Lag 2: LiteLLM (AI Gateway) → lokal Docker Lag 3: Portvokteren → lokal native (systemd) Lag 4: CLI-verktøy (synops-*) → per-kall, isolert Lag 5: PostgreSQL → lokal Docker, SPOF ``` ## Deteksjon ### Bot-nedetid Portvokteren overvåker `synops-respond` sin exit-kode. Ved feil: ``` @bot (ingen respons på 30 sek) → Portvokteren sender automatisk i chatten: "⚠ Boten er midlertidig utilgjengelig. Meldingen din er lagret og blir besvart når tjenesten er tilbake." → Oppretter work_item i innboks: "Bot-nedetid" + tagged "bug" → Logger i ai_usage_log med error-status ``` Brukeren vet at meldingen er mottatt. Når boten er tilbake, kan den prosessere ubesvarte meldinger. ### Healthcheck Portvokteren eksponerer `/health` som sjekker: - PG-tilkobling - STDB-tilkobling - LiteLLM-tilgjengelighet - Disk-status Systemd restarter portvokteren ved gjentatte feil. ## LLM fallback-kjede LiteLLM håndterer modell-fallback. `@bot` fungerer uansett hvilken modell som svarer: ``` synops-respond → LiteLLM ├── Claude (primær) ├── GPT-4 (fallback 1) ├── Gemini (fallback 2) └── Lokal modell (fallback 3, alltid oppe) ``` Brukeren merker kanskje kvalitetsforskjell, men tjenesten er oppe. Fallback-kjeden konfigureres i LiteLLM — ingen endring i portvokteren eller synops-respond. ## Ekstern API-bot og CLI-verktøy En LLM via API har ikke shell-tilgang. Den trenger det heller ikke — portvokteren er mellomleddet. ### Function calling / tool use ``` Bruker: "@bot sjekk om RSS-feeden oppdaterte seg" → portvokteren → synops-respond → LLM API LLM svarer med structured output: { "response": "Jeg sjekker RSS-feeden for deg.", "actions": [ { "tool": "synops-rss", "args": { "collection_id": "abc123" } } ] } Portvokteren: 1. Poster chat-svaret i samtalen 2. Spawner: synops-rss --payload-json '{"collection_id":"abc123"}' 3. Poster resultatet som oppfølgingsmelding ``` LLM-en beskriver *hva* som skal gjøres. Portvokteren *gjør* det. Navnekonvensjonen (`synops-{tool}`) betyr at portvokteren kan dispatche uten hardkodet mapping — samme generiske dispatch som jobbkøen (se `docs/retninger/unix_filosofi.md`). ### Tilgangskontroll for actions Ikke alle brukere skal kunne trigge alle verktøy via `@bot`. Portvokteren sjekker: 1. Brukerens rolle i konteksten (owner/admin/member/reader) 2. Verktøyets tilgangsnivå (fra `cli_tool`-nodens metadata) 3. Rate limiting per bruker En `reader` kan spørre `@bot` om informasjon, men ikke trigge `synops-render` eller `synops-audio`. ## Fallback per situasjon | Situasjon | Deteksjon | Fallback | Brukeropplevelse | |-----------|-----------|----------|------------------| | Claude API nede | LiteLLM timeout | Neste modell i kjeden | Svarer, kanskje litt dårligere | | Alle LLM-er nede | synops-respond exit != 0 | Statisk "utilgjengelig" + work_item | Vet at meldingen er mottatt | | Portvokteren nede | Systemd healthcheck → restart | CLI fungerer for Claude Code | Web-brukere venter, terminal funker | | PG nede | Connection refused | Alt stopper | Eneste reelle SPOF | | STDB nede | Reconnect-loop | PG-fallback for lesing, skriving bufres | Sanntid borte, data trygt | ## PG som eneste SPOF PostgreSQL er den eneste komponenten der nedetid stopper alt. Men det er også den mest stabile — PG krasjer sjelden, og gjenoppbygging fra backup er veldokumentert (se `docs/setup/produksjon.md`). Mitigering: - Automatisk PG-dump (se oppgave 12.2) - STDB kan gjenoppbygges fra PG - `synops-snapshot` sikrer at docs-fallback finnes i repo - CAS-filer er uavhengig av PG (filsystem) ## Onboarding som statisk dispatch Første `@bot` i en ny brukers velkomst-chat trenger ikke LLM-roundtrip. Portvokteren gjenkjenner mønsteret og serverer onboarding-noden direkte: ```rust if is_welcome_chat && is_first_bot_mention { return serve_static_node(ONBOARDING_NODE_UUID); } ``` Null latency, null AI-kostnad, fungerer selv om alle LLM-er er nede. Onboarding-teksten er en vanlig node — oppdaterbar uten redeploy. Etter første melding fungerer chatten normalt med LLM. ## Bygger på - `docs/infra/ai_gateway.md` — LiteLLM fallback-kjeder - `docs/retninger/unix_filosofi.md` — generisk dispatch - `docs/retninger/maskinrommet.md` — portvokter-rollen - `docs/concepts/arbeidstavlen.md` — @bot-konvensjonen - `docs/concepts/selvdokumenterende_system.md` — onboarding-node