release(v4.0.0): Shade GA — V3.x consolidation + audit prep
Some checks failed
Test / test (push) Has been cancelled
Cross-platform vectors / TypeScript vectors (bun) (push) Has been cancelled
Cross-platform vectors / Kotlin vectors (gradle) (push) Has been cancelled
Docker build and publish / docker (push) Has been cancelled
Publish / publish (push) Has been cancelled

V3.1 → V3.12 consolidated and tagged for the first GA release. Wire
format unchanged from 0.4.x — 4.0 peers interoperate with 0.4.x peers
byte-for-byte. The version bump is semantic: audit-cycle complete,
opt-in surface fully exposed, threat model refreshed for every new
surface.

Highlights:
- All 24 @shade/* packages bumped to 4.0.0 in lockstep.
- CHANGELOG 4.0.0 section is the canonical manifest of what landed.
- THREAT-MODEL extended (§10 fingerprint gates, §11 WebRTC P2P, §12
  Web-Worker boundary) + residual-risks table refreshed.
- OpenAPI now covers all 27 routes: prekey, transfer, KT, inbox,
  bridge, observer, /metrics, /healthz, /ready.
- MIGRATION 0.3.x → 4.0 documented + smoke-tested against
  shade migrate-storage on a real SQLite DB.
- docs/audit/REVIEW-BUNDLE.md + SCOPE.md ready for external reviewer.
- scripts/soak.ts harness for the GA-stable 2-week soak window.
- All V*.md plans archived under docs/archive/ with Status: Done.
- Voice/Video carved out into V5.0; 4.0 audit focuses on the frozen
  non-realtime stack.

Tests: TS 1000/1000 + Kotlin 11/11 cross-platform vectors green.
Docker: gt.zyon.no/stian/shade-prekey:4.0.0 builds and reports
  version 4.0.0 on /health.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-03 18:35:35 +02:00
parent 8b055912b7
commit e6fdf31b49
298 changed files with 37909 additions and 256 deletions

206
bun.lock
View File

@@ -17,14 +17,16 @@
},
"packages/shade-cli": {
"name": "@shade/cli",
"version": "0.3.0",
"version": "0.4.0",
"bin": {
"shade": "src/cli.ts",
},
"dependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/keychain": "workspace:*",
"@shade/sdk": "workspace:*",
"@shade/storage-encrypted": "workspace:*",
"@shade/storage-sqlite": "workspace:*",
"@shade/transport": "workspace:*",
},
@@ -34,7 +36,10 @@
},
"packages/shade-core": {
"name": "@shade/core",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/observability": "workspace:*",
},
"devDependencies": {
"@shade/proto": "workspace:*",
},
@@ -44,16 +49,17 @@
},
"packages/shade-crypto-web": {
"name": "@shade/crypto-web",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@noble/curves": "^2.0.1",
"@noble/hashes": "^2.0.1",
"@shade/core": "workspace:*",
"@shade/streams": "workspace:*",
},
},
"packages/shade-dashboard": {
"name": "@shade/dashboard",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/widgets": "workspace:*",
"react": "^19.0.0",
@@ -68,10 +74,11 @@
},
"packages/shade-files": {
"name": "@shade/files",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/observability": "workspace:*",
"@shade/proto": "workspace:*",
"@shade/sdk": "workspace:*",
"@shade/streams": "workspace:*",
@@ -92,9 +99,74 @@
"react",
],
},
"packages/shade-inbox": {
"name": "@shade/inbox",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/proto": "workspace:*",
"@shade/server": "workspace:*",
},
"devDependencies": {
"@shade/crypto-web": "workspace:*",
"@shade/inbox-server": "workspace:*",
},
},
"packages/shade-inbox-server": {
"name": "@shade/inbox-server",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/observability": "workspace:*",
"@shade/server": "workspace:*",
"hono": "^4.12.12",
},
"devDependencies": {
"@shade/crypto-web": "workspace:*",
},
"optionalDependencies": {
"@shade/crypto-web": "workspace:*",
"@shade/storage-postgres": "workspace:*",
"@shade/storage-sqlite": "workspace:*",
},
},
"packages/shade-key-transparency": {
"name": "@shade/key-transparency",
"version": "0.4.0",
"dependencies": {
"@noble/hashes": "^2.0.1",
"@shade/core": "workspace:*",
},
"devDependencies": {
"@shade/crypto-web": "workspace:*",
"fast-check": "^3.22.0",
},
},
"packages/shade-keychain": {
"name": "@shade/keychain",
"version": "0.4.0",
},
"packages/shade-observability": {
"name": "@shade/observability",
"version": "0.1.0",
"dependencies": {
"@noble/hashes": "^2.0.1",
},
"devDependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/server": "workspace:*",
},
"peerDependencies": {
"@opentelemetry/api": ">=1.7.0",
},
"optionalPeers": [
"@opentelemetry/api",
],
},
"packages/shade-observer": {
"name": "@shade/observer",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/server": "workspace:*",
@@ -106,18 +178,33 @@
},
"packages/shade-proto": {
"name": "@shade/proto",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
},
},
"packages/shade-recovery": {
"name": "@shade/recovery",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/sdk": "workspace:*",
},
"devDependencies": {
"@shade/server": "workspace:*",
"fast-check": "^3.22.0",
},
},
"packages/shade-sdk": {
"name": "@shade/sdk",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/files": "workspace:*",
"@shade/key-transparency": "workspace:*",
"@shade/observability": "workspace:*",
"@shade/observer": "workspace:*",
"@shade/proto": "workspace:*",
"@shade/server": "workspace:*",
@@ -126,12 +213,24 @@
"@shade/transfer": "workspace:*",
"@shade/transport": "workspace:*",
},
"devDependencies": {
"@shade/transport-webrtc": "workspace:*",
},
"peerDependencies": {
"@shade/transport-webrtc": "workspace:*",
},
"optionalPeers": [
"@shade/transport-webrtc",
],
},
"packages/shade-server": {
"name": "@shade/server",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/inbox-server": "workspace:*",
"@shade/key-transparency": "workspace:*",
"@shade/observability": "workspace:*",
"hono": "^4.12.12",
},
"devDependencies": {
@@ -144,11 +243,31 @@
"@shade/storage-sqlite": "workspace:*",
},
},
"packages/shade-storage-encrypted": {
"name": "@shade/storage-encrypted",
"version": "0.4.0",
"dependencies": {
"@noble/hashes": "^2.0.1",
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/storage-postgres": "workspace:*",
"@shade/storage-sqlite": "workspace:*",
"postgres": "^3.4.9",
},
"peerDependencies": {
"@shade/keychain": "workspace:*",
},
"optionalPeers": [
"@shade/keychain",
],
},
"packages/shade-storage-postgres": {
"name": "@shade/storage-postgres",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/inbox-server": "workspace:*",
"@shade/key-transparency": "workspace:*",
"@shade/server": "workspace:*",
"drizzle-orm": "^0.45.2",
"postgres": "^3.4.9",
@@ -159,29 +278,33 @@
},
"packages/shade-storage-sqlite": {
"name": "@shade/storage-sqlite",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/inbox-server": "workspace:*",
"@shade/server": "workspace:*",
},
},
"packages/shade-streams": {
"name": "@shade/streams",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@noble/hashes": "^2.0.1",
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/proto": "workspace:*",
},
"devDependencies": {
"@shade/crypto-web": "workspace:*",
},
},
"packages/shade-transfer": {
"name": "@shade/transfer",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/observability": "workspace:*",
"@shade/proto": "workspace:*",
"@shade/streams": "workspace:*",
},
@@ -194,18 +317,51 @@
},
"packages/shade-transport": {
"name": "@shade/transport",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/crypto-web": "workspace:*",
"@shade/key-transparency": "workspace:*",
"@shade/proto": "workspace:*",
"@shade/server": "workspace:*",
},
},
"packages/shade-transport-bridge": {
"name": "@shade/transport-bridge",
"version": "0.1.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/server": "workspace:*",
},
"devDependencies": {
"@shade/crypto-web": "workspace:*",
"@shade/inbox-server": "workspace:*",
"hono": "^4.12.12",
},
"optionalDependencies": {
"@shade/inbox-server": "workspace:*",
},
"peerDependencies": {
"hono": "^4",
},
"optionalPeers": [
"hono",
],
},
"packages/shade-transport-webrtc": {
"name": "@shade/transport-webrtc",
"version": "0.4.0",
"dependencies": {
"@shade/core": "workspace:*",
"@shade/streams": "workspace:*",
"@shade/transfer": "workspace:*",
},
},
"packages/shade-widgets": {
"name": "@shade/widgets",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@shade/recovery": "workspace:*",
"@shade/sdk": "workspace:*",
"@shade/streams": "workspace:*",
"@shade/transfer": "workspace:*",
@@ -390,14 +546,28 @@
"@shade/files": ["@shade/files@workspace:packages/shade-files"],
"@shade/inbox": ["@shade/inbox@workspace:packages/shade-inbox"],
"@shade/inbox-server": ["@shade/inbox-server@workspace:packages/shade-inbox-server"],
"@shade/key-transparency": ["@shade/key-transparency@workspace:packages/shade-key-transparency"],
"@shade/keychain": ["@shade/keychain@workspace:packages/shade-keychain"],
"@shade/observability": ["@shade/observability@workspace:packages/shade-observability"],
"@shade/observer": ["@shade/observer@workspace:packages/shade-observer"],
"@shade/proto": ["@shade/proto@workspace:packages/shade-proto"],
"@shade/recovery": ["@shade/recovery@workspace:packages/shade-recovery"],
"@shade/sdk": ["@shade/sdk@workspace:packages/shade-sdk"],
"@shade/server": ["@shade/server@workspace:packages/shade-server"],
"@shade/storage-encrypted": ["@shade/storage-encrypted@workspace:packages/shade-storage-encrypted"],
"@shade/storage-postgres": ["@shade/storage-postgres@workspace:packages/shade-storage-postgres"],
"@shade/storage-sqlite": ["@shade/storage-sqlite@workspace:packages/shade-storage-sqlite"],
@@ -408,6 +578,10 @@
"@shade/transport": ["@shade/transport@workspace:packages/shade-transport"],
"@shade/transport-bridge": ["@shade/transport-bridge@workspace:packages/shade-transport-bridge"],
"@shade/transport-webrtc": ["@shade/transport-webrtc@workspace:packages/shade-transport-webrtc"],
"@shade/widgets": ["@shade/widgets@workspace:packages/shade-widgets"],
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],