Oppdater docs og config for native maskinrommet + Claude-agent
- CLAUDE.md: ny driftsmodell-seksjon, maskinrommet native, Claude-agent - docs/infra/claude_agent.md: arkitektur, sikkerhet, drift, oppsett - config/caddy/Caddyfile: synk fra server (host.docker.internal) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
33a1b44946
commit
1dd48317af
3 changed files with 154 additions and 12 deletions
18
CLAUDE.md
18
CLAUDE.md
|
|
@ -56,6 +56,7 @@ CLAUDE.md er eneste startdokument. Alt annet ligger under `docs/`:
|
|||
- `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)
|
||||
|
|
@ -66,13 +67,24 @@ CLAUDE.md er eneste startdokument. Alt annet ligger under `docs/`:
|
|||
- Begge har sudo + docker-tilgang på serveren.
|
||||
|
||||
## Stack
|
||||
- **Orkestrator/Backend:** Rust (maskinrommet)
|
||||
- **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:** LiteLLM (AI Gateway), faster-whisper (STT), ElevenLabs (TTS)
|
||||
- **Infra:** Docker Compose, Caddy, Authentik (SSO)
|
||||
- **AI:** Claude Code (chat-agent), LiteLLM (AI Gateway), faster-whisper (STT)
|
||||
- **Infra:** Docker Compose, Caddy, Authentik (SSO), systemd
|
||||
|
||||
## Driftsmodell
|
||||
- **Maskinrommet** kjører direkte på hosten som systemd-tjeneste (`maskinrommet.service`),
|
||||
ikke i Docker. Dette gir tilgang til `claude` CLI for agent-chat.
|
||||
Bygges med `cargo build --release`, startes med `sudo systemctl restart maskinrommet`.
|
||||
- **Øvrige tjenester** (PG, STDB, Caddy, Authentik, Whisper, LiteLLM) kjører i Docker.
|
||||
- **Caddy** bruker `host.docker.internal` for å nå maskinrommet på hosten.
|
||||
- **Claude som chat-deltaker:** Agent-node (`d3eebc99-...-a44`) i grafen. Legg Claude
|
||||
til som `member_of` i en kommunikasjonsnode → alle meldinger trigger `agent_respond`-jobb
|
||||
→ maskinrommet kaller `claude -p` → svar skrives tilbake i chatten.
|
||||
- **Kill switch:** `UPDATE agent_identities SET is_active = false WHERE agent_key = 'claude-main'`
|
||||
|
||||
## Produksjonsserver
|
||||
- **IP:** 157.180.81.26
|
||||
|
|
|
|||
|
|
@ -4,6 +4,22 @@
|
|||
# Alt annet rutes internt via Docker-nettverket sidelinja-net.
|
||||
# Auto-TLS via Let's Encrypt for alle domener.
|
||||
|
||||
# === Felles favicon-snippet ===
|
||||
(favicon) {
|
||||
handle /favicon.ico {
|
||||
root * /srv/static
|
||||
file_server
|
||||
}
|
||||
handle /apple-touch-icon.png {
|
||||
root * /srv/static
|
||||
file_server
|
||||
}
|
||||
handle /icon-*.png {
|
||||
root * /srv/static
|
||||
file_server
|
||||
}
|
||||
}
|
||||
|
||||
# === SSO ===
|
||||
auth.sidelinja.org {
|
||||
reverse_proxy authentik-server:9000
|
||||
|
|
@ -11,6 +27,8 @@ auth.sidelinja.org {
|
|||
|
||||
# === Sidelinja (hovedapplikasjon) ===
|
||||
sidelinja.org {
|
||||
import favicon
|
||||
|
||||
# SpacetimeDB (WebSocket)
|
||||
handle_path /spacetime/* {
|
||||
reverse_proxy spacetimedb:3000
|
||||
|
|
@ -28,18 +46,13 @@ sidelinja.org {
|
|||
# Aktiveres når SvelteKit-containeren er klar (fase 3)
|
||||
# reverse_proxy sveltekit:3000
|
||||
|
||||
# Placeholder til SvelteKit er deployet
|
||||
respond "sidelinja.org — Synops v2 under utvikling" 200
|
||||
header Content-Type text/html
|
||||
respond `<!DOCTYPE html><html><head><meta charset="utf-8"><title>sidelinja.org</title><link rel="icon" href="/favicon.ico" sizes="32x32"><link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192"><link rel="apple-touch-icon" href="/apple-touch-icon.png"></head><body><p>sidelinja.org — underveis!</p></body></html>` 200
|
||||
}
|
||||
|
||||
# === Maskinrommet API ===
|
||||
api.sidelinja.org {
|
||||
# Rust/axum backend (fase 2)
|
||||
# Aktiveres når maskinrommet-containeren er klar
|
||||
# reverse_proxy maskinrommet:3001
|
||||
|
||||
# Placeholder til maskinrommet er deployet
|
||||
respond "api.sidelinja.org — ikke tilgjengelig ennå" 503
|
||||
reverse_proxy host.docker.internal:3100
|
||||
}
|
||||
|
||||
# === Forgejo (Git) ===
|
||||
|
|
@ -47,7 +60,20 @@ git.sidelinja.org {
|
|||
reverse_proxy forgejo:3000
|
||||
}
|
||||
|
||||
# === Synops (plattformdomene) ===
|
||||
# Subdomener (api.synops.no, auth.synops.no osv.) legges til individuelt
|
||||
# etter behov — HTTP-challenge fungerer per subdomain uten DNS-plugin.
|
||||
synops.no {
|
||||
import favicon
|
||||
|
||||
header Content-Type text/html
|
||||
respond `<!DOCTYPE html><html><head><meta charset="utf-8"><title>synops.no</title><link rel="icon" href="/favicon.ico" sizes="32x32"><link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192"><link rel="apple-touch-icon" href="/apple-touch-icon.png"></head><body><p>synops.no — underveis!</p></body></html>` 200
|
||||
}
|
||||
|
||||
# === Vegard.info ===
|
||||
vegard.info {
|
||||
respond "vegard.info — under construction" 200
|
||||
import favicon
|
||||
|
||||
header Content-Type text/html
|
||||
respond `<!DOCTYPE html><html><head><meta charset="utf-8"><title>vegard.info</title><link rel="icon" href="/favicon.ico" sizes="32x32"><link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192"><link rel="apple-touch-icon" href="/apple-touch-icon.png"></head><body><p>vegard.info — underveis!</p></body></html>` 200
|
||||
}
|
||||
|
|
|
|||
104
docs/infra/claude_agent.md
Normal file
104
docs/infra/claude_agent.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# Infrastruktur: Claude som chat-deltaker
|
||||
|
||||
## Oversikt
|
||||
|
||||
Claude deltar i samtaler som en agent-node i grafen. Når en bruker sender
|
||||
en melding i en kommunikasjonsnode der Claude er deltaker, trigger maskinrommet
|
||||
en `agent_respond`-jobb som kaller `claude -p` CLI og skriver svaret tilbake.
|
||||
|
||||
## Arkitektur
|
||||
|
||||
```
|
||||
Bruker sender melding (via frontend)
|
||||
→ create_node() i maskinrommet
|
||||
→ sjekker: har kommunikasjonsnoden en agent-deltaker?
|
||||
→ ja: enqueue agent_respond-jobb (prioritet 8)
|
||||
→ jobbkø-worker plukker opp (poll hvert 2s)
|
||||
→ kaller: claude -p "<prompt>" --output-format json --dangerously-skip-permissions
|
||||
→ parser JSON-respons, henter result-feltet
|
||||
→ skriver svar som content-node (STDB instant + PG async)
|
||||
→ frontend viser melding i sanntid via STDB WebSocket
|
||||
```
|
||||
|
||||
Latens: ~3-5 sekunder fra melding til svar.
|
||||
|
||||
## Noder og tabeller
|
||||
|
||||
### Claude-noden
|
||||
- **UUID:** `d3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44`
|
||||
- **node_kind:** `agent`
|
||||
- **visibility:** `discoverable`
|
||||
|
||||
### agent_identities
|
||||
Kobler agent-noder til konfigurasjon og nøkkel.
|
||||
|
||||
| Felt | Verdi |
|
||||
|------|-------|
|
||||
| agent_key | `claude-main` |
|
||||
| agent_type | `claude` |
|
||||
| config | max_context_messages, rate_limit_per_hour, etc. |
|
||||
|
||||
### agent_permissions
|
||||
Autorisasjonsnivåer per bruker/agent-par.
|
||||
|
||||
| Nivå | Betydning |
|
||||
|------|-----------|
|
||||
| `direct` | Kan bestille endringer som implementeres direkte |
|
||||
| `propose` | Kan foreslå endringer som krever godkjenning |
|
||||
|
||||
### ai_usage_log
|
||||
Logger hvert agent-svar med timestamps, job_id, og kommunikasjons-ID.
|
||||
|
||||
## Sikkerhet
|
||||
|
||||
| Mekanisme | Beskrivelse |
|
||||
|-----------|-------------|
|
||||
| **Kill switch** | `agent_identities.is_active = false` stopper all aktivitet |
|
||||
| **Rate limiting** | Maks 60 responser per time (konfigurerbart) |
|
||||
| **Loop-prevensjon** | Stopper hvis siste 3 meldinger er fra agenten |
|
||||
| **Egne meldinger** | Svarer aldri på egne meldinger (sjekk i trigger) |
|
||||
|
||||
## Oppsett av ny chat med Claude
|
||||
|
||||
```sql
|
||||
-- 1. Opprett kommunikasjonsnode
|
||||
INSERT INTO nodes (id, node_kind, title, visibility, metadata, created_by)
|
||||
VALUES ('<uuid>', 'communication', 'Min chat med Claude', 'hidden', '{}', '<bruker-uuid>');
|
||||
|
||||
-- 2. Legg til bruker som owner
|
||||
INSERT INTO edges (id, source_id, target_id, edge_type, metadata, system, created_by)
|
||||
VALUES ('<uuid>', '<bruker-uuid>', '<comm-uuid>', 'owner', '{}', false, '<bruker-uuid>');
|
||||
|
||||
-- 3. Legg til Claude som member_of
|
||||
INSERT INTO edges (id, source_id, target_id, edge_type, metadata, system, created_by)
|
||||
VALUES ('<uuid>', 'd3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44', '<comm-uuid>', 'member_of', '{}', false, '<bruker-uuid>');
|
||||
|
||||
-- 4. Recompute access
|
||||
SELECT recompute_access('<bruker-uuid>', '<comm-uuid>', 'owner', '<owner-edge-uuid>');
|
||||
SELECT recompute_access('d3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44', '<comm-uuid>', 'member', '<member-edge-uuid>');
|
||||
```
|
||||
|
||||
Etter dette vil alle meldinger i chatten automatisk trigge Claude-svar.
|
||||
|
||||
## Drift
|
||||
|
||||
Maskinrommet kjører som systemd-tjeneste direkte på hosten:
|
||||
|
||||
```bash
|
||||
sudo systemctl status maskinrommet # status
|
||||
sudo systemctl restart maskinrommet # restart etter ny build
|
||||
sudo journalctl -u maskinrommet -f # live-logger
|
||||
```
|
||||
|
||||
Bygg og deploy:
|
||||
```bash
|
||||
cd ~/synops/maskinrommet && cargo build --release
|
||||
sudo systemctl restart maskinrommet
|
||||
```
|
||||
|
||||
## Faser
|
||||
|
||||
- **Fase A (MVP):** Chat-agent — implementert og verifisert
|
||||
- **Fase B:** Autorisasjon og oppgaver (direct vs propose flyt)
|
||||
- **Fase C:** Autonom implementering (claude Code som subprocess for kode-endringer)
|
||||
- **Fase D:** @mentions, typing-indikator, admin-panel
|
||||
Loading…
Add table
Reference in a new issue