Closed feature request

SDK change (REQUIRED): slow verbs must report measured progress - percent, ETA, cold vs warm

John Lauer · 2mo ago ·closed by John Lauer

SDK CHANGE - re-audit required. The Bridge SDK gained a REQUIRED rule today (billboard + SKILL.md + bridges-SDK.md all updated, verified served):

Every slow verb reports MEASURED progress - percent, ETA, and cold-vs-warm.

It was a SUGGESTION on 2026-08-14 and that was not enough: a live Fusion surface button still sat on "starting the app ... cold start can take a couple of minutes". That is a shrug, not data - a UI cannot draw a bar from it, the user cannot tell slow from wedged, and the number never narrows.

The shape (full spec + rationale in the SDK under "REQUIRED: every slow verb reports MEASURED progress"):

"progress": {
  "phase": "cold_start", "stepLabel": "Loading the electronics workspace",
  "percent": 38, "elapsedSec": 27, "estimatedSec": 71, "etaSec": 44,
  "confidence": "measured", "startKind": "cold"
}

Key points: percent MONOTONIC; estimatedSec REVISED as you learn (a static constant is not an estimate); cold vs warm measured + reported separately (they differ 10-50x) with a rolling per-machine history seeded from real samples and exposed in describe; long verbs return {started, jobId, statusVerb, progress} and stay pollable (never block silently past your own timeout); terminal frames carry actuals + the failing phase.

ab forwards progress VERBATIM (no parsing, no per-app logic - same generic-renderer rule as the status chip and stepShot) and renders the bar; ab will report its own slow operations in the same shape, so this is symmetric rather than something only bridges owe.

Your demo verb already proves the shape works - the gap was that ONLY the demo verb did it. Instrument the rest: *_start, *_show_*, install/export/build, anything with a p50 over ~3s.

Tracking + discussion: kicad-bridge#32 and fusion-bridge#32 (the two EDA bridges are the motivating cases; the rule applies to every bridge). Push back there if you want a different shape - one shape everyone likes beats several.

2 Replies

John Lauer · 2mo ago

Shipped in pup 2.0.383 (insiders; promote pending). Terminal frame: pup_open_window returns progress {phase cold_start|open_window, stepLabel, percent 100, elapsedSec (actual), estimatedSec (median of THIS machine's rolling history per start kind, ~/.adom/pup-timings.json, last 20 samples), etaSec 0, confidence unknown->estimated->measured as samples accrue (measured at 3+), startKind cold|warm, launchMs on a cold spawn}. Cold vs warm are measured and kept separately (the spawn site times puppeteer.launch; a window joining a live browser is warm). The Chrome-for-Testing download reports percent from bytes plus elapsed and an ETA computed from the real byte rate (chrome.js readiness), never a constant. pup_describe exposes progressContract {statusVerb pup_readiness, slowVerbs, blockedByPhases} and the timing history the estimates come from. Verified live on AdomLapper: a warm open returned elapsedSec 1.4, startKind warm, confidence unknown on the very first sample (history was empty), which is the honest ladder. Live rows are in #64.

John Lauer closed this · 2mo ago
John Lauer · 2mo ago

Addendum: the first cut (2.0.383) reported frames but never persisted samples - my helper was named recordTiming, and an older function recordTiming(opName, ms) later in server.js (the win32 call-stats helper) silently won, since a later function declaration overrides an earlier one. Renamed to collision-proof names in 2.0.385 and verified the ladder live on AdomLapper: three warm opens -> estimatedSec 1, confidence estimated, estimated, then measured on the third sample; pup_describe now shows the history (open_window_warm: 3 samples). Lesson recorded for the SDK: a bridge adding progress helpers into a large single file should grep for name collisions first.

Log in to reply.