Message Flags
Reference WKProto fixed-header and Setting bits and understand persistence, red-dot, command, receipt, encryption, and stream boundaries.
Two different bit sets affect a message: low fixed-header booleans and message Setting bits. Integrators use SDK-exposed types instead of hand-written magic numbers; this page cross-checks wire meaning across languages.
Goal and completion criteria
For any flag, you can explain whether it affects persistence, routing, display, or encoding and avoid interpreting protocol intent as proof of business completion.
Authority
Fixed-header bits align with pkg/protocol/codec/common.go; Setting values align with pkg/protocol/frame/setting.go. Tests freeze bit order, names, and values.
Fixed-header bits
| Bit | Name | Scope | Integrator guidance |
|---|---|---|---|
0 | NoPersist | Wire flag | The plain non-command branch returns compatibility success without delivery; only the command-style branch enters transient online delivery. Neither has a durable sequence or offline recovery. |
1 | RedDot | Wire flag | Carries red-dot display intent; it is not a read receipt and does not by itself prove a server unread-count change. |
2 | SyncOnce | Wire flag | Routes command-style messages through a separate CMD Channel; recoverable commands additionally require binding and CMD synchronization. |
3 | DUP | Wire flag | Protocol retransmission marker; product idempotency still relies on a stable client_msg_no and result correlation. |
Setting bit values
| Value | Name | Scope | Integrator guidance |
|---|---|---|---|
128 | SettingReceiptEnabled | Wire flag | Enables protocol receipt intent; do not equate it with Channel commit, device-side business execution, or end-user read state. |
32 | SettingSignal | Wire flag | Marks compatible signal mode; use only when the selected SDK and protocol version explicitly support it. |
16 | SettingNoEncrypt | Wire flag | Skips negotiated session payload encryption; it does not replace TLS and should not be enabled for sensitive messages. |
8 | SettingTopic | Wire flag | Indicates that the packet carries a Topic field; Topic lifecycle remains a compatible-client and product contract. |
2 | SettingStream | Wire flag | Indicates compatible stream-message fields; durable AI stream projection and realtime deltas remain separate paths. |
NoPersist requires command semantics
Plain NoPersist does not deliver in real time
Plain non-command NoPersist, without SyncOnce and without a command Channel, returns compatibility success after pre-route checks but does not resolve authority, append, or deliver online. Only command-style NoPersist enters transient online delivery. Neither branch supports offline recovery.
Therefore:
- reliable chat, notification, audit, and replayable product events use ordinary durable messages;
- online-only commands use command semantics and accept that an offline target cannot recover them;
- recoverable commands use durable
SyncOncewith separate CMD bind/sync/ack; - never treat a successful
NoPersistresult as proof that a device received anything.
RedDot and receipts
RedDot carries client display intent through storage, delivery, and compatibility callbacks, but it does not mean:
- the server changed a Conversation
read_seq; - the end user viewed the message;
- the receiver emitted a product receipt.
SettingReceiptEnabled is also protocol receipt intent. SENDACK is a Channel commit result, RECVACK is Session transport feedback, and end-user read or device execution needs a separate product contract.
Encryption-related bits
SettingNoEncryptmakes compatible WKProto adapters skip negotiated Session payload encryption. It neither disables nor supplies TLS.- Never enable it for sensitive messages.
SettingSignalis specialized signal mode and requires explicit support from the exact SDK and protocol version.- Do not invent an end-to-end encryption guarantee from one bit; key distribution, identity verification, and rotation require a complete design.
Topic and Stream
SettingTopic indicates that the packet carries a Topic field. SettingStream indicates compatible stream fields; it does not automatically promise realtime token push, durable event projection, and reconnect recovery together. The current AI stream tutorial uses a durable base plus message-event projection and explicitly separates a realtime delta path.
Combination guide
| Requirement | Selection |
|---|---|
| Ordinary recoverable chat | NoPersist=false, SyncOnce=false |
| Online-only command | NoPersist=true, SyncOnce=true; accept no history |
| Recoverable command | NoPersist=false, SyncOnce=true; add CMD binding and sync |
| Product read receipt | Separate durable receipt; do not rely on RedDot or RECVACK |
| Streaming AI | Read AI & IoT instead of setting only the Stream bit |
Troubleshooting
- NoPersist succeeds but peer receives nothing: check for missing command-style
SyncOnce; the plain branch intentionally does not deliver. - Message cannot recover offline: inspect NoPersist or a missing CMD recovery flow.
- Red dot and unread disagree: inspect Message Flag separately from Conversation badge floor.
- One SDK fails after a Setting bit is enabled: verify exact SDK and protocol version rather than retaining an unknown bit blindly.
Security boundary
Unknown bits fail closed or are ignored safely by a compatible SDK; they never default to enabled. Raw setting and Header may enter controlled diagnostics, but never write them together with a complete sensitive payload into ordinary logs.
Next step
Apply these bits in Messaging, and classify outcomes through Reason Codes.