Skip to content

Protocol and limits

PAM Native uses a versioned, bounded, little-endian binary protocol between persistent PHP, the Rust engine, Android, and iOS.

SDK Protocol PHP Android
pushinbr/pam-native 0.2.x 1 8.4.x API 26–36

The Swift peer decodes protocol version 1 and rejects unknown node kinds, invalid property values, oversized frames, malformed lengths, and trailing bytes before UIKit mutation.

All three peers must support the exact protocol version. A mismatch is rejected before applying a node or mutation.

Protocol identifiers are sequential integers beginning at 1. Existing identifiers are never renamed, reused, or renumbered.

New optional properties, node kinds, events, and operations may be appended. Changing an existing field’s representation or meaning requires a new protocol version and an explicit compatibility adapter.

Protocol version 1 currently defines properties through ID 284 and events through ID 34.

Frame Magic Producer Consumer
Complete tree PNT1 PHP Rust
Incremental patch PNP1 PHP Rust
UI mutation batch PNB1 Rust Android or iOS

Each frame starts with a four-byte magic value, a u16 protocol version, and bounded payload counts. Strings and opaque values use a u32 byte length. Node IDs are non-zero u64 values.

Decoders reject:

  • duplicate node IDs or properties;
  • cycles and disconnected trees;
  • invalid enum values;
  • trailing bytes;
  • malformed lengths; and
  • payloads above the published bounds.
Operation ID
Create subtree 1
Remove node 2
Update property 3
Move node 4
Set root 5
Resource Limit
Complete frame 16 MiB
Nodes 100,000
Tree depth 512
Properties per node 128
String or opaque property 1 MiB
Queued native event payload 1 MiB

These are part of protocol version 1. They protect memory use and decoder complexity and must not be raised silently for a single application.

Rust tests pin byte-for-byte tree, patch, and mutation frames. PHP tests pin sequential enums and deterministic encoding. Android and iOS check the protocol version before decoding.

Changing a golden frame under protocol version 1 is a release blocker, not a routine snapshot update.

The canonical tables live in:

  • PHP: NodeKind, PropKey, EventKind, and NativeOperation;
  • Rust: pam-native-protocol/src/lib.rs; and
  • Android: PamProtocol.kt, PamRenderer.kt, and NativeModuleRegistry.kt; and
  • iOS: PamProtocol.swift, PamRenderer.swift, and NativeModuleRegistry.swift.