SpacetimeDB er nå helt fjernet fra Synops. Sanntid håndteres av PG LISTEN/NOTIFY + WebSocket i portvokteren (maskinrommet). Kode fjernet: - spacetimedb/ Rust-modul og spacetime.json - maskinrommet/src/stdb.rs (HTTP-klient for STDB-reducers) - frontend module_bindings/ (23 auto-genererte filer) - spacetimedb npm-avhengighet fra package.json - scripts/test-sanntid.sh (testet STDB-flyt) Infrastruktur: - Docker-container stoppet og fjernet fra docker-compose.yml - Caddy: fjernet /spacetime/* reverse proxy - maskinrommet-env.sh: fjernet STDB_IP og SPACETIMEDB_*-variabler - .env.example: fjernet SpacetimeDB-seksjoner Dokumentasjon oppdatert: - CLAUDE.md: stack, lagmodell, kjerneprinsipper, driftsmodell - docs/arkitektur.md: skrivestien, lesestien, datalag, teknologivalg - docs/retninger/datalaget.md: migrasjonshistorikk, status "fjernet" - 37 andre docs oppdatert (features, concepts, infra, ops, retninger) - Alle kode-kommentarer med STDB-referanser oppdatert Verifisert: maskinrommet bygger og starter OK, frontend bygger OK, helsesjekk returnerer 200. Caddy reloadet.
4.6 KiB
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
- 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:
- Brukerens rolle i konteksten (owner/admin/member/reader)
- Verktøyets tilgangsnivå (fra
cli_tool-nodens metadata) - 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 |
| WebSocket nede | Portvokteren restarter | Frontend rekobler automatisk | Sanntid midlertidig 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)
synops-snapshotsikrer 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:
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-kjederdocs/retninger/unix_filosofi.md— generisk dispatchdocs/retninger/maskinrommet.md— portvokter-rollendocs/concepts/arbeidstavlen.md— @bot-konvensjonendocs/concepts/selvdokumenterende_system.md— onboarding-node