docs(scaffold): plan, tasks og loggposter for vault + G0
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,4 +14,315 @@
|
||||
# created: 2026-07-09
|
||||
# updated: 2026-07-09
|
||||
# completed_at: null
|
||||
tasks: []
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user