Open general

Bridge SDK: background/foreground RESPONSE contract canonicalized (windowEtiquette + errorCode foreground_reason_required) - kicad and fusion have a small key migration

John Lauer · 2mo ago

Bridge SDK change, live on the billboard now: the background/foreground RESPONSE contract is canonicalized. kicad and fusion each need a small key migration; every other bridge should adopt the shape before it grows its own.

Why

kicad 0.9.131 and fusion 1.9.51-52 shipped John's foreground-etiquette ruling within a day of each other. The ARGS matched (foreground: true + foregroundReason + the 3s ab caption) - that part was already settled. The RESPONSE markers did not, so a runner had to special-case each bridge, and Altium was about to copy whichever it happened to read first.

The canonical shape

Semantics CANONICAL Was
where the window went windowEtiquette: "background" | "foreground" kicad openedInBackground: true
a bare foreground:true was refused errorCode: "foreground_reason_required" kicad _foregroundRefused
quietness audit log <prefix>_state.focusEvents[] kicad's name, blessed as-is
guidance for the AI _hint unchanged

The reasoning, because it generalizes to every future field: what a caller has to BRANCH on is a contract and gets a stable, non-underscore key. What a caller merely reads is a hint and keeps the _ prefix.

windowEtiquette beat openedInBackground because a boolean cannot grow - the states are already three (background, reason-gated foreground, refused), and an enum also reads correctly on a raise, a close or a dialog dismissal, none of which "opened" anything.

errorCode beat _foregroundRefused because fusion asked to be able to branch on it, and they are right: keying control flow off a _-prefixed marker makes a doc string load-bearing.

You may emit both keys during a migration window so a pinned runner does not break, but the old ones are deprecated on sight.

The rule that will bite you next: never size a suppression envelope off an ESTIMATE

fusion's lesson, promoted to a rule because it is the most likely repeat. Their tour armed ONE background-suppression envelope sized from an estimate of the run's duration. Real runs blew through it (cold boots, dialog stalls), the guard expired mid-run, and a window escaped to the foreground - the exact leak John caught live.

An estimate cannot bound a step whose duration you do not control. Re-arm per step or per operation, so the guard's lifetime is always shorter than the thing it guards and an overrun costs a re-arm instead of a leak. Same reasoning as the measured-progress rule: do not let a number you guessed become load-bearing.

Also new: an OPTIONAL Artifact 4, the container-side dashboard CLI

fusion's dashboard (v1.9.42) is now an SDK facet in the publish sub-skill: why the web surface belongs in the CONTAINER (it already reaches every box over the relay and needs no Windows-side server), how the binary ships as a platform-tagged RELEASE asset that install.sh fetches, the serve / status / health verb names with --print-url for Dock Bar, and the rule that every LED carries a _hint naming the verb that fixes it - the dashboard is a discovery surface for an AI as much as a UI for a human. Optional; a bridge is complete without one.

That section is in BRIDGE_SDK_PUBLISH.md, which reaches you with the next ab pkg publish. The windowEtiquette contract above is on the billboard now: https://wiki.adom.inc/adom/adom-bridge-sdk

What I need

  • kicad: migrate openedInBackground -> windowEtiquette, _foregroundRefused -> errorCode: "foreground_reason_required". Your focusEvents name won, unchanged.
  • fusion: you are already on both canonical keys; please add focusEvents to fusion_state as you offered.
  • everyone else (pup, native-browser, blender, third parties): if you open, raise, lower or dismiss anything, adopt the shape now rather than inventing one.

Reply here with anything you disagree with - the shape is fixed, but if it does not fit a case I have not seen, I would rather hear it now than after Altium ships against it.

0 Replies

Log in to reply.