From c5de6086ca2b6d6297d298bde02251a25b70ebbc Mon Sep 17 00:00:00 2001 From: vegard Date: Tue, 17 Mar 2026 05:04:09 +0100 Subject: [PATCH] Innarbeid ekstern review: RLS-siloer, AGE-pragmatisme, compute-separasjon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bruker_ikke_workspace: RLS-advarsel tatt på alvor — samlings-noder er harde sikkerhetsiloer under panseret, edge-basert tilgang er UX-lag innenfor siloene - datalaget: AGE moderert fra "beslutning" til "planlagt utvidelse" — start med CTEs, legg til AGE når det faktisk trengs - maskinrommet: compute-separasjon dokumentert — tunge workers kan flyttes til egen node, maskinrommet ruter transparent Co-Authored-By: Claude Opus 4.6 --- docs/retninger/bruker_ikke_workspace.md | 35 ++++++++++++++++++++++--- docs/retninger/datalaget.md | 15 ++++++++--- docs/retninger/maskinrommet.md | 21 +++++++++++++++ 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/docs/retninger/bruker_ikke_workspace.md b/docs/retninger/bruker_ikke_workspace.md index 4cd8932..d700f9e 100644 --- a/docs/retninger/bruker_ikke_workspace.md +++ b/docs/retninger/bruker_ikke_workspace.md @@ -102,20 +102,47 @@ Ingen "slett bruker fra workspace." Fjern deltaker-edges. Brukerens private noder som hadde edge til samlings-noden beholder den edgen (det er brukerens innhold), men de mister tilgang til andres noder. +## RLS og sikkerhet: samlings-noder som harde siloer + +Viktig arkitekturbeslutning: **"bruker, ikke workspace" er en +UX-modell, ikke en sikkerhetsmodell.** + +Ren edge-basert tilgangskontroll — der hver lesing traverserer grafen +for å sjekke om brukeren har en sti til noden — ville kvelt +databasen når grafen vokser. I dag har PG bunnsolid RLS med +`workspace_id = current_setting(...)` — instant og vanntett. + +Løsningen er å skille UX fra sikkerhet: +- **UX-laget:** Brukeren ser sine edges. Ingen "velg workspace." + Filtrering etter samlings-node er frivillig. +- **Sikkerhetslaget:** Under panseret har hver node fortsatt en + `workspace_id` (eller samlings-node-id) som RLS sjekker. Det er + den harde sikkerhetsgensen — billig, velprøvd, instant. +- **Finere tilgang innenfor siloen:** Edge-basert tilgang (eier, + admin, deltaker, leser) sjekkes *innenfor* en silo, ikke som + erstatning for den. + +Samlings-noder er altså ikke bare frivillig organisering — de er +sikkerhetsiloer i databasen. Brukeren merker det ikke, men PG +trenger det. + ## Spenninger og åpne spørsmål - **Overblikk.** Uten workspaces som organisatorisk enhet — hvordan unngår du at alt flyter sammen? Samlings-noder er svaret, men de må være intuitive å opprette og bruke uten å bli "workspaces med ny navn." -- **Tilgangskontroll i praksis.** Edge-basert tilgang er fleksibelt, - men kan det bli uoversiktlig? "Hvem har tilgang til hva" må være - lett å besvare. Kanskje samlings-noden gir en naturlig audit-visning. +- **Kryssgående noder og siloer.** Hvis noder har `workspace_id` for + RLS, kan en node da tilhøre to samlings-noder? Kanskje via en + "primær silo" for RLS + sekundære edges for visning. Trenger + gjennomtenkt design. - **Arv og konflikter.** En node med edge til to samlings-noder med ulike pruning-profiler — hva vinner? Trenger klare regler som er intuitive for brukeren. - **Migrering.** Eksisterende workspace-modell har innhold. Kan - workspaces bli samlings-noder gradvis? + workspaces bli samlings-noder gradvis? RLS-modellen gjør dette + enklere — workspace_id kan bli samlings-node-id uten endring i + sikkerhetslogikk. ## Forhold til andre retninger diff --git a/docs/retninger/datalaget.md b/docs/retninger/datalaget.md index d8fcf19..78ca613 100644 --- a/docs/retninger/datalaget.md +++ b/docs/retninger/datalaget.md @@ -52,7 +52,8 @@ og edges lagres i PG-tabeller, men spørres med Cypher-semantikk. ## Beslutning -**PostgreSQL + Apache AGE** som enhetlig datalager for noder og edges. +**PostgreSQL** som enhetlig datalager for noder og edges. +**Apache AGE** som planlagt utvidelse — ikke forpliktet fra dag én. De fleste spørringer i dette systemet er grunne: - "Vis noder med edge til denne brukeren" — 1 hopp @@ -60,9 +61,15 @@ De fleste spørringer i dette systemet er grunne: - "Finn alle kommunikasjonsnoder brukeren har tilgang til" — 2-3 hopp - "Traverser kunnskapsgrafen mellom to emner" — 3-5 hopp -AGE håndterer dette. Skulle det vise seg at dypere traverseringer -blir en flaskehals *i praksis*, kan Neo4j evalueres da — men med -én VPS og realistiske datamengder er det usannsynlig. +PG med rekursive CTEs håndterer 1-3 hopp utmerket. AGE legges til +når graftraversering faktisk blir en målbar flaskehals — ikke før. +AGE er en extension, ikke en migrering, så den kan boltes på uten +å endre eksisterende kode. + +Pragmatisk rekkefølge: +1. **Nå:** PG med nodes/edges-tabeller og CTEs +2. **Når CTEs blir smertefulle:** Legg til AGE for Cypher-spørringer +3. **Usannsynlig:** Evaluer Neo4j hvis AGE ikke holder ## Lagmodell diff --git a/docs/retninger/maskinrommet.md b/docs/retninger/maskinrommet.md index b59f56c..0a1856b 100644 --- a/docs/retninger/maskinrommet.md +++ b/docs/retninger/maskinrommet.md @@ -255,6 +255,27 @@ Rekkefølge: definer traits → migrer eksisterende worker-jobber inn → legg til nye tjenester etter hvert. Fast punkt fra dag én, full dekning over tid. +## Compute-separasjon + +Maskinrommet orkestrerer — men tunge jobber trenger ikke kjøre på +samme maskin. Hetzner CPX42 (8 vCPU, 16 GB RAM) skal håndtere state +(PG, SpacetimeDB) og sanntid (Caddy, LiveKit, SvelteKit). Whisper +(CPU-intensiv, spesielt large-v3) og lokal LLM (kildevern-modus) +vil konkurrere om ressurser under live innspilling. + +Maskinrommets abstraksjon gjør dette løsbart: +- **Nå:** Alt på én VPS. Jobbkøen prioriterer sanntid over batch. + Whisper kjøres med lavere concurrency under live-sesjoner. +- **Senere:** Trekk ut tunge workers til en separat node (billig + ARM/Ampere-instans) som poller jobbkøen over internt nettverk. + Maskinrommet ruter transparent — primitivene merker ingenting. +- **Kildevern-modus:** Lokal LLM (Llama/Gemma) krever GPU eller + dedikert compute. Urealistisk på delt VPS. Egen node for dette. + +Poenget: maskinrommet er designet for å rute arbeid, ikke for å +*utføre* alt selv. Compute-separasjon er en konfigurasjon, ikke en +arkitekturendring. + ## Spenninger og åpne spørsmål - **Synkron vs asynkron.** "Fang" og "lever" kan være instant, men