Payload
Marker interface for self-contained typed payload slot types.
Generic-bounded payload slots (<P : Payload>) accept any type that implements this interface plus Nothing (covariance).
Strict transitive shape rule (buffer-codec lockdown v1, Change 1): the KSP processor walks the declared shape of every concrete Payload- implementing type referenced from an @ProtocolMessage data class and rejects raw-bytes types anywhere in that shape — ReadBuffer, WriteBuffer, PlatformBuffer, ByteArray, primitive arrays, java.nio.ByteBuffer. The walk descends through value-class wrappers and sealed Payload trees.
Why: a Payload outlives the codec's decode scope, but a raw-bytes member can reference reclaimed pool memory (the JS-aliased ByteArray case) or carry implicit ownership obligations the type system can't verify. Self-contained typed values close the bug class at compile time.
Decode into a self-contained typed value:
a value class around a scalar /
String/ domain objecta platform-native handle (e.g.
BitmapoverPlatformBitmapviabuffer.toNativeData()→ platform decoder)
For consumers who genuinely need raw bytes (IPC forwarding, persistence, debug capture), step outside the Payload abstraction: a non-Payload result type decoded by a hand-written Codec<YourType>. Inside that codec, use ReadBuffer.copyToByteArray for heap bytes, or factory.allocate().write(source) for a consumer-owned PlatformBuffer.