Files
Shade/.scaffold/tasks.yaml
2026-08-14 11:58:49 +02:00

329 lines
15 KiB
YAML

# Scaffold kanban-kort. Skjema per kort:
# - id: kort-slug # unik i fila
# title: ""
# description: ""
# status: todo # todo | doing | done | blocked
# column: todo # speiler status (kanban-kolonne)
# priority: medium # low | medium | high
# assignee: human # cursor | claude | human | any
# context: "" # valgfri: hvorfor/hvor i koden
# acceptance: "" # valgfri: hva «ferdig» betyr
# todos:
# - text: "Underoppgave"
# done: false
# created: 2026-07-09
# updated: 2026-07-09
# completed_at: null
tasks:
# ─────────────── G0 — Stopp blødningen (P0-blockere) ───────────────
- id: g0-gcm-nonce-reuse
title: "Fjern AES-GCM nonce-gjenbruk i at-rest storage"
description: >
deriveNonce() lager deterministisk nonce fra (fieldKey, tabell, pk) uten
meldingsteller. saveSession re-krypterer sesjonsraden ved hvert ratchet-steg,
så to DB-snapshots deler (key, nonce) over ulik plaintext = GCM forbidden
attack. Systemisk: gjelder alle muterbare rader (config, prekey-state, trust).
status: done
column: done
priority: high
assignee: claude
context: >
Kallesteder kartlagt 2026-08-13: kun row-codec.ts:67 og :96 lager nonce,
og :83/:112 tvinger den ved lesing. deriveNonce() er eksportert fra både
index.ts og crypto.ts, så den beholdes (deprecated) framfor å brekke
konsumenter. VERIFISERT: aeadOpen leser alltid nonce fra blob-prefiks
(aead.ts:72) og expectedNonce er kun en valgfri ekstrasjekk — eksisterende
blobber åpnes derfor uendret, og ingen migreringssti trengs.
acceptance: "Tilfeldig nonce per skriving; aeadOpen leser nonce fra prefiks (dropp expectedNonce-tvang). Negativ test: to session-snapshots ved ulik message-count deler ikke (key, nonce). Test som åpner en blob forseglet med gammel deterministisk nonce. Alle eksisterende tester grønne."
todos:
- text: "row-codec.ts:67/96 → tilfeldig 12-byte nonce, lagret i blob-prefiks"
done: true
- text: "Dropp expectedNonce-argumentet i row-codec.ts:83/112"
done: true
- text: "Negativ regresjonstest for nonce-unikhet på tvers av re-saves"
done: true
- text: "Bakoverkompatibilitetstest: blob med gammel deterministisk nonce åpnes"
done: true
- text: "Marker deriveNonce deprecated (fortsatt eksportert fra index/crypto)"
done: true
- text: "IKKE PUBLISERT — Prism er pinnet på 4.12.0 og får fiksen først ved release"
done: false
created: 2026-07-10
updated: 2026-08-13
completed_at: 2026-08-13
- id: g0-observer-publish
title: "Fiks @shade/observer publiserings-artefakt (tomt på registry)"
description: >
outDir=dist-build avviker fra alle andre pakker (dist). Publish kjører
rm -rf dist og shipper files:[dist] → tarballen mangler JS, main peker på
manglende fil. dist-build/ er det untrackede avviket i git status.
status: todo
column: todo
priority: high
assignee: claude
context: "packages/shade-observer/tsconfig.json (outDir), scripts/publish-all.ts:109/186-227, dashboard copy-to-observer.ts-konflikten"
acceptance: "outDir=dist; dashboard-SPA-konflikt løst eksplisitt; 4.11.2 republisert med verifisert tarball; dist-build/ i .gitignore."
todos:
- text: "tsconfig outDir → dist"
done: false
- text: "Løs dashboard-SPA vs publish-eierskap til dist/"
done: false
- text: "gitignore dist-build/ + fjern restene"
done: false
- text: "Republiser observer 4.11.2"
done: false
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: g0-typecheck-gate
title: "Pin TypeScript, fiks baseUrl, kjør typecheck i CI"
description: >
TS ikke pinnet noe sted → bunx tsc henter 7.0.2 som fjernet baseUrl (brukt i
consumer-strict). typecheck exit 1 nå → prepublish:check rød. Gaten kjøres
heller aldri i CI.
status: done
column: done
priority: high
assignee: claude
context: "tests/consumer-strict/tsconfig.json:17 (baseUrl), scripts/typecheck-all.ts (bruker upinnet bunx tsc), .gitea/workflows/test.yml"
acceptance: "typescript pinnet som devDependency og brukt av typecheck-all.ts; baseUrl fjernet; bun run typecheck grønn og kjøres i .gitea/workflows/test.yml."
todos:
- text: "Pin typescript i root devDependencies"
done: true
- text: "typecheck-all.ts bruker lokal tsc, ikke bunx latest"
done: true
- text: "Fjern baseUrl fra consumer-strict tsconfig (var allerede borte)"
done: true
- text: "Legg typecheck-steg i test.yml"
done: true
created: 2026-07-10
updated: 2026-08-14
completed_at: 2026-08-14
- id: g0-cli-bin-tarball-verify
title: "Fiks cli bin-omskriving + tarball-verifisering i publish"
description: >
bin.shade=src/cli.ts omskrives ikke til dist/ (rewriteEntryPointsForDist
dekker kun main/types/exports). npm i -g @shade/cli gir brutt binær. Samme
rot som observer: publish mangler integritetssjekk.
status: todo
column: todo
priority: high
assignee: claude
context: "scripts/publish-all.ts:186-196 (rewriteEntryPointsForDist), packages/shade-cli/package.json (bin)"
acceptance: "bin omskrives til dist/; publish asserterer at bun pm pack inneholder main-filen for hver pakke; npm i -g @shade/cli kjørbar."
todos:
- text: "Utvid rewriteEntryPointsForDist til pkgJson.bin"
done: false
- text: "Legg tarball-innhold-assert (bun pm pack) i publish-flyten"
done: false
created: 2026-07-10
updated: 2026-07-10
completed_at: null
# ─────────────── G1 — Revisjonsklar kjerne (P1-sikkerhet) ───────────────
- id: g1-symmetric-safety-number
title: "Symmetrisk safety-number (lagre peer-signeringsnøkkel per sesjon)"
description: >
getRemoteFingerprint sender remoteIdentityKey (DH) som begge argumenter →
H(dh‖dh) ≠ peerens egen H(sig‖dh). OOB-verifisering kan aldri matche →
primær MITM-forsvar ikke-funksjonelt.
status: todo
column: todo
priority: high
assignee: claude
context: "packages/shade-core/src/session.ts:238-245, SDK verify()/markPeerVerified()/isPeerVerified() shade.ts:590/649/659"
acceptance: "Peer-signeringsnøkkel lagres per sesjon; kanonisk symmetrisk safety-number; kryssparts-test alice.verify(bob, bob.getIdentityFingerprint())===true uten MITM."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: g1-argon2id-backup
title: "Koble argon2id inn i backup-KDF (TS + Kotlin)"
description: >
Backup-passord-KDF er HKDF → offline brute-force i HKDF-hastighet.
argon2idAsync fra @noble/hashes er allerede dependency og brukes i
storage-encrypted. Kotlin har deriveMasterKeyArgon2id via Bouncy Castle.
status: todo
column: todo
priority: high
assignee: claude
context: "packages/shade-sdk/src/backup.ts:112-119, android/.../backup/BackupKdf.kt:27-36, referanse: storage-encrypted/src/crypto/kdf.ts:73-91"
acceptance: "Backup-KDF = argon2id på begge plattformer; backup-vektor re-pinnet; cross-platform-vektortest grønn."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: g1-hono-upgrade-audit
title: "Oppgrader hono ≥4.12.18 + bun audit-gate"
description: >
hono <4.12.18 har bodyLimit-bypass (svekker §7 64 KiB body-cap), path
traversal i serve-static, IP-restriction-bypass. Dev/test: happy-dom
(critical VM-escape), vite, postcss.
status: todo
column: todo
priority: high
assignee: claude
context: "hono i shade-server/inbox-server/transfer/observer/transport-bridge; bun.lock pinner nåværende"
acceptance: "hono ≥4.12.18 overalt; bun audit uten runtime-high/critical; §7 DoS-cap re-evaluert."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: g1-at-rest-tamper-test
title: "Håndhevende §4 at-rest-tuklingstest + bestill ekstern review"
description: >
SECURITY.md-cellen «§4 at-rest session DB» er «none yet» → ikke håndhevet.
Ekstern krypto-review + pentest står «Pending V4.0» og må ikke skli forbi V5.0.
status: todo
column: todo
priority: high
assignee: any
context: "SECURITY.md:18 (celler uten testlenke ikke håndhevet), THREAT-MODEL §4"
acceptance: "Negativ test som beviser at at-rest-tukling fanges (AAD/tag); SECURITY.md-celle lenket. Ekstern review + pentest bestilt."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
# ─────────────── G2/G3-hoder (nedbrytes når G0/G1 nærmer seg) ───────────────
- id: g2-ci-wall
title: "G2: CI som mur — lint/format/coverage/soak + rydd .github + arkitektur"
description: >
biome (lint+format), coverage-terskel (gulv=dagens), soak:smoke i CI;
fjern/synk stale .github/workflows (7 pakker→npmjs); publish kjører
prepublish:check; bryt server↔inbox-server-syklus; rydd sdk/cli/files ubrukte
deps; dashboard private; pin bun i workflows; kjør alle 8 examples (fiks
accept-race i shade-transfer/engine.ts:1140).
status: todo
column: todo
priority: medium
assignee: claude
context: "Se helsesjekk-artifact 2026-07-10 (P2-arkitektur + CI-hull)"
acceptance: "PR blokkeres ved brudd på typecheck·lint·format·test·coverage; alle 8 examples grønne i CI; ingen udeklarert/ubrukt hard dep."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: g3-parity-lock
title: "G3: Paritetslås — ShadeStream-vektorer + Kotlin v4.11 + interop"
description: >
ShadeStream (v4.11) har null vektorer selv på TS-siden. Kotlin stopper på
v4.10. Lag vektorer (3-DH deriveStreamRootKey, wire 0x31-0x33, frame
seal/open) konsumert av begge; port ShadeStream til Kotlin; utvid
cross-vectors path-filter; PARITY-VERSION-sjekk; symmetriser alle 14
vektorfiler; Robolectric-tester for KeystoreStorage; E2E socket-interop.
status: todo
column: todo
priority: medium
assignee: claude
context: "packages/shade-core/src/stream.ts, scripts/generate-vectors.ts, .gitea/workflows/cross-vectors.yml, android/shade-android-keystore (0 tester)"
acceptance: "Begge sider verifiserer alle 14 vektorer + ShadeStream; minor-bump uten Android-ack ⇒ rød CI; E2E TS-server↔Kotlin-klient over socket grønn."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: g4-docs-truth
title: "G4: Docs = sannhet — oppdater til 4.11.x, fiks lenker/remote/eksempler"
description: >
README/MIGRATION/CHANGELOG/CONTRIBUTING frosset på 4.0. Riktig remote er
Gitea (ikke GitHub). Legg indexeddb/ShadeStream/broadcast i README+
SHADE-BY-SCENARIO; Postgres at-rest quick-start + salt-livssyklus; per-pakke
README for sdk/core/files/streams/storage-encrypted/transport.
status: todo
column: todo
priority: medium
assignee: claude
context: "README.md, MIGRATION.md, CHANGELOG.md, CONTRIBUTING.md, docs/SHADE-BY-SCENARIO.md"
acceptance: "Én sannhetskilde for versjon; ingen brutte doc-lenker (CI link-check); hvert ECOSYSTEM-scenario har kjørende CI-testet eksempel-sti."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
# ─────────────── Åpne beslutninger (Stian avgjør i plandiskusjon) ───────────────
- id: decision-g3-vs-g4-order
title: "BESLUTNING: rekkefølge G3 (paritetslås) vs G4 (docs)"
description: >
Foreslått G3 før G4 fordi «production»-label på Android henger på paritet.
Men hvis Prism/Vyvern trenger docs-sannhet raskere, kan de bytte plass.
status: blocked
column: blocked
priority: medium
assignee: human
acceptance: "Rekkefølge bestemt; plan.md Neste-seksjon speiler valget."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: decision-external-review-timing
title: "BESLUTNING: bestille ekstern krypto-review/pentest nå eller etter G0+G1"
description: >
Parallelt nå (raskere kalender) vs etter G0+G1-fiksene (revisor ser korrekt
kjerne — nonce-fiks + symmetrisk safety-number inne). Fable heller mot fikse først.
status: blocked
column: blocked
priority: medium
assignee: human
context: "Kobles til g1-at-rest-tamper-test; SECURITY.md-celler «Pending V4.0»"
acceptance: "Tidspunkt bestemt; g1-at-rest-tamper-test oppdatert deretter."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
- id: decision-argon2id-migration
title: "BESLUTNING: argon2id backup-migreringsstrategi"
description: >
Re-pinning av backup-vektor betyr at eksisterende 4.x-backups må migreres.
Big-bang i 4.12 vs dobbelt-lesende overgangsvindu (les HKDF-legacy, skriv argon2id).
status: blocked
column: blocked
priority: medium
assignee: human
context: "Kobles til g1-argon2id-backup"
acceptance: "Migreringsstrategi valgt; g1-argon2id-backup-kortet får todos deretter."
created: 2026-07-10
updated: 2026-07-10
completed_at: null
# ─────────────── V4.13 — @shade/vault (server-side kryptert fillager) ───────────────
- id: vault-package
title: "@shade/vault — innholdsadressert kryptert fillager på relayen"
description: >
Shade kan flytte filer mellom peers (@shade/files) og lagre én liten
profil-blob per konto (/v1/blob/<slotId>), men har ingen alltid-på lagring
av krypterte filer. Uten den kan ingen Shade-app tilby backup, og ingen
klient kan lese data når peeren er avslått. Klienten krypterer og navngir
etter hash av ciphertext; serveren ser aldri klartekst.
status: doing
column: doing
priority: high
assignee: claude
context: >
Bestilt av Scaffold-backupen 2026-08-13, men generell: docs/files.md peker
selv på Dispatch/Mail/Drive-style apps som konsumenter. Egen HKDF-gren ved
siden av shade-blob-*-v1 i storage-encrypted/src/crypto/kdf.ts, så et
vault-kompromiss ikke rører profil-slotten. Rutes i shade-server/src/
standalone.ts ved siden av createBlobRoutes.
acceptance: >
Klient kan pushe/hente en samling krypterte objekter mot relayen uten at
serveren kan lese noe; oplog gir versjonsliste og henting av tidligere
versjon; ny enhet med kontocredentials rekonstruerer hele samlingen.
SHADE_VAULT_DB_PATH dokumentert med samme advarsel som SHADE_BLOB_DB_PATH.
todos:
- text: "HKDF-gren for vault-nøkler (slot, innhold, signatur)"
done: true
- text: "Innholdsadressert put/get med CAS-semantikk"
done: true
- text: "Append-only oplog per samling — versjonsliste og rollback"
done: true
- text: "Serverruter + persistenskonfigurasjon i standalone.ts"
done: true
- text: "docs/vault.md + README-rad i statustabellen"
done: false
- text: "IKKE DEPLOYET — krever SHADE_VAULT_DB_PATH i compose + Dokploy-runde"
done: false
created: 2026-08-13
updated: 2026-08-14
completed_at: null