synops/CLAUDE.md

10 KiB

Synops — Claude Code Prosjektguide

Prosjektoversikt

Synops er en plattform for redaksjonelt arbeid og podcast-produksjon. Self-hosted på Hetzner VPS med full datakontroll.

Synops er plattformen. Sidelinja (podcastredaksjonen) er en tenant — en organisasjon som bruker Synops. Denne distinksjonen er bevisst: plattformkode og infrastruktur er skilt fra tenant-data og -innhold.

Arbeidsflyt

  • Standard arbeidsmodus: Start i planleggingsmodus. Lag en grundig plan, få godkjenning, deretter implementer. Jobbene er ment å kunne kjøre lenge autonomt uten input underveis.
  • Alt skjer på serveren. Claude Code kjører direkte på produksjonsserveren (/home/vegard/synops/). Rust, Node.js og Docker er tilgjengelig. Bygging, testing og deploy skjer her. Vegard kobler til via SSH/tmux.
  • Browser-testing: Claude har ikke tilgang til browser. Visuell testing gjøres av Vegard. Claude verifiserer backend (kompilering, API, DB-state).
  • Commit og push: Bruk egen vurdering. Trygt og reverserbart.
  • Deploy til produksjon: Krever alltid eksplisitt godkjenning fra Vegard.
  • Diskusjon: Forklar og diskuter før arkitekturendringer. For implementering innenfor eksisterende spec — bare kjør.

Dokumentasjonstre

CLAUDE.md er eneste startdokument. Alt annet ligger under docs/:

  • docs/arkitektur.md — Overordnet arkitektur, lagmodell, teknologivalg
  • docs/retninger/ — Arkitektoniske teser og vedtatte retninger:
    • README.md — Oversikt og status
    • status_quo.md — Hva v1 var: ambisiøse primitiver, tradisjonell overflate
    • rom_ikke_forum.md — Opplevelse-først, to-lags-modell, administrativ opplevelse
    • universell_input.md — Tre primitiver (input, mottak, kommunikasjon), noder+edges
    • maskinrommet.md — Rust-orkestrator: fang, prosesser, lever
    • bruker_ikke_workspace.md — Noder er sentrum: brukere, team, innhold er noder. Tilgangsmatrise fra edges.
    • datalaget.md — PG(+AGE) som graf og arkiv, SpacetimeDB som sanntidslag
    • arbeidsflaten.md — Spatial canvas med verktøy-paneler, drag-and-drop, kompatibilitetsmatrise
    • unix_filosofi.md — Maskinrommet som orkestrator, arbeid i CLI-verktøy, Claude og maskinrommet deler verktøykasse
  • docs/primitiver/ — Spesifikasjoner for kjerneprimitivene:
    • nodes.md — Node-skjema, node_kind, visibility, CAS-noder, eierskap
    • edges.md — Edge-skjema, typer, metadata, systemedges
    • traits.md — Trait-system: evner/funksjonalitet for samlingsnoder, katalog, pakker
    • (kommer: input, mottak, kommunikasjonsnode)
  • docs/concepts/ — Brukeropplevelser/produktområder:
    • studioet.md, møterommet.md, redaksjonen.md, podcastfabrikken.md, kunnskapsgrafen.md, valgomaten.md, den_asynkrone_gjesten.md, publisering.md, adminpanelet.md
  • docs/features/ — Tekniske byggeklosser:
    • Se individuelle filer for chat, kanban, kalender, meldingsboks, kunnskapsgraf, whiteboard, live transkripsjon, ressursforbruk, m.fl.
    • lydstudio.md — Lydredigering via FFmpeg, EDL, ikke-destruktiv prosessering
    • artikkelverktoy.md — Langform TipTap-editor, drag-and-drop mottak, source_material-edges
    • universell_overfoering.md — Drag-and-drop mellom verktøy-paneler, kompatibilitetsmatrise
  • docs/proposals/ — Idébank med 32+ uimplementerte forslag (se README.md)
  • docs/setup/ — Oppsett og drift:
    • produksjon.md — Steg-for-steg oppsett av Hetzner VPS fra scratch
    • lokal.md — Historisk: lokalt utviklingsmiljø (WSL2). Utdatert — all utvikling skjer nå på serveren.
    • migration_safety.md — Sjekkliste for PostgreSQL-migrasjoner (v1 workspace-RLS, trenger omskriving til node_access)
  • docs/infra/ — Infrastruktur og drift:
    • ai_gateway.md — LiteLLM som sentralisert AI-ruter (BYOK + fallback)
    • api_grensesnitt.md — Kommunikasjonskart: SvelteKit er web-API, Rust er worker
    • jobbkø.md — PostgreSQL-basert køsystem for bakgrunnsjobber
    • synkronisering.md — PostgreSQL ↔ SpacetimeDB dataflyt og eierskapsmodell
    • claude_agent.md — Claude som chat-deltaker: arkitektur, triggere, sikkerhet
  • docs/erfaringer/ — Lærdommer fra v1 (adapter-mønster, Svelte 5, SpacetimeDB, Authentik)
  • reference/ — Kode fra v1 med gjenbruksverdi (Editor.svelte)
  • ops/ — Repeterbare vedlikeholdsjobber (ryddejobb, doc-audit, drift-sjekk)

