Legg til task-liste og autonom runner for implementering
tasks.md: 51 oppgaver i 12 faser med avhengighetskart og statusmarkører ([?] for åpne spørsmål, [!] for blokkert). run-next-task.sh: plukker neste tilgjengelige oppgave, hopper over blokkerte faser og deres avhengigheter, starter fersk Claude Code-sesjon med full kontekst-prompt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c1d3ad66a5
commit
43fc267089
2 changed files with 317 additions and 0 deletions
193
scripts/run-next-task.sh
Executable file
193
scripts/run-next-task.sh
Executable file
|
|
@ -0,0 +1,193 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Plukker neste ugjorte oppgave fra tasks.md og starter en Claude Code-sesjon.
|
||||||
|
# Hopper over oppgaver med [?] (åpent spørsmål) eller [!] (blokkert),
|
||||||
|
# og oppgaver som avhenger av blokkerte faser.
|
||||||
|
#
|
||||||
|
# Bruk:
|
||||||
|
# ./scripts/run-next-task.sh # kjør neste oppgave
|
||||||
|
# ./scripts/run-next-task.sh --dry # vis hvilken oppgave som er neste
|
||||||
|
# ./scripts/run-next-task.sh --status # vis status for alle oppgaver
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
TASKS="$ROOT/tasks.md"
|
||||||
|
|
||||||
|
# --- Avhengighetskart: fase → faser den avhenger av ---
|
||||||
|
declare -A PHASE_DEPS=(
|
||||||
|
[1]=""
|
||||||
|
[2]="1"
|
||||||
|
[3]="2"
|
||||||
|
[4]="2"
|
||||||
|
[5]="3 4"
|
||||||
|
[6]="2"
|
||||||
|
[7]="6"
|
||||||
|
[8]="5"
|
||||||
|
[9]="3"
|
||||||
|
[10]="2"
|
||||||
|
[11]="5 6 7"
|
||||||
|
[12]="1 2 3 4 5 6 7 8 9 10 11"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Finn blokkerte faser ---
|
||||||
|
# En fase er blokkert hvis den har en [?] eller [!] oppgave
|
||||||
|
blocked_phases() {
|
||||||
|
local phases=""
|
||||||
|
for phase in $(seq 1 12); do
|
||||||
|
# Sjekk om fasen har blokkerte oppgaver
|
||||||
|
if grep -qP "^\- \[\?\] ${phase}\." "$TASKS" 2>/dev/null || \
|
||||||
|
grep -qP "^\- \[!\] ${phase}\." "$TASKS" 2>/dev/null; then
|
||||||
|
phases="$phases $phase"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "$phases"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sjekk om en fase er tilgjengelig (alle avhengigheter er ferdige eller i det minste ikke blokkert)
|
||||||
|
phase_available() {
|
||||||
|
local phase=$1
|
||||||
|
local blocked="$2"
|
||||||
|
|
||||||
|
# Sjekk om denne fasen selv er blokkert
|
||||||
|
if echo "$blocked" | grep -qw "$phase"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sjekk om avhengige faser er blokkert
|
||||||
|
local deps="${PHASE_DEPS[$phase]}"
|
||||||
|
for dep in $deps; do
|
||||||
|
if echo "$blocked" | grep -qw "$dep"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
# Sjekk at alle oppgaver i avhengig fase er ferdige
|
||||||
|
if grep -qP "^\- \[ \] ${dep}\." "$TASKS" 2>/dev/null; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Status-visning ---
|
||||||
|
if [[ "${1:-}" == "--status" ]]; then
|
||||||
|
echo "=== Synops oppgavestatus ==="
|
||||||
|
echo ""
|
||||||
|
done=$(grep -cP '^\- \[x\]' "$TASKS" || true)
|
||||||
|
todo=$(grep -cP '^\- \[ \]' "$TASKS" || true)
|
||||||
|
questions=$(grep -cP '^\- \[\?\]' "$TASKS" || true)
|
||||||
|
blocked_count=$(grep -cP '^\- \[!\]' "$TASKS" || true)
|
||||||
|
done=${done:-0}; todo=${todo:-0}; questions=${questions:-0}; blocked_count=${blocked_count:-0}
|
||||||
|
total=$((done + todo + questions + blocked_count))
|
||||||
|
echo "Ferdige: $done / $total"
|
||||||
|
echo "Gjenstår: $todo"
|
||||||
|
echo "Spørsmål: $questions"
|
||||||
|
echo "Blokkert: $blocked_count"
|
||||||
|
echo ""
|
||||||
|
if [[ $questions -gt 0 ]]; then
|
||||||
|
echo "--- Åpne spørsmål ---"
|
||||||
|
grep -A2 '^\- \[\?\]' "$TASKS" || true
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
if [[ $blocked_count -gt 0 ]]; then
|
||||||
|
echo "--- Blokkerte oppgaver ---"
|
||||||
|
grep -A2 '^\- \[!\]' "$TASKS" || true
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Finn neste oppgave ---
|
||||||
|
blocked=$(blocked_phases)
|
||||||
|
|
||||||
|
next_task=""
|
||||||
|
line_num=""
|
||||||
|
task_text=""
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
num=$(echo "$line" | cut -d: -f1)
|
||||||
|
text=$(echo "$line" | cut -d: -f2- | sed 's/^- \[ \] //')
|
||||||
|
# Hent fase-nummer fra oppgave-ID (f.eks. "1.3" → "1")
|
||||||
|
phase=$(echo "$text" | grep -oP '^\d+' || echo "")
|
||||||
|
|
||||||
|
if [[ -n "$phase" ]] && phase_available "$phase" "$blocked"; then
|
||||||
|
next_task="$line"
|
||||||
|
line_num="$num"
|
||||||
|
task_text="$text"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done < <(grep -n '^\- \[ \]' "$TASKS")
|
||||||
|
|
||||||
|
if [[ -z "$next_task" ]]; then
|
||||||
|
if [[ -n "$blocked" ]]; then
|
||||||
|
echo "Ingen tilgjengelige oppgaver. Blokkerte faser:$blocked"
|
||||||
|
echo "Kjør --status for detaljer."
|
||||||
|
else
|
||||||
|
echo "Alle oppgaver er gjort!"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Neste oppgave (linje $line_num):"
|
||||||
|
echo " $task_text"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ "${1:-}" == "--dry" ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROMPT="$(cat <<'PROMPT_HEADER'
|
||||||
|
Du skal implementere neste oppgave i Synops-prosjektet.
|
||||||
|
Du jobber autonomt — ingen bruker er tilgjengelig for spørsmål underveis.
|
||||||
|
|
||||||
|
PROMPT_HEADER
|
||||||
|
)
|
||||||
|
|
||||||
|
## Oppgave
|
||||||
|
$task_text
|
||||||
|
|
||||||
|
$(cat <<'PROMPT_BODY'
|
||||||
|
|
||||||
|
## Arbeidsflyt
|
||||||
|
|
||||||
|
1. **Orienter deg.** Les `CLAUDE.md` for prosjektkontekst. Les dokumentene
|
||||||
|
som refereres i oppgaven. Les `tasks.md` for å forstå hvor prosjektet står.
|
||||||
|
2. **Implementer.** Skriv kode, kjør på server via SSH om nødvendig.
|
||||||
|
3. **Verifiser.** Kompilering, curl-test, kjør relevante tester.
|
||||||
|
4. **Oppdater dokumentasjon.** Hvis implementeringen avviker fra eksisterende
|
||||||
|
docs, oppdater dem. Nye tekniske beslutninger dokumenteres i relevante
|
||||||
|
filer under `docs/`. Docs skal alltid reflektere faktisk tilstand.
|
||||||
|
5. **Oppdater tasks.md.** Endre `- [ ]` til `- [x]` for denne oppgaven.
|
||||||
|
6. **Commit og push.** Commit alle endringer (kode + docs + tasks.md) med
|
||||||
|
en beskrivende melding. Push til forgejo (bruk `tea` / `git push forgejo`).
|
||||||
|
|
||||||
|
## Hvis noe blokkerer
|
||||||
|
|
||||||
|
Hvis du støter på noe som krever avklaring fra Vegard:
|
||||||
|
- Endre oppgavens status til `- [?]` i tasks.md
|
||||||
|
- Legg til innrykket tekst under oppgaven med spørsmålet:
|
||||||
|
```
|
||||||
|
- [?] 1.5 Authentik: opprett OIDC-provider...
|
||||||
|
> Spørsmål: Skal vi bruke implicit flow eller authorization code + PKCE?
|
||||||
|
> Kontekst: PKCE er sikrere men krever backend-støtte.
|
||||||
|
```
|
||||||
|
- Commit og push tasks.md slik at Vegard kan se spørsmålet.
|
||||||
|
- Avslutt sesjonen. Ikke start på neste oppgave.
|
||||||
|
|
||||||
|
Hvis du støter på et teknisk problem du ikke kan løse:
|
||||||
|
- Endre oppgavens status til `- [!]` i tasks.md
|
||||||
|
- Dokumenter problemet under oppgaven.
|
||||||
|
- Commit og push. Avslutt.
|
||||||
|
|
||||||
|
## Regler
|
||||||
|
|
||||||
|
- Jobb kun på denne ene oppgaven.
|
||||||
|
- Ikke deploy til produksjon uten eksplisitt godkjenning.
|
||||||
|
- Følg eksisterende arkitektur og konvensjoner i `docs/`.
|
||||||
|
- Hold det enkelt — minimum viable for oppgaven.
|
||||||
|
- Dokumentasjon er like viktig som kode. Neste sesjon har ingen kontekst
|
||||||
|
fra denne — alt den vet kommer fra kode, docs og git-historikk.
|
||||||
|
- Skriv commit-meldinger som forklarer *hvorfor*, ikke bare *hva*.
|
||||||
|
PROMPT_BODY
|
||||||
|
)"
|
||||||
|
|
||||||
|
echo "Starter Claude Code-sesjon..."
|
||||||
|
cd "$ROOT"
|
||||||
|
claude --print "$PROMPT"
|
||||||
124
tasks.md
Normal file
124
tasks.md
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
# Synops — Implementeringsoppgaver
|
||||||
|
|
||||||
|
Sekvensiell liste. Hver oppgave gjøres i én Claude Code-sesjon.
|
||||||
|
Runner-scriptet plukker første ugjorte oppgave som ikke er blokkert.
|
||||||
|
|
||||||
|
## Statuser
|
||||||
|
|
||||||
|
- `- [ ]` — Klar til å gjøres
|
||||||
|
- `- [x]` — Ferdig
|
||||||
|
- `- [?]` — Åpent spørsmål, trenger avklaring fra Vegard. Neste sesjon hopper over denne og alle som avhenger av den.
|
||||||
|
- `- [!]` — Blokkert av teknisk problem. Beskrivelse under oppgaven.
|
||||||
|
|
||||||
|
Åpne spørsmål og blokkeringer skrives som innrykket tekst under oppgaven
|
||||||
|
med `>` prefix. Se eksisterende oppgaver for format.
|
||||||
|
|
||||||
|
## Avhengigheter
|
||||||
|
|
||||||
|
Oppgaver innen en fase er sekvensielle (1.1 før 1.2, osv).
|
||||||
|
Faser avhenger av hverandre slik:
|
||||||
|
|
||||||
|
```
|
||||||
|
Fase 1 (infra) → Fase 2 (maskinrommet) → Fase 3 (frontend)
|
||||||
|
↘ Fase 4 (tilgang)
|
||||||
|
Fase 3 + 4 → Fase 5 (kommunikasjon)
|
||||||
|
Fase 2 → Fase 6 (CAS) → Fase 7 (lyd)
|
||||||
|
Fase 5 → Fase 8 (aliaser)
|
||||||
|
Fase 3 → Fase 9 (visninger)
|
||||||
|
Fase 2 → Fase 10 (AI)
|
||||||
|
Fase 5 + 6 + 7 → Fase 11 (produksjon)
|
||||||
|
Alt → Fase 12 (herding)
|
||||||
|
```
|
||||||
|
|
||||||
|
Hvis en oppgave er `[?]` eller `[!]`, hoppes den over — og alle
|
||||||
|
oppgaver som avhenger av den (innen fasen + avhengige faser).
|
||||||
|
Uavhengige faser kan fortsatt plukkes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fase 1: Infrastruktur-fundament
|
||||||
|
|
||||||
|
- [ ] 1.1 PostgreSQL schema: opprett database `synops`, enums (`visibility`, `access_level`), tabeller (`nodes`, `edges`, `node_access`, `auth_identities`) med indekser. Kjør på server via SSH. Ref: `docs/primitiver/nodes.md`, `docs/primitiver/edges.md`, `docs/retninger/bruker_ikke_workspace.md`.
|
||||||
|
- [ ] 1.2 Seed-data: opprett Vegards brukernode (`node_kind='person'`, `title='Vegard'`) og `auth_identities`-rad. Opprett Sidelinja samlings-node og `owner`-edge fra Vegard.
|
||||||
|
- [ ] 1.3 SpacetimeDB modul: opprett Rust-modul med `nodes` og `edges`-tabeller som speiler PG-skjema. Grunnleggende reducers for CRUD. Deploy til server. Ref: `docs/retninger/datalaget.md`, `docs/erfaringer/spacetimedb_integrasjon.md`.
|
||||||
|
- [ ] 1.4 Caddy-config: reverse proxy for maskinrommet (api.sidelinja.org), SpacetimeDB, og SvelteKit. Auto-TLS. Ref: `docs/setup/produksjon.md`.
|
||||||
|
- [ ] 1.5 Authentik: opprett OIDC-provider og applikasjon for Synops. Konfigurer redirect URIs. Ref: `docs/erfaringer/authentik_oppsett.md`.
|
||||||
|
|
||||||
|
## Fase 2: Maskinrommet — skjelett
|
||||||
|
|
||||||
|
- [ ] 2.1 Rust-prosjekt: opprett `maskinrommet/` med axum, tokio, sqlx (PG), serde. Dockerfile. Kompilerer og starter. Ref: `docs/retninger/maskinrommet.md`.
|
||||||
|
- [ ] 2.2 Auth-middleware: valider Authentik JWT-tokens, slå opp `auth_identities` → node_id. Returner 401 for ugyldige tokens.
|
||||||
|
- [ ] 2.3 SpacetimeDB-klient i maskinrommet: koble til STDB, skriv noder og edges via reducers.
|
||||||
|
- [ ] 2.4 Skrivestien: `POST /intentions/create_node` — valider, skriv STDB (instant), spawn async PG-skriving. Returner node_id umiddelbart.
|
||||||
|
- [ ] 2.5 Flere intensjoner: `create_edge`, `update_node`, `delete_node`. Validering av tilgang (created_by eller owner/admin-edge).
|
||||||
|
- [ ] 2.6 Docker Compose: legg maskinrommet inn i server-stacken. Intern nettverkstilgang til PG og STDB.
|
||||||
|
|
||||||
|
## Fase 3: Frontend — skjelett
|
||||||
|
|
||||||
|
- [ ] 3.1 SvelteKit-prosjekt: opprett `frontend/` med TypeScript, TailwindCSS. PWA-manifest. Lokal dev med HMR.
|
||||||
|
- [ ] 3.2 Authentik login: OIDC-flow (authorization code + PKCE). Session-håndtering. Redirect til login ved 401.
|
||||||
|
- [ ] 3.3 STDB WebSocket-klient: abonner på noder og edges. Reaktiv Svelte-store som oppdateres ved endringer.
|
||||||
|
- [ ] 3.4 Mottaksflaten v0: vis noder med edge til innlogget bruker, sortert på `created_at`. Enkel liste med tittel og utdrag.
|
||||||
|
- [ ] 3.5 TipTap-editor: enkel preset (tekst, markdown, lenker). Send `create_node`-intensjon til maskinrommet ved submit.
|
||||||
|
- [ ] 3.6 Sanntidstest: åpne to faner, skriv i én, se noden dukke opp i den andre via STDB.
|
||||||
|
|
||||||
|
## Fase 4: Tilgangskontroll
|
||||||
|
|
||||||
|
- [ ] 4.1 `recompute_access` i maskinrommet: ved edge-endring, oppdater `node_access`-matrisen. Håndter direkte edges (owner, admin, member, reader).
|
||||||
|
- [ ] 4.2 Team-transitivitet: member_of-edge til team → arv tilgang fra teamets edges.
|
||||||
|
- [ ] 4.3 Visibility-filtrering: STDB-spørringer respekterer visibility-enum. Frontend ser bare noder brukeren har tilgang til.
|
||||||
|
- [ ] 4.4 RLS-policies på PG: `node_access`-basert filtrering for tunge spørringer.
|
||||||
|
|
||||||
|
## Fase 5: Kommunikasjonsnoder
|
||||||
|
|
||||||
|
- [ ] 5.1 Opprett kommunikasjonsnode: intensjon `create_communication` → node med `node_kind='communication'`, deltaker-edges, metadata (started_at).
|
||||||
|
- [ ] 5.2 Kontekst-arv: input i kommunikasjonsnode → automatisk `belongs_to`-edge.
|
||||||
|
- [ ] 5.3 Chat-visning i frontend: noder med `belongs_to`-edge til kommunikasjonsnode, sortert på tid, sanntid via STDB.
|
||||||
|
- [ ] 5.4 Én-til-én chat: opprett kommunikasjonsnode med to deltakere. Full loop: skriv melding → vis i sanntid hos begge.
|
||||||
|
|
||||||
|
## Fase 6: CAS og mediefiler
|
||||||
|
|
||||||
|
- [ ] 6.1 CAS-lagring: filsystem med content-addressable hashing (SHA-256). Katalogstruktur med hash-prefix. Deduplisering.
|
||||||
|
- [ ] 6.2 Upload-endepunkt: `POST /intentions/upload_media` → hash fil, lagre i CAS, opprett media-node med `has_media`-edge.
|
||||||
|
- [ ] 6.3 Serving: `GET /cas/{hash}` → stream fil fra disk. Caddy kan serve direkte for ytelse.
|
||||||
|
- [ ] 6.4 Bilder i TipTap: drag-and-drop/paste → upload → CAS-node → inline i `metadata.document` via `node_id`.
|
||||||
|
|
||||||
|
## Fase 7: Lyd-pipeline
|
||||||
|
|
||||||
|
- [ ] 7.1 faster-whisper oppsett: Docker-container, GPU hvis tilgjengelig, norsk modell. Ref: `docs/erfaringer/`.
|
||||||
|
- [ ] 7.2 Transkripsjons-pipeline: lydfil i CAS → maskinrommet trigger Whisper → resultat i `content`-feltet.
|
||||||
|
- [ ] 7.3 Voice memo i frontend: opptak-knapp i input-komponenten → upload → CAS → transkripsjon.
|
||||||
|
- [ ] 7.4 Lyd-avspilling: spiller av original lyd fra CAS-node. Waveform-visning.
|
||||||
|
|
||||||
|
## Fase 8: Aliaser
|
||||||
|
|
||||||
|
- [ ] 8.1 Alias-noder: opprett alias-node med `alias`-edge (system=true) fra hovednoden. Usynlig for traversering.
|
||||||
|
- [ ] 8.2 Kontekstbasert identitet: maskinrommet setter `created_by` til alias-node når brukeren opererer i kontekst der aliaset er vert/deltaker.
|
||||||
|
|
||||||
|
## Fase 9: Flere visninger
|
||||||
|
|
||||||
|
- [ ] 9.1 Kanban-visning: noder med board-edge, gruppert på status-edge. Drag-and-drop for statusendring.
|
||||||
|
- [ ] 9.2 Kalender-visning: noder med `scheduled`-edge, på tidslinje.
|
||||||
|
- [ ] 9.3 Dagbok-visning: private noder (ingen delte edges), sortert på tid.
|
||||||
|
- [ ] 9.4 Kunnskapsgraf: topic-noder, `mentions`-edges. Visuell graf-visning.
|
||||||
|
|
||||||
|
## Fase 10: AI og beriking
|
||||||
|
|
||||||
|
- [ ] 10.1 LiteLLM oppsett: Docker-container, API-nøkler, modell-routing. Ref: `docs/infra/ai_gateway.md`.
|
||||||
|
- [ ] 10.2 AI-foreslåtte edges: maskinrommet sender innhold til LLM → foreslår mentions, topics.
|
||||||
|
- [ ] 10.3 Oppsummering: kommunikasjonsnode → AI-generert sammendrag som ny node.
|
||||||
|
- [ ] 10.4 TTS: tekst → lyd via ElevenLabs. Mottaker-preferanse i metadata.
|
||||||
|
|
||||||
|
## Fase 11: Produksjons-pipeline
|
||||||
|
|
||||||
|
- [ ] 11.1 LiveKit oppsett: Docker-container for WebRTC. Ref: `docs/setup/produksjon.md`.
|
||||||
|
- [ ] 11.2 Sanntidslyd: kommunikasjonsnode med live-status → LiveKit-rom for deltakere.
|
||||||
|
- [ ] 11.3 Pruning-logikk: TTL per modalitet, signaler som forlenger levetid, disk-nødventil.
|
||||||
|
- [ ] 11.4 Podcast-RSS: samlings-node med publiserings-edges → generert RSS-feed.
|
||||||
|
|
||||||
|
## Fase 12: Herding
|
||||||
|
|
||||||
|
- [ ] 12.1 Observerbarhet: strukturert logging, metrikker (request latency, queue depth, AI cost).
|
||||||
|
- [ ] 12.2 Backup: PG-dump rutine, STDB → PG gjenoppbygging ved krasj.
|
||||||
|
- [ ] 12.3 Feilhåndtering: retry med backoff i skrivestien, dead letter queue for feilede PG-skrivinger.
|
||||||
|
- [ ] 12.4 Ytelse: profiler STDB-spørringer, optimaliser node_access-oppdatering.
|
||||||
Loading…
Add table
Reference in a new issue