synops/docs/concepts/arbeidstavlen.md
vegard 23c63c2458 Implementer synops-node CLI-verktøy (oppgave 21.14)
Nytt CLI-verktøy for å hente og vise en node med alle tilkoblede edges.
Støtter rekursiv graf-traversering (--depth) og to output-formater
(markdown og JSON). Brukes av Claude og maskinrommet for å inspisere
graf-tilstand.

Features:
- Hent node med alle edges (inn og ut)
- Berik edges med peer-tittel og node_kind for lesbarhet
- --depth 0: bare noden, --depth 1: + edges (default), --depth 2+: traverser
- --format md (default) eller json
- Kompakt metadata-visning, forkortet innhold

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:24:43 +00:00

355 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Konsept: Arbeidstavlen (Prosjektstyring)
**Filsti:** `docs/concepts/arbeidstavlen.md`
## 1. Konsept
Alt prosjektarbeid i Synops — oppgaver, bugs, ideer, forslag,
feature-forespørsler — er noder i PostgreSQL. Én kanban-tavle
organiserer arbeidet. Claude og Vegard deler samme data via CLI
og web. Arbeidselementer oppstår organisk fra samtaler, manuelt
input, eller systemhendelser.
## 2. Hvorfor
`tasks.md` var en pragmatisk bootstrap. Den har tre fundamentale
problemer:
1. **Race conditions.** Flere Claude-instanser redigerer samme fil
samtidig. Endringer overskrives, status forsvinner, git-konflikter
oppstår.
2. **Fragil parsing.** Bash-scripts parser markdown med regex
(`grep -P '^\- \[~\]'`). Formateringsendringer knekker parseren.
3. **Frakoblet fra grafen.** Oppgaver kan ikke lenkes til samtaler,
dokumenter, eller personer via edges. De lever utenfor
datamodellen.
Løsningen: arbeidselementer er noder. De deltar i grafen som alt
annet. De har edges til samtaler (hvor ideen kom fra), til
personer (hvem som jobber), til dokumenter (hva de implementerer),
og til hverandre (foreldre/barn).
## 3. Nodemodell
Arbeidselementer bruker `node_kind: 'work_item'`:
```
work_item-node:
title: "Forbedre lydkvalitet ved opptak"
content: "Brukere rapporterer at ..." (ren tekst, søkbar)
metadata: {
"size": "small", // small | medium | large
"origin": "chat" // chat | manual | system
}
```
### Kategorisering via edges, ikke typer
Det finnes ingen `node_kind` per kategori (task, bug, idea).
Distinksjonen gjøres med `tagged`-edges:
```
work_item ──tagged──→ board { "tag": "bug" }
work_item ──tagged──→ board { "tag": "idea" }
work_item ──tagged──→ board { "tag": "feature" }
work_item ──tagged──→ board { "tag": "tech-debt" }
```
Dette følger eksisterende filosofi: edges definerer hva en node er,
ikke noden selv.
### Størrelse er organisk
Ingen tvungen hierarki-klassifisering. Et element starter som
`small` og vokser:
```
"Fiks fade-bug" → small (én commit)
"Redesign lydpipeline" → medium (noen timer)
"Redesign lydpipeline" → large (har fått barn-items)
├── belongs_to: "Nytt EDL-format"
├── belongs_to: "FFmpeg wrapper"
└── belongs_to: "Oppdater studio-UI"
```
Samme tekst-primitiv-filosofi: en node kan vokse.
## 4. Edge-modell
| Edge-type | Source → Target | Metadata | Betydning |
|-----------|----------------|----------|-----------|
| `belongs_to` | work_item → board | `{ "position": 1.5 }` | Kortet tilhører tavlen |
| `status` | work_item → board | `{ "value": "neste" }` | Kolonneplassering |
| `assigned_to` | work_item → person/agent | — | Hvem jobber på dette |
| `belongs_to` | work_item → work_item | `{ "position": 1.0 }` | Deloppgave |
| `source_material` | work_item → content | `{ "context": "summarized", "excerpt": "..." }` | Hvor ideen kom fra |
| `tagged` | work_item → board | `{ "tag": "bug" }` | Kategorisering |
| `mentions` | work_item → any node | — | Relatert dokument/feature |
`assigned_to` er en ny edge-type. Retning: work_item → person.
Semantikk: "dette elementet er tildelt denne personen/agenten."
Barn-items har sin egen `status`-edge. Et barn kan være ferdig
mens forelderen fortsatt er i arbeid.
## 5. Kanban-oppsettet
Tavlen er en `collection`-node med `kanban`-trait:
```jsonc
{
"node_kind": "collection",
"title": "Synops Arbeidstavle",
"metadata": {
"traits": {
"kanban": {
"columns": ["innboks", "backlog", "neste", "pågår", "review", "ferdig"]
}
}
}
}
```
### Kolonnesemantikk
| Kolonne | Hva | Hvem styrer | WIP-grense |
|---------|-----|-------------|------------|
| **Innboks** | Ubehandlede elementer fra chat og automatikk | System/@bot | Ingen |
| **Backlog** | Vurdert, ikke prioritert. Kan være hundrevis | Vegard | Ingen |
| **Neste** | Prioritert og klar. Claude plukker herfra | Vegard | ~10 |
| **Pågår** | Noen jobber aktivt på dette | Claude/Vegard | 23 |
| **Review** | Implementert, venter på Vegards sjekk | Claude | ~5 |
| **Ferdig** | Arkivert. Alltid søkbart | System | Ingen |
### Bevegelsesregler
```
Innboks → Backlog/Neste Vegard triagerer
Backlog → Neste Vegard prioriterer
Neste → Pågår Claude/Vegard starter. assigned_to-edge opprettes
Pågår → Review Claude ferdig. Commits refererer work_item UUID
Review → Ferdig Vegard bekrefter
Review → Pågår Vegard ber om endringer
Enhver → Backlog Deprioritering
```
### Backlog-visning
Backlog trenger ikke være kanban. Hundrevis av elementer er
bedre i en filtrert listevisning med søk, tags og sortering.
Bare **Neste → Pågår → Review → Ferdig** er aktive kanban-lanes.
## 6. @bot-konvensjonen
`@bot` er Synops sin generiske markør for AI-assistanse i
samtaler. Ruteren i maskinrommet bestemmer hvilken modell eller
agent som svarer — brukeren trenger ikke vite om det er Claude,
en annen modell, eller en spesialisert agent.
### Slik fungerer det
1. En bruker skriver i en kommunikasjonsnode der bot-agenten er
`member_of`.
2. Maskinrommet trigger `agent_respond`-jobb (eksisterende flow).
3. Boten svarer i samtalen.
4. **Nytt:** Hvis samtalen inneholder actionable innhold, oppretter
boten også `work_item`-noder.
### Når opprettes work items?
Deteksjonsheuristikker (i `synops-respond` eller et nytt
`synops-triage`-verktøy):
- Imperative setninger: "Fiks ...", "Legg til ...", "Vi bør ..."
- Spørsmål som impliserer arbeid: "Kan vi endre ...?"
- Eksplisitte markører: "TODO:", "oppgave:", "ide:"
### Hva opprettes?
For hvert actionable element:
- `work_item`-node med tittel og beskrivelse
- `belongs_to`-edge → arbeidstavlen
- `status`-edge med `value: "innboks"`
- `source_material`-edge → chat-meldingen (proveniens)
- Eventuelt `assigned_to`-edge til agent-noden (om boten kan
gjøre det selv)
Vegard triagerer innboksen og prioriterer.
### Ruting
`@bot` rutes av maskinrommet basert på kontekst:
- Standard: Claude (nåværende `agent_respond`-flyt)
- Fremtidig: spesialiserte agenter, andre modeller, eller
regelbaserte svar — uten endring i brukergrensesnittet
## 7. Task runner og jobbhenting
### CLI: `synops-tasks`
```bash
synops-tasks --list [--status <status>] [--tag <tag>]
synops-tasks --next # neste fra "neste"-kolonnen
synops-tasks --claim <uuid> --write # atomisk: status → pågår + assigned_to
synops-tasks --complete <uuid> --write # status → review
synops-tasks --prompt <uuid> # generer prompt for autonom sesjon
```
`--claim` bruker `SELECT ... FOR UPDATE` for atomisk status-
endring. Ingen race conditions.
### Task runner
`run-next-task.sh` blir en tynn wrapper:
```bash
TASK_JSON=$(synops-tasks --next --format json)
TASK_ID=$(echo "$TASK_JSON" | jq -r '.id')
synops-tasks --claim "$TASK_ID" --write
claude -p --dangerously-skip-permissions \
"$(synops-tasks --prompt "$TASK_ID")"
synops-tasks --complete "$TASK_ID" --write
```
### Stale-deteksjon
Items som har stått i "pågår" lenger enn 60 minutter uten
commit frigjøres tilbake til "neste":
```bash
synops-tasks --unstale --write
```
## 8. CLAUDE.md som bootstrap
CLAUDE.md forblir prosjektets startdokument — det lastes alltid
inn i konteksten. Strukturen beholdes i hovedsak, men
oppgavehenting endres:
**Erstatt tasks.md-referanser med:**
```markdown
## Arbeidshenting
Oppgaver hentes fra arbeidstavlen (PG). Bruk CLI:
- `synops-tasks --next` — vis neste oppgave
- `synops-tasks --list` — vis hele tavlen
- `synops-tasks --claim <uuid> --write` — ta en oppgave
- `synops-tasks --complete <uuid> --write` — marker ferdig
Task runner: `./scripts/run-next-task.sh`
Se `docs/concepts/arbeidstavlen.md` for full spesifikasjon.
```
Doc-treet i CLAUDE.md beholdes — det er verdifull navigasjon.
Endringen er kirurgisk: erstatt oppgaverelaterte instruksjoner.
## 9. Migrering fra tasks.md
### Steg 1: Opprett arbeidstavle-noden
Én `collection`-node med kanban-trait og seks kolonner.
Fast UUID som dokumenteres i CLAUDE.md.
### Steg 2: Migrer gjenstående oppgaver
Script leser `tasks.md`, oppretter `work_item`-noder for
gjenstående `- [ ]`-elementer. Ferdigstilte `[x]`-elementer
kan migreres til "ferdig" for historikk, eller forbli i
`tasks.md` som lesbart arkiv i git-historikken.
Fase- og avhengighetsinfo overføres til `metadata` og
`belongs_to`-edges mellom relaterte items.
### Steg 3: Switch task runner
`run-next-task.sh` bruker `synops-tasks` i stedet for
markdown-parsing. `tasks.md` redigeres ikke lenger.
## 10. CLI og web: samme data
```
Terminal (Claude/Vegard) Web (SvelteKit)
│ │
synops-tasks --list KanbanTrait panel
synops-tasks --claim <uuid> Drag-and-drop kolonne
psql → direkte SQL Arbeidsflaten
│ │
└──────────── PG ──────────────────┘
↕ synk
SpacetimeDB → WebSocket → sanntid i frontend
```
| Grensesnitt | Leser fra | Skriver til |
|-------------|-----------|-------------|
| `synops-tasks` CLI | PG direkte | PG direkte |
| Web (KanbanTrait) | SpacetimeDB | Maskinrommet → PG + STDB |
| `synops-respond` | PG | PG + STDB (via maskinrommet) |
Ingen nytt UI trengs — arbeidstavlen er bare en `collection`-node
med kanban-trait. Vegard ser den på arbeidsflaten ved siden av
andre paneler.
## 11. Komponenter
| Feature | Rolle i Arbeidstavlen |
|---------|----------------------|
| Kanban (trait) | Visuell tavle med kolonner og drag-and-drop |
| Chat | @bot i samtaler skaper arbeidselementer |
| `synops-tasks` CLI | Claude og scripts henter/oppdaterer arbeid |
| `synops-respond` | Boten oppretter work_items fra chat-innsikt |
| Jobbkø | `run-next-task.sh` orkestrerer autonome sesjoner |
## 12. Utviklingsfaser
1. Opprett arbeidstavle-noden i PG med kanban-trait og seks kolonner.
2. Implementer `synops-tasks` CLI (list, next, claim, complete, prompt).
3. Migrer gjenstående oppgaver fra `tasks.md`.
4. Oppdater `run-next-task.sh` til å bruke `synops-tasks`.
5. Utvid `synops-respond` til å opprette work_items fra chat.
6. Oppdater CLAUDE.md med ny arbeidshenting-seksjon.
## 13. Fallback: `synops-snapshot`
PG nede betyr at Claude mister tilgang til verktøyoversikt,
arbeidstavle og arkitektur-noder. Løsningen er en generert
snapshot-fil som alltid ligger i repo:
```bash
synops-snapshot --write
→ Kobler til PG
→ Henter: cli_tool-noder, work_items (neste/pågår/review),
arbeidstavle-status, aktive agenter
→ Skriver til docs/snapshot.md
→ Deterministisk output — ingen diff hvis ingenting endret seg
```
### Når den kjøres
- **Automatisk:** Post-hook i `run-next-task.sh` etter hver oppgave
- **Periodisk:** Cron (hvert 5. minutt) som sikkerhetsnett
- **Manuelt:** `synops-snapshot --write` ved behov
### Hva den inneholder
- Alle `cli_tool`-noder med usage og metadata
- Arbeidstavle-status (antall per kolonne, items i neste/pågår)
- Siste endringer (nyeste work_items)
- Tidsstempel for når snapshot ble generert
### CLAUDE.md-referanse
```markdown
## Fallback-kontekst
Hvis PG er utilgjengelig, se `docs/snapshot.md` for siste kjente
tilstand. Generert av `synops-snapshot`. Ikke rediger manuelt.
```
Filen committes og pushes som del av normal arbeidsflyt.
`synops-snapshot` er selv et CLI-verktøy og en `cli_tool`-node
i grafen.
## 14. Avgrensning
- Arbeidstavlen erstatter `tasks.md` for prosjektstyring.
Den erstatter **ikke** docs-filer — arkitektur, retninger,
feature-specs og konseptdokumenter lever fortsatt som
markdown i `docs/`.
- `@bot` er en chat-konvensjon, ikke en ny primitiv. Den bruker
eksisterende `member_of`-edge og `agent_respond`-flyt.
- Work items er noder i grafen — ikke en separat
prosjektstyringsmodul. De følger alle regler for noder,
edges, visibility og tilgangskontroll.