Aktører

  • Vegard — serveradmin, utvikler, bruker. Kobler til via SSH/tmux.
  • Claude — AI-agent, utvikler. Kjører direkte på serveren (/home/vegard/synops/).
  • Begge har sudo + docker-tilgang på serveren.

Stack

  • Orkestrator/Backend: Rust (maskinrommet) — kjører native på hosten
  • Frontend: SvelteKit (TypeScript, PWA)
  • Sanntid: SpacetimeDB
  • Database/Graf: PostgreSQL (+Apache AGE ved behov)
  • Binærlagring: CAS (content-addressable store)
  • AI: Claude Code (chat-agent), LiteLLM (AI Gateway), faster-whisper (STT)
  • Infra: Docker (tredjepart), systemd (egenutviklet), Caddy, Authentik (SSO)

Driftsmodell: hybrid native + Docker

Egenutviklet kode kjører native på hosten (systemd). Tredjepartstjenester kjører i Docker. Prinsipp: Docker for det vi ikke bygger selv, native for det vi har full kontroll over.

Native (systemd)

Tjeneste Beskrivelse Deploy
Caddy Reverse proxy + TLS sudo systemctl reload caddy (config: /srv/synops/config/caddy/Caddyfile)
maskinrommet Rust API + jobbkø cargo build --releasesudo systemctl restart maskinrommet
SvelteKit Frontend (når klar) npm run build → systemd

Maskinrommet kjører native fordi det trenger tilgang til claude CLI og hele hosten. Env-filen genereres dynamisk av scripts/maskinrommet-env.sh med Docker container-IPs.

Docker (docker-compose)

Tjeneste Begrunnelse
PostgreSQL Versjonsstyring, enkel oppgradering
SpacetimeDB Eksperimentelt, offisielt image
Authentik Kompleks stack (server + worker + Redis)
LiteLLM Ferdig image, sjelden oppdatering
faster-whisper Modellhåndtering, ferdig image

Kommunikasjon mellom lagene

  • Caddy (native) → Docker-tjenester: via localhost-porter (Authentik:9000, Forgejo:3000, SpacetimeDB:9080)
  • Caddy (native) → native tjenester: direkte localhost (maskinrommet:3100, SvelteKit:3200)
  • Maskinrommet (host) → Docker-tjenester: via container-IP (løses dynamisk i maskinrommet-env.sh)

CLI-verktøy (tools/)

Trenger du et verktøy — lag det. Gjør det generisk, robust og stabilt, så blir det tilgjengelig for maskinrommet (jobbkø) også. Claude og maskinrommet deler verktøykasse.

  • Navnekonvensjon: synops-<verb> (f.eks. synops-transcribe, synops-render)
  • Delt lib: synops-common crate (PG-tilkobling, CAS, node/edge-typer)
  • Dokumentert i tools/README.md
  • Ref: docs/retninger/unix_filosofi.md, docs/infra/agent_api.md

