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
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:
@@ -88,6 +88,21 @@ export async function ensureClientTables(sql: Sql): Promise<void> {
|
||||
CREATE INDEX IF NOT EXISTS shade_stream_state_status_idx
|
||||
ON shade_stream_state(status, direction)
|
||||
`;
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS shade_peer_verifications (
|
||||
peer_address TEXT PRIMARY KEY,
|
||||
fingerprint TEXT NOT NULL,
|
||||
verified_at BIGINT NOT NULL,
|
||||
verified_by TEXT NOT NULL,
|
||||
identity_version BIGINT NOT NULL
|
||||
)
|
||||
`;
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS shade_peer_identity_versions (
|
||||
peer_address TEXT PRIMARY KEY,
|
||||
version BIGINT NOT NULL
|
||||
)
|
||||
`;
|
||||
}
|
||||
|
||||
export async function ensurePrekeyServerTables(sql: Sql): Promise<void> {
|
||||
@@ -128,3 +143,99 @@ export async function ensurePrekeyServerTables(sql: Sql): Promise<void> {
|
||||
CREATE INDEX IF NOT EXISTS shade_server_otp_address_idx ON shade_server_one_time_prekeys(address)
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tables for the Key-Transparency log (V3.12).
|
||||
*
|
||||
* Append-only invariant for `shade_kt_leaves`:
|
||||
* - Application code never UPDATEs or DELETEs leaves.
|
||||
* - A trigger guards against accidental mutation in misconfigured ops:
|
||||
* even a misbehaving DBA query is rejected, which protects the log
|
||||
* from silent re-writes.
|
||||
*/
|
||||
export async function ensureKTLogTables(sql: Sql): Promise<void> {
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS shade_kt_leaves (
|
||||
leaf_index BIGINT PRIMARY KEY,
|
||||
leaf_hash TEXT NOT NULL,
|
||||
timestamp_ms BIGINT NOT NULL,
|
||||
operation SMALLINT NOT NULL,
|
||||
address TEXT NOT NULL,
|
||||
bundle_hash TEXT NOT NULL
|
||||
)
|
||||
`;
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS shade_kt_leaves_address_idx
|
||||
ON shade_kt_leaves(address)
|
||||
`;
|
||||
await sql`
|
||||
CREATE OR REPLACE FUNCTION shade_kt_block_mutations()
|
||||
RETURNS trigger AS $$
|
||||
BEGIN
|
||||
RAISE EXCEPTION 'shade_kt_leaves is append-only: % rejected', TG_OP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql
|
||||
`;
|
||||
await sql`DROP TRIGGER IF EXISTS shade_kt_leaves_no_update ON shade_kt_leaves`;
|
||||
await sql`
|
||||
CREATE TRIGGER shade_kt_leaves_no_update
|
||||
BEFORE UPDATE OR DELETE OR TRUNCATE ON shade_kt_leaves
|
||||
FOR EACH STATEMENT
|
||||
EXECUTE FUNCTION shade_kt_block_mutations()
|
||||
`;
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS shade_kt_index (
|
||||
address TEXT PRIMARY KEY,
|
||||
latest_leaf_index BIGINT NOT NULL,
|
||||
bundle_hash TEXT NOT NULL,
|
||||
deleted BOOLEAN NOT NULL DEFAULT FALSE
|
||||
)
|
||||
`;
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS shade_kt_sths (
|
||||
tree_size BIGINT NOT NULL,
|
||||
timestamp_ms BIGINT NOT NULL,
|
||||
root_hash TEXT NOT NULL,
|
||||
index_root TEXT NOT NULL,
|
||||
log_id TEXT NOT NULL,
|
||||
signature TEXT NOT NULL,
|
||||
PRIMARY KEY (tree_size, timestamp_ms, signature)
|
||||
)
|
||||
`;
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS shade_kt_sths_timestamp_idx
|
||||
ON shade_kt_sths(timestamp_ms DESC)
|
||||
`;
|
||||
}
|
||||
|
||||
export async function ensureInboxServerTables(sql: Sql): Promise<void> {
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS shade_inbox_owners (
|
||||
address TEXT PRIMARY KEY,
|
||||
signing_key TEXT NOT NULL
|
||||
)
|
||||
`;
|
||||
await sql`CREATE SEQUENCE IF NOT EXISTS shade_inbox_seq`;
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS shade_inbox_blobs (
|
||||
address TEXT NOT NULL,
|
||||
msg_id TEXT NOT NULL,
|
||||
ciphertext TEXT NOT NULL,
|
||||
received_at BIGINT NOT NULL,
|
||||
expires_at BIGINT NOT NULL,
|
||||
PRIMARY KEY (address, msg_id)
|
||||
)
|
||||
`;
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS shade_inbox_addr_expires_idx
|
||||
ON shade_inbox_blobs(address, expires_at)
|
||||
`;
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS shade_inbox_addr_received_idx
|
||||
ON shade_inbox_blobs(address, received_at)
|
||||
`;
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS shade_inbox_expires_idx
|
||||
ON shade_inbox_blobs(expires_at)
|
||||
`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user