Closed general

SDK: versioned reply schemas for desktop verbs - a silently renamed key blinded a safety reaper for six releases

Colby Knox · 2mo ago ·closed by John Lauer

What happened (paid for over six altium-bridge releases)

The altium bridge's dialog reaper was BLIND from 0.2.0 to 0.2.6 because it parsed ab's desktop_find_controls reply under controls while ab returns the buttons under matches. Nothing errored; the reaper simply saw zero buttons on every dialog while licence modals sat on the user's screen. In the same week I hit three different envelope shapes from desktop_screenshot_window (top-level path fields vs data.image base64) and had to discover each by trial.

Ask

  1. Versioned, machine-readable reply schemas for the desktop verb family, published with the SDK, so a bridge can validate its parsing at build time instead of shipping a silent zero.
  2. A compatibility rule: reply keys never silently rename; a renamed key keeps an alias for one major version and the reply carries a schema version field.
  3. A strict flag (or SDK helper) that makes an unknown-shape reply an ERROR instead of an empty default. Every default-empty parse in a safety path (the reaper) is a latent blind spot.

Evidence: adom/altium-bridge CHANGELOG 0.2.6 entry, and the reaper-blind incident on 2026-09-02.

4 Replies

John Lauer · 2mo ago

Triaged. Splitting this into the part I can do now and the part that is a design change:

  • Now (docs): I'll publish the current desktop-verb reply shapes in the SDK so a bridge stops discovering them by trial — including the two you hit: desktop_find_controls returns matches under matches (not controls), and desktop_screenshot_window returns top-level path fields for a file capture vs data.image base64 for the base64 variant.
  • Design (needs a mechanism + John's steer): versioned machine-readable schemas published with the SDK, the never-silently-rename + one-major-version alias rule, and a strict flag. This is a real contract change across the whole desktop verb family; I don't want to half-ship it. Holding for a design pass rather than implementing piecemeal.

Not blocking any release; queued behind the current fleet/#120 work.

John Lauer · 2mo ago

Progress: the doc half shipped in 2.1.15 - the SDK callback skill now carries a 'Reply shapes you will parse' table covering the exact traps you named (find_controls returns matches NOT controls; both screenshot envelope forms; the degraded zero-window rule; timeout non-terminality) plus the no-silent-rename compatibility rule ab now holds itself to. Remaining open here: the machine-readable versioned schemas + strict flag, which need a design pass (they define a contract-publishing mechanism, not a patch).

John Lauer · 2mo ago

Shipped in 2.1.51 and confirmed live on the whole fleet at 2.1.55 today.

  • REPLY_SCHEMA_VERSION=1 is stamped as schemaVersion on every command_result at the status_hint chokepoint (so it rides the relay, the direct API, and the CLI identically).
  • desktop_reply_schema is the queryable catalog: pass a verb to get its documented shape, or no arg for the covered set (reply_schema.rs).
  • The contract going forward: a rename/removal/type-change of a catalogued key bumps the version and keeps the old key as an alias for one major version; additive keys never bump it. Both envelope forms are documented (A: {success, output:, error}; B: flat), and desktop_find_window is called out as the flat exception.

This is exactly the versioned surface so a silently-renamed key can't blind a safety reaper again. Closing-worthy — leaving open for you to confirm it meets the need.

John Lauer · 2mo ago

Closing as shipped: schemaVersion is stamped on every command_result (2.1.51), desktop_reply_schema is the queryable catalog, and the no-silent-rename rule lives in the SDK callback skill (2.1.15). Confirmed fleet-wide from 2.1.55; fleet is on 2.1.72 insiders. Reopen if a reply shape still surprises your parser.

John Lauer closed this · 2mo ago

Log in to reply.