Claude som chat-deltaker

  • Agent-node: d3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44 (node_kind: agent)
  • Trigger: Melding i kommunikasjonsnode der Claude er member_ofagent_respond-jobb → claude -p → svar tilbake i chatten
  • Kill switch: UPDATE agent_identities SET is_active = false WHERE agent_key = 'claude-main'
  • Detaljer: Se docs/infra/claude_agent.md

Produksjonsserver

  • IP: 157.180.81.26
  • SSH: ssh vegard@157.180.81.26
  • Root-login: Deaktivert
  • Server-filer: /srv/synops/ (docker-compose.yml, .env, config/, data/)
  • Domener:
    • sidelinja.org — Tenant-app (Sidelinja podcastredaksjonen)
    • auth.sidelinja.org — Authentik SSO
    • git.sidelinja.org — Forgejo (SSH port 222)
    • vegard.info — Separat nettsted
    • synops.no — Plattformdomene (placeholder, klar for subdomener)

Git

  • Repos i Forgejo:
    • vegard/synops — plattformkode og arkitektur: ssh://git@git.sidelinja.org:222/vegard/synops.git
    • sidelinja/sidelinja — podcastinnhold: ssh://git@git.sidelinja.org:222/sidelinja/sidelinja.git
  • Git-identitet: vegard / vnotnes@pm.me
  • Forgejo-bruker: vegard (admin)
  • CLI: Bruk tea, ikke gh (vi bruker Forgejo, ikke GitHub)

Viktige regler

  • Aldri eksponere databaseporter mot internett
  • All AI-trafikk via maskinrommet, aldri direkte til leverandør-APIer
  • Tunge jobber (Whisper, LLM, TTS) blokkerer aldri brukerforespørsler
  • Sjekk alltid relevant doc i docs/ før implementering
  • Dokumenter lærdommer i docs/erfaringer/

Lagmodell

GUI (SvelteKit) — spatial canvas med verktøy-paneler
  │ skriv              │ les (sanntid, direkte WebSocket)
  ▼                    ▼
Maskinrommet (Rust)    SpacetimeDB ──→ GUI
  │ orkestrerer
  ▼
CLI-verktøy (tools/) ←── Claude bruker de samme
  │
  ▼
Tjenester: PG+AGE, SpacetimeDB, CAS, Whisper, LiteLLM, LiveKit ...

Kjerneprinsipper

  1. Alt er noder og edges. Ingen separate tabeller for chat, kanban, kalender, notater. Visninger er spørringer mot grafen.
  2. Tre primitiver: Input (fanger), Mottak (presenterer), Kommunikasjon (samler folk). Alt annet er visninger og edges.
  3. Maskinrommet orkestrerer, CLI-verktøy gjør jobben. Maskinrommet eier auth, intentions, jobbkø og edge-logikk. All prosessering (transkribering, rendering, AI, lyd) skjer i CLI-verktøy som maskinrommet spawner. Claude bruker de samme verktøyene direkte. Ny funksjonalitet starter som CLI-verktøy, absorberes i orkestratoren, dokumenteres nøye. Ref: docs/retninger/unix_filosofi.md.
  4. Noder er sentrum. Brukere, team, innhold — alt er noder. Du ser dine edges. Tilgang via materialisert tilgangsmatrise.
  5. Privat er default. Input uten mottaker-edge er privat. Security by design, ikke konfigurasjon.
  6. PG er arkivet, SpacetimeDB er nåtid. Ingen eierskapskonflikt. To lag, to roller.
  7. Alt er paneler i en arbeidsflate. Brukergrensesnittet er et spatial canvas der verktøy plasseres, sizes og arrangeres fritt. Hver feature er et panel i BlockShell. Interaksjon mellom paneler via drag-and-drop:
    • Dra ut av kontekst → ny node. Innhold som dras fra et verktøy til et annet skaper en ny node med source_material-edge tilbake.
    • Dra verktøy inn i kontekst → transformer. Et verktøy (AI, editor, studio) som mottar en node anvender sin funksjon på originalen. Ref: docs/retninger/arbeidsflaten.md, docs/features/universell_overfoering.md.