CryptoContext + optionale suspend-context-Varianten (Default → sync-Basis → bestehende Provider+Tests unverändert); ScopeVaultClient (Ktor, 404/410); ScopedCryptoProvider (delegiert pro Scope an MasterKeyCryptoProvider mit Sub-Key, Mutex-Cache, Master-Fallback, shredded→wirft); createScopedKeyProviderFromVault; EventSyncConfig.scopeResolver → Factory baut Scoped-Provider, Context an emit/pull/reencrypt. Parität zu @mana/event-sync 0.7.0 + mana-swift-event-sync 0.6.0. Build + Tests grün, abwärtskompatibel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.5 KiB
3.5 KiB
Changelog
0.5.0 — 2026-06-16
- Per-Mandant-Crypto-Shredding (A3), Parität zu
@mana/event-sync0.7.0 +mana-swift-event-sync0.6.0:CryptoContext+ optionalesuspend- context-Varianten vonencryptPayload/decryptPayload(Default forwarden zur synchronen Basis → bestehende Provider + Tests unverändert).ScopeVaultClient(Ktor: getOrMint/get/shred gegen/encryption-vault/scopes/:appId/:scopeId/key, 404→ScopeNotFoundException, 410→ScopeShreddedException).ScopedCryptoProvider(delegiert pro Scope an eineMasterKeyCryptoProvider- Instanz mit dem Sub-Key, Mutex-Cache, Master-Fallback; geschreddert → wirft).createScopedKeyProviderFromVault.EventSyncConfig.scopeResolver→ Factory baut den Scoped-Provider; Context an emit/pull/reencrypt durchgereicht. Wire identischenc:1:, abwärtskompatibel, bestehende Tests grün.
0.4.0 — 2026-06-10
- Decrypt-Failures sichtbar statt Silent-Skip (Parität zu
@mana/event-sync0.6.0 +mana-swift-event-sync): Ein nicht- entschlüsselbares Event aus dem Pull wurde bisher viarunCatching{}.getOrNull()still verworfen — die App sah nie, dass ihr Daten fehlen (derenc:1-Footgun). Jetzt:- persistenter Zähler in Meta (
decrypt-failure-count,…-last-at,…-last-event), abfragbar viastats()→decryptFailures/decryptFailureLastAt, Reset viaclearDecryptFailures(); - neuer Hook
onDecryptFailure: ((DecryptFailure) -> Unit)?pro Event, zusätzlich feuertonErrormitEventSyncError.DecryptFailed(eventId); decryptPulledPayload(payload, eventId, provider)wirft auch, wenn der Provider den Ciphertext unangetastet durchreicht (NoOp ohne Key) — vorher wäre derenc:1:-String als „Plaintext" in der Projektion gelandet. Der Pull-Cursor wandert trotz Failures weiter — Sync hängt nicht fest.
- persistenter Zähler in Meta (
0.2.0 — 2026-06-04 (Phase 2 Teil 2)
EventSyncEngine— vollständige Orchestrierung (Port von Swift): Anonymous-First-Identität, Emit (lokal + Outbox + Crypto-Wire), Pull-Loop (decrypt + Projektion + Cursor),signIn-Claim (anon→sub Re-Attribution + Re-Encrypt + Drain), Poll-Timer, Soft-Fail, Schema-Outdated-Stop, Crypto-Degraded-Outbox-Pause, Aggregate-Change-Listener.EventStore(Interface) +InMemoryEventStore— Event-Log + Outbox + Meta + Retention; Room-Adapter folgt im App-Modul.SyncTransport/SyncWebSocket— Abstraktionen;SyncHttpClientimplementiertSyncTransport.createEventSyncEngine(...)— Produktions-Verdrahtung (HTTP + Vault).EventSyncConfig/AuthMode/ClaimResult/EngineStats/AnonymousRetention.- 36 Tests (inkl. Crypto-Roundtrip über zwei Geräte, signIn-Claim, Schema-Outdated). Braucht mana-kotlin-core 0.2.0.
0.1.0 — 2026-06-04 (Phase 2 Teil 1)
Erstes Skelett. Phase 2 (Teil 1) des Android-Plans
(WORDECK_ANDROID_GREENFIELD.md).
MasterKeyCryptoProvider(AES-GCM-256) +NoOpCryptoProvider— wire- kompatibel zu Swift/TS, byte-genau bewiesen per WebCrypto-Golden-Vektor.VaultClient+createMasterKeyProviderFromVault(Key-Fetch, ZK-Erkennung).EventEnvelope+ActorContext+ flexibler Long-Serializer (sequenceNumber als String oder Zahl).Ulid(Port der Swift-Generierung).SyncHttpClient(append/pull gegen mana-sync, 422→SchemaOutdated).- 26 Tests grün.
Offen (Teil 2): WebSocket-Client, Room-EventStorage, EventSyncEngine.