Skip to content

applink: content_transport.md frame notation is ambiguous about the type-tag byte #14

Description

@beyondeye

Summary

The AppLink data-plane frame notation in aidocs/applink/content_transport.md is ambiguous about whether the 1-byte type tag is part of the MessagePack array or a raw prefix byte. The prose and the example notation pull in opposite directions; only the server source disambiguates.

Surfaced while implementing the mobile decoder (aitasks_mobile t14_1, the applink wire codec) — caught during plan verification, but a future implementer reading only the doc could easily get it wrong.

The ambiguity

  • §Wire encoding (line 32): "every binary frame starts with a 1-byte type ID … The remainder is MessagePack-encoded." → reads as raw prefix byte + msgpack array of the rest.
  • §Frame types (lines ~95, ~109, …): frames are written as a single array literal, e.g.
    [0x01, pane_id, frame_id, cols, rows, cursor, [row, ...], osc8?]
    
    → reads as one msgpack array whose first element is the tag.

These two readings produce different bytes and an incompatible decoder.

Ground truth (from the server encoder)

.aitask-scripts/applink/content.py settles it — every encode_* does:

return bytes([FRAME_KEYFRAME]) + _packb(arr)   # e.g. content.py:384

i.e. a raw 1-byte tag prefix followed by a MessagePack array of the body fields only (the tag is NOT an array element). Also confirmed there: osc8 is appended only when non-empty, so the body array is variable length (e.g. keyframe is 6 or 7 elements) rather than carrying a nil placeholder.

Suggested doc fix

In §Frame types, either:

  • annotate the notation as logical-not-literal and state explicitly that 0xNN is a raw leading byte, the bracketed remainder is the msgpack array of body fields, and the tag is not an array element; and/or
  • show the body array without the tag, e.g. tag=0x01, then msgpack [pane_id, frame_id, cols, rows, cursor, [rows], osc8?].

Also worth making explicit (both already true in the encoder, easy to miss in the doc):

  • the trailing osc8? is omitted entirely when empty (variable-length array), and
  • packed truecolor is a negative int64 (-((0xFF<<24)|(r<<16)|(g<<8)|b)) that does not fit a signed 32-bit int — decoders must use a 64-bit read.

No behavior change requested — the wire format is correct and frozen; this is purely a documentation-clarity fix so consumers (mobile decoder, future clients) read it the same way the server writes it.

Filed from aitasks_mobile during t14_1; related to the t822 applink work that authored these docs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions