Fjernet fil-basert oppgaveliste (tasks.md, tasks-arkiv.md, tasks/). Oppgaver er nå noder (node_kind: 'task') med prioritet, status, agent-tildeling og krasj-deteksjon via PG. Atomisk plukking med FOR UPDATE SKIP LOCKED. Dokumentert i docs/infra/oppgaver.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 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.
- Defensiv skriving: Skriv planer, arbeidsstatus og mellomresultater
til disk underveis (f.eks.
docs/fikseliste.mdeller en dedikert fil idocs/). Kontekst kan forsvinne ved planmodus-reset eller krasj. Neste instans skal kunne lese seg opp fra filene og fortsette. - Oppgaver: Oppgaver er noder i grafen (
node_kind: 'task'). Plukkes av agenter via PG-query, ikke filer. Sedocs/infra/oppgaver.md.
Dokumentasjonstre
CLAUDE.md er eneste startdokument. Oppgavelister i roten, docs under docs/:
-
docs/infra/oppgaver.md— Oppgaver som noder i grafen -
docs/arkitektur.md— Overordnet arkitektur, lagmodell, teknologivalg -
docs/retninger/— Arkitektoniske teser og vedtatte retninger:README.md— Oversikt og statusstatus_quo.md— Hva v1 var: ambisiøse primitiver, tradisjonell overflaterom_ikke_forum.md— Opplevelse-først, to-lags-modell, administrativ opplevelseuniversell_input.md— Tre primitiver (input, mottak, kommunikasjon), noder+edgesmaskinrommet.md— Rust-orkestrator: fang, prosesser, leverbruker_ikke_workspace.md— Noder er sentrum: brukere, team, innhold er noder. Tilgangsmatrise fra edges.datalaget.md— PG(+AGE) som graf og arkiv, PG LISTEN/NOTIFY + WebSocket som sanntidslagarbeidsflaten.md— Spatial canvas med verktøy-paneler, drag-and-drop, kompatibilitetsmatriseunix_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, eierskapedges.md— Edge-skjema, typer, metadata, systemedgestraits.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,arbeidstavlen.md,selvdokumenterende_system.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 prosesseringartikkelverktoy.md— Langform TipTap-editor, drag-and-drop mottak, source_material-edgesuniversell_overfoering.md— Drag-and-drop mellom verktøy-paneler, kompatibilitetsmatrise
-
docs/fikseliste.md— UI-bugs og forbedringer (levende jobbliste for grensesnitt) -
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 scratchlokal.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 workerjobbkø.md— PostgreSQL-basert køsystem for bakgrunnsjobbersynkronisering.md— Historisk: PG ↔ SpacetimeDB dataflyt (arkivdokument, SpacetimeDB fjernet mars 2026)claude_agent.md— Claude som chat-deltaker: arkitektur, triggere, sikkerhetobserverbarhet.md— Strukturert logging, metrikk-endepunkt (/metrics), AI-kostnadoppgaver.md— Oppgaver som noder: prioritet, status, agent-plukking, krasj-deteksjon
-
docs/erfaringer/— Lærdommer fra v1 (Svelte 5, Authentik). STDB-docs arkivert iarkiv/ -
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: PG LISTEN/NOTIFY + WebSocket (portvokteren)
- 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 --release → sudo 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 |
| 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)
- 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-commoncrate (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_of→agent_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 (synops.no er primær):
synops.no— Offentlig landingsside + /pub/* + /media/* (Caddy → statisk + maskinrommet)ws.synops.no— Appen (SvelteKit + /api/* → maskinrommet). Krever login.auth.synops.no— Authentik SSOapi.synops.no— Maskinrommet direkte (CLI, webhooks, eksternt)git.synops.no— Forgejo (SSH port 222)vegard.info— Personlig nettsted (statisk)sidelinja.org— Redirect til synops.noworkspace.synops.no— Legacy redirect til ws.synops.no*.sidelinja.org— Legacy aliaser (auth, api, git)
Git
- Repos i Forgejo:
vegard/synops— plattformkode og arkitektur:ssh://git@git.synops.no:222/vegard/synops.gitsidelinja/sidelinja— podcastinnhold:ssh://git@git.synops.no:222/sidelinja/sidelinja.git
- Git-identitet: vegard / vnotnes@pm.me
- Forgejo-bruker: vegard (admin)
- CLI: Bruk
tea, ikkegh(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 via WebSocket)
▼ ▲
Maskinrommet (Rust) ───┘ PG LISTEN/NOTIFY → WebSocket → GUI
│ orkestrerer
▼
CLI-verktøy (tools/) ←── Claude bruker de samme
│
▼
Tjenester: PG+AGE, CAS, Whisper, LiteLLM, LiveKit ...
Kjerneprinsipper
- Alt er noder og edges. Ingen separate tabeller for chat, kanban, kalender, notater. Visninger er spørringer mot grafen.
- Tre primitiver: Input (fanger), Mottak (presenterer), Kommunikasjon (samler folk). Alt annet er visninger og edges.
- 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. - Noder er sentrum. Brukere, team, innhold — alt er noder. Du ser dine edges. Tilgang via materialisert tilgangsmatrise.
- Privat er default. Input uten mottaker-edge er privat. Security by design, ikke konfigurasjon.
- PG er sannhetskilden. All data lever i PostgreSQL. Sanntid via PG LISTEN/NOTIFY + WebSocket i portvokteren.
- 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.
- Dra ut av kontekst → ny node. Innhold som dras fra et verktøy
til et annet skaper en ny node med