329 lines
15 KiB
YAML
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
|