PG NOTIFY fyrer ved COMMIT. Når alt skrives i én transaksjon
eksisterer node_access allerede når WS mottar node_changed,
og kan levere noden til alle deltakere i sanntid.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
To spor for agent-respons:
1. Permanent: agent er member_of → svar på alle meldinger
2. @bot-nevnelse: bruker skriver @bot → engangs-svar, agent
trenger ikke være deltaker
Femkompis-problemet løst: @bot i en gruppechat gir ett svar,
ikke evig bot-loop. Dedikerte bot-chatter (member_of) fungerer
som før.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bot-svar var usynlige fordi node_access ikke ble propagert.
Alle deltakere i chatten (owner/member_of) får nå reader-access
til svar-noder. Erfaringsnotat dokumenterer mønsteret.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Handler-moduser (internal/external/paused), chat-ID, scripts,
start/stopp-prosedyrer, feilsøking. Alt en ny sesjon trenger
for å starte polling uten forkunnskaper.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tre moduser i agent_identities.handler_mode:
- internal: maskinrommet kjører synops-respond (eksternt API)
- external: jobb settes til 'deferred', forblir urørt for Claude Code
- paused: svar bruker med "AI utilgjengelig", marker done
Jobbkøen overskriver ikke deferred-status (sjekker result.status).
Ny job_status 'deferred' i PG enum.
Scripts: vaktmester-poll.sh (finn deferred jobber),
vaktmester-complete.sh (marker behandlet).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
WebSocket-filtrering brukte statisk visible_nodes-cache som ikke
inneholdt nye noder. For INSERT-events sjekkes nå node_access i PG
direkte, og noden legges til i cachen. Løser timing-problemet der
node_changed kom før access_changed.
chat-reply.sh: skriv melding som Claude Code med access-propagering.
agent.rs: jobb opprettes uansett kill-switch, deferred for ekstern handler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fjern X-Frame-Options fra Forgejo og Authentik, erstatt med
Content-Security-Policy: frame-ancestors 'self' *.synops.no.
Web Viewer kan nå vise Git og Auth inne i arbeidsflaten.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Vis en URL i en iframe inne i en BlockShell. URL-bar med
navigasjon (tilbake/frem/oppdater), bokmerker for vanlige
sider (admin, auth, git, synops.no). Sandbox for sikkerhet.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Canvas: keyboard-events ignoreres når bruker skriver i input/textarea.
Space fungerer nå i søkefelt og tekstredigering.
Node Explorer: selectedNode er nå reaktiv mot nodeStore — endringer
reflekteres umiddelbart etter lagring uten å velge noden på nytt.
✏️-knapp vises bare for noder brukeren eier.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
✕ på søk/filter for rask reset. ✏️ for inline redigering av
tittel, innhold og metadata (JSON). Lagre via updateNode API.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Canvas handlePointerDown ignorerer klikk inne i .blockshell-content.
Inputs, knapper, selects og lister i paneler fungerer normalt.
Bare headeren starter Canvas-drag.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reset til 100% justerer kameraposisjon slik at det du ser i
midten forblir i midten. Gjelder dobbeltklikk og toolbar-knapp.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Canvas: scroll=pan, Ctrl+scroll=zoom, piltaster, dblclick=100%.
BlockShell: Ctrl+scroll zoomer panel-innhold.
Nye paneler plasseres i viewport-sentrum, ikke utenfor bildet.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Seks prinsipper inline i CLAUDE.md: forstå hvorfor, ikke hardkod
det dynamiske, én fiks ikke workarounds, preferer fjerning,
én mekanisme per problem, gjør det riktig én gang.
Utdypning i docs/retninger/kvalitetsprinsipper.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Retningslinje for kode og konfigurasjon. Ti prinsipper:
ikke hardkod det dynamiske, forstå hvorfor noe fungerer,
én mekanisme per problem, konfigurer på lavest nivå,
wildcard over spesifikk, sjekkliste for nye domener,
test med andre øyne, dokumenter beslutninger, preferer
fjerning over tillegg, én fiks ikke to workarounds.
Motivert av ORIGIN-fellen ved multi-subdomain.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dropdown viser begge arbeidsflater med absolutte URLer
(ws.synops.no og adm.synops.no). Navigasjon mellom subdomener
fungerer uten å miste sesjon.
Erfaringsnotat: multi-subdomain med SvelteKit — ORIGIN-fellen,
cookie-domene, CSRF, OIDC redirect URIs, sjekkliste for nye
subdomener.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ORIGIN=https://ws.synops.no tvang SvelteKit til å sette url.hostname
til ws.synops.no for ALLE requests. Fjernet ORIGIN — AUTH_TRUST_HOST=true
lar SvelteKit lese hostname fra Host-headeren, som gir korrekt
adm.synops.no-deteksjon.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
event.locals.isAdminHost fra hooks ble ikke pålitelig overført.
Sjekker event.url.hostname direkte i stedet.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Header viser "Administrasjon" i stedet for "Hjem" på adm.synops.no
- Tom-tilstand foreslår admin-verktøy (Nodeutforsker, Forbruk, AI)
- homeLabel prop i ContextHeader for konfigurerbar tittel
- isAdminHost fra layout server → +page.svelte
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Session-cookie settes på .synops.no slik at login på ws.synops.no
også gjelder for adm.synops.no. Berettiget nå med to subdomener
som trenger samme sesjon. CSRF-token forblir host-bound (__Host-).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ORIGIN er hardkodet til ws.synops.no, men adm.synops.no trenger
også POST (auth callback). CSRF ivaretatt av OIDC PKCE+state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ny trait: NodeExplorerTrait — søk og utforsk noder med edges.
Split-visning: nodeliste til venstre, detaljer til høyre.
Filtrer på node_kind, søk i tittel/innhold/ID.
Klikk edges for å navigere i grafen.
adm.synops.no setter isAdminHost flag via hooks/layout.
Registrert i TRAIT_PANEL_INFO som 'node_explorer'.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nytt subdomain for admin. Caddy ruter til SvelteKit.
Hooks redirecter adm.synops.no/ til /admin.
Authentik OIDC redirect URI lagt til.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Admin er ikke et separat system — det er en arbeidsflate med
admin-traits. Samme canvas, samme BlockShell, samme SvelteKit.
adm.synops.no som eget domene med admin-rolle-krav.
13 admin-traits: node explorer, oppgavetavle, jobbkø, API-nøkler,
brukeradmin, AI-ruting, serverhelse, forbruk, logger, systemkonfig,
webhooks, podcast-import, podcaststatistikk.
Noen traits delt mellom admin og brukere med ulik tilgang.
Eksisterende /admin/*-sider migreres til traits.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tre nye node-typer for oppgavestyring:
- proposal: status (draft/discussed/approved/rejected/parked)
- assignment: status (open/planning/active/paused/done/blocked) + priority
- task: status (open/active/done/failed/skipped) + priority
Validering i create_node og update_node. Ingen ny tabell —
bruker eksisterende nodes-tabell med metadata.
Ref: docs/infra/oppgaver.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Konfigurerbare brukerklasser (Basis, Proff(ish), Superduper ultra
premium, Admin) med token-budsjett per dag, modellnivå-tilgang og
feature-gates. Budsjettsjekk før hvert LLM-kall. Admin-forbruk
vises med kostnadsestimat. Automatiske triggere teller mot
brukerens budsjett. Klasser og brukere som noder i grafen.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Ny «Nivåer»-fane i /admin/ai med synops/low, medium, high, extreme
- Per-nivå: fallback-kjede, provider-administrasjon, kostnadsestimat
- Test-knapp sender prompt gjennom LiteLLM og viser respons, latens, tokens, kostnad
- Backend: POST /admin/ai/test_prompt + GET /admin/ai/tier_costs
- Migration 033: oppretter de fire synops/* aliasene med providers
Sjekker at det faktisk ble committet kodeendringer (utenom tasks/)
før oppgaven markeres som fullført. Oppgaver uten kodeendring
flyttes tilbake til køen. Forhindrer falske "Task fullført".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Task-runneren markerte oppgaver som ferdige uten å implementere dem.
Claude Code-sesjonene avsluttet uten kode, men scriptet tolket det
som suksess. 18 oppgaver beholdt som ekte fullført (verifisert med
kodeendringer). 37 flyttes tilbake for reell implementering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>