Back to Bitchat Android

Client rewrite compatibility contracts

docs/client-rewrite-contracts.md

2.0.23.8 KB
Original Source

Client rewrite compatibility contracts

This document defines the behavior a from-scratch BitChat client must preserve. The executable source of truth is the JVM test suite under app/src/test/**/contracts, together with the pre-existing protocol, security, mesh, and state tests.

The remaining implementation work and milestone progress are tracked in test-implementation-plan.md.

Required contract layers

LayerCompatibility promisePrimary tests
Outer mesh packetv1/v2 header widths, big-endian fields, flags, section order, route placement, signature placement, padding, compression, signing bytesBinaryProtocolTest, ClientRewriteWireContractTest
Chat payloadFlag bits, millisecond timestamp, UTF-8 byte lengths, encrypted-content substitution, optional-field orderClientRewriteWireContractTest
Inner payloadsNoise type bytes, private-message TLVs, peer-state TLVs, file-transfer TLVs, live-voice bursts, fragment header, sync request TLVsClientRewriteWireContractTest, AuthenticatedPeerStateTest, PrivateMediaTransferPreparerTest, VoiceBurstPacketTest, FragmentManagerTest
Identity/securityAnnouncement extensions, capability bitfield endianness, Noise static-key binding, handshake identity binding, signaturesIdentityAnnouncementTest, NoiseSessionManagerIdentityBindingTest, ClientRewritePrimitiveContractTest
Sync/routingStable packet IDs, GCS bitstream, replay collapse, TTL handling, relay choice, confirmed graph edgesClientRewritePrimitiveContractTest, GCSFilterTest, PacketRelayManagerTest, MeshGraphServiceTest, TransportBridgeServiceTest
NostrBech32, secp256k1 key derivation, NIP-01 event IDs/signatures, NIP-44 authenticated encryption, NIP-13 PoW, authenticated NIP-17 sealsClientRewriteNostrContractTest, NostrProtocolTest
Application statePeer unions, canonical private conversations, chronological history, delivery/read behavior, media migration policyAppStateStoreTest, PrivateChatManagerTest, MediaSendingManagerMigrationTest

Golden-vector policy

Golden vectors compare literal externally visible bytes or hashes. Do not update them merely because an implementation changed. Update a vector only when the wire protocol is intentionally versioned and interoperating clients are updated together.

Round-trip tests remain useful but are not sufficient on their own: an encoder and decoder can share the same defect. Each critical wire format therefore has at least one literal vector.

Rewrite acceptance gate

From a configured Android development environment, run:

sh
./gradlew clientRewriteContractTest

The task runs the new golden vectors and the complete existing unit suite. A rewrite is compatible only when this gate passes. Tests should be ported unchanged when package boundaries change; adapter façades are preferable to weakening assertions.

Device-only acceptance

Local JVM tests cannot prove Android radio and lifecycle behavior. Before shipping a rewrite, run the following on at least two physical devices:

  1. BLE discovery, connection, disconnect, reconnect, and multi-hop relay.
  2. Runtime permission denial/retry for Bluetooth, location, notifications, and microphone.
  3. Foreground-service survival with the screen off and after process recreation.
  4. Cross-client Android/iOS exchange for announce, public/private text, delivery and read receipts, image/audio/file transfer, sync replay, and Nostr fallback.
  5. Corrupt, duplicated, reordered, delayed, and partially delivered fragments.
  6. Identity rotation, verification continuity, downgrade rejection, and recovery after stale Noise sessions.

Those scenarios belong in instrumented tests or a two-device interoperability harness; they must not be represented as passing JVM mocks.