# 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 | 2–3 | | **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. Boten er først og fremst en **samtalepartner** — den svarer på spørsmål, forklarer, diskuterer og hjelper. I tillegg fanger den opp actionable innhold og oppretter noder i bakgrunnen. ### Boten er en generell samtalepartner `@bot` svarer på alt: ``` "Hva betyr CTR?" → Forklaring i chatten. Ingen node. "Lydkvaliteten var dårlig i dag" → Svar + diskusjon i chatten. → work_item i innboks: "Undersøk lydkvalitet" + tagged "bug" "Kan du sjekke om RSS-feeden oppdaterte seg?" → Kjører synops-rss, rapporterer resultat i chatten. "Vi bør legge til kapittelmerkering" → Diskuterer i chatten. → work_item i innboks: "Kapittelmerkering i podcast" + tagged "idea" "Forklar hvordan edge-validering fungerer" → Forklaring i chatten. Ingen node. ``` Brukeren merker bare at de får svar. Noder dukker opp i innboksen i bakgrunnen for Vegard å triagere. ### To output-kanaler 1. **Chat-svar** (alltid) — boten svarer i samtalen 2. **Noder** (når relevant) — boten oppretter work_items, melder fra om feil, fanger opp forslag Kanal 2 er usynlig for brukeren. De ser bare svaret. ### Slik fungerer det 1. En bruker skriver i en kommunikasjonsnode der bot-agenten er `member_of`. 2. Vaktmesteren trigger `agent_respond`-jobb (eksisterende flow). 3. Boten svarer i samtalen. 4. Boten vurderer: er noe her actionable? 5. Hvis ja: oppretter riktig node-type med riktig tag. ### Hva fanges opp? | Innhold | Resultat | Tag | |---------|----------|-----| | Bug / feil / noe virker ikke | work_item + mentions berørt cli_tool | `bug` | | Idé / forslag / "vi bør" | work_item | `idea` | | Feature-forespørsel | work_item | `feature` | | Teknisk gjeld / "dette er rotete" | work_item | `tech-debt` | | Generelt spørsmål | Bare chat-svar, ingen node | — | ### 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) - `tagged`-edge med riktig kategori - `mentions`-edges til berørte noder (verktøy, features) - Eventuelt `assigned_to`-edge til agent-noden (om boten kan gjøre det selv) Vegard triagerer innboksen og prioriterer. ### Ruting `@bot` rutes av vaktmesteren 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 ] [--tag ] synops-tasks --next # neste fra "neste"-kolonnen synops-tasks --claim --write # atomisk: status → pågår + assigned_to synops-tasks --complete --write # status → review synops-tasks --prompt # 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 --write` — ta en oppgave - `synops-tasks --complete --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 Drag-and-drop kolonne psql → direkte SQL Arbeidsflaten │ │ └──────────── PG ──────────────────┘ │ ↕ synk │ PG LISTEN/NOTIFY → WebSocket → sanntid i frontend ``` | Grensesnitt | Leser fra | Skriver til | |-------------|-----------|-------------| | `synops-tasks` CLI | PG direkte | PG direkte | | Web (KanbanTrait) | WebSocket (PG) | Maskinrommet → PG | | `synops-respond` | PG | PG (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.