mirror of
https://github.com/mvschwarz/openrig-studio.git
synced 2026-11-07 05:56:21 -10:00
Six findings from building a small app against the v0.6.0 tag using only the README, the skill and the contract docs. None blocked the build; the most valuable were about the ROUTE IN rather than the product. THE SKILL NEVER MENTIONED THE THREE PRIMITIVES. Its "Read next" table listed four documents and change-signal.md, focus.md and drive.md were not among them — watchSignal and driveSurface appeared nowhere, and its one "focus" mention was SHELL focus, meaning navigation. The README tells coding agents to load the skill FIRST, so an agent following that instruction learned nothing about the three features this SDK is for. It now leads with them: what you want, what to read, what you call, and which two the scaffolder has already wired. THE GENERATED PROJECT'S OWN README had the same hole while the page beside it already called driveSurface — code doing something the shipped docs did not explain. It now carries the three primitives and says which are already in the page. Its test is keyed on what the emitted page actually IMPORTS, so the doc cannot drift away from the code it describes. A DRIVE OP POSTED BEFORE A SURFACE LOADED WAS REPLAYED ON LOAD. Measured in the cold build with a brand-new page: it applied an op that predated it and showed that op's narration on boot. The runtime keeps the last op forever, so every never-seen-it page treated it as new — a reload re-ran it, a second tab ran it again. Harmless for `select`; for `play`, `export` or `delete` it is a side effect nobody asked for, arriving unbidden in every new tab. Ops that predate a surface are now HISTORY, NOT INSTRUCTIONS: the first poll adopts the current generation as a baseline and applies nothing. Both readings were defensible, which is why the surprising one must not be the silent default. `resumeLatestOnLoad: true` opts back in for surfaces whose ops are pure view state. The one race — an op posted between load and first answer is skipped — is stated in the contract rather than hidden, and it fails toward doing nothing rather than toward acting on stale intent. Verified in a browser, both halves: the stale op does not replay AND a live op still applies, so the fix is not deafness. NETWORKIDLE NEVER SETTLES against a studio, because /api/events stays open for the life of the page. The most common browser-automation wait times out on every page load, and the symptom reads as a slow or broken studio rather than as a wait that cannot succeed. Now documented where the stream is, with what to wait for instead. TWO STALE PACKAGE VERSIONS: the skill said 0.4.0 against a shipped 0.6.0, and a second 0.4.0 was hiding in shell-contract.md. Both were true when written. Rather than update numbers that go stale on every release, the docs no longer state the package version at all and point at the package instead. A guard now fails any shipped doc under skills/ or contract/ that hardcodes a three-part version — with IPv4 stripped first, since 127.0.0.1 is not a version, and a positive control so it cannot pass by finding no documents. THE TEMPLATE'S OWN FILENAME leaked into every generated README: it said `surface.html` while the emitted file is <name>.html, in a document where every other reference was correctly interpolated. Left alone deliberately: an unconfigured studio showing the SDK's fixture seat. The runtime is honest about it — the panel says it cannot be attached and says why, and manifest.seats.source makes it queryable. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>