Skip to content

feat(truapi): Pocket modality RFC and protocol spec - #609

Draft
valentinfernandez1 wants to merge 2 commits into
mainfrom
rfc/pocket-modality
Draft

feat(truapi): Pocket modality RFC and protocol spec#609
valentinfernandez1 wants to merge 2 commits into
mainfrom
rfc/pocket-modality

Conversation

@valentinfernandez1

Copy link
Copy Markdown
Collaborator

Tracking issue: #563

What this defines

Pocket is a collection of product-backed cards owned by the host. Each card shows a product's key information at a glance and opens the product when tapped.

The host renders each collapsed card natively from a CustomRendererNode tree that the product's worker streams. Tapping a card opens the product's Widget executable in a WebView.

A product cannot add a card on its own. The user adds one by following a Pocket deeplink and approving a host dialog that shows the card as it will look. Both the user and the owning product can remove a card. Humanity, Balance and Scarcity are privileged cards. They are always present and nobody can remove them.

Chat and Pocket share the product's single Worker executable. Its lifetime is a reference count: one reference per active chat, one per visible card. The host terminates the worker when the count reaches zero. When the worker starts, its entry module runs under a bounded time and memory budget.

The RFC also defines the deeplink format and where card definitions are published:

  • Deeplinks: polkadot://<product>.<tld>/-/pocket/add?card=<id> offers to add a card, and /-/pocket/open?card=<id> expands one. The first path segment - is reserved for host-handled targets.
  • Card definitions: the Worker manifest gains a pocket.cards list. Each entry names the card and points at a static preview tree inside the product archive, so the approval dialog runs no product code.

Protocol surface

Method Direction Ids
pocket.list_subscribe product to host 198 to 201
pocket.remove_card product to host 202 to 203
pocket.action_subscribe product to host 204 to 207
pocket.card_render host to product 208 to 211

The Pocket trait is available to the Worker execution only. Every payload travels in a V1 envelope. A card_render item encodes byte for byte like a chat custom-message render item, so a host that decodes one decodes the other.

The renderer tree types (CustomRendererNode, its props, modifiers and tokens) live in truapi::v01::renderer and are re-exported through truapi::latest. Chat uses them from there. Their wire encoding is unchanged.

Scope

This PR contains the RFC and the crate-level spec only.

truapi-server implements the trait with the default bodies. A host without a Pocket surface answers remove_card with Unavailable, ends the two subscriptions with an empty Interrupt frame, and never opens card_render. ProductRuntimeControl::render_pocket_card is the entry point a host calls to open a face stream.

Pocket behaviour in the runtime, the platform trait, the native bindings and the CLI is tracked by the "Implementation, rust-core" task in #563.

@valentinfernandez1
valentinfernandez1 requested a review from a team September 4, 2026 16:02
@valentinfernandez1
valentinfernandez1 marked this pull request as draft September 4, 2026 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant