The Subscribe panel initializes its coupon model only when the layout owner's live data has no value for that input. Status changes keep the entered code. The framework text field uses immediate input with no debounce, and redemption captures the typed input before changing the panel to “Checking the coupon…”. Coupon validation, entitlement writes, install behavior, and content registration still use the existing Store funnel.

The text field's code pointer is relative to its coupon-model data context. An absolute /code pointer starts at the layout root, bypasses that context, and redraws the field blank even though the acknowledged coupon model still contains the typed value. The regression resolves the actual rendered control through the GUI binding API, so it covers the same pointer and context the browser uses rather than inspecting only the server-side model.

The old panel rebuilt host.Edit(new CouponInput(), id) on every status emission. That editor bound a fresh blank model to the same data key. A server-acknowledged client edit was therefore lost during a status redraw. An idempotent check against the render snapshot is insufficient: the top-level renderer accumulates its own snapshots. Initialization instead goes through host.Update against the current owner collection, outside the control's render data.

Store/Plugin/Test/CouponInputTests.cs contains both live regressions and PluginTestsArea registers them in the normal Store/Plugin Tests area. The redraw case renders the actual coupon panel, then queues an identity read on the same layout owner after each render. Typed, JsonElement, and JsonObject values must survive idle, redeeming, and validation-error states. The click case resolves and validates the rendered field's pointer, data context and immediate write settings, records the acknowledged edit on the layout owner, fences on that serialized owner, and dispatches the real ClickedEvent to the rendered Redeem control. Its random non-empty code must reach lookup and report Invalid coupon code.; Enter a coupon code. proves the redraw discarded the edit. Because the synthetic code does not exist, this click case cannot grant an entitlement or start an install. Both cases restore the original input and status slots on the owner queue and wait for that update before succeeding; they also clean up on failure.

Baseline and candidate proof — 11 September 2026

A focused host fixture used actual LayoutAreaHost, the remote layout client, and UpdatePointer to enter a synthetic coupon. It waited for the owner's populated echo before changing status, observed the new error control, and then read the owner inside its serialized update queue. This avoids mistaking an earlier replayed value for retained input. Two further fixture cases execute the exact native regression above, verifying restoration of an existing input and removal of a previously absent slot.

All three cases failed against unchanged Plugins 481298ac3f1bf4fe5a6af843b4fc60adf023faae product source, and all three passed after this correction. The native case covers nine shape/status combinations. The isolated framework checkout was core b65c1957de948673c997c0584f13773c41c3e101, matching the failed Education CI framework source. The Store/Plugin library was emitted by that core's unchanged canonical compile-check.py using its declared source, test, and configuration closure; the host fixture built strictly with zero warnings and errors. It references a library, never a test executable.

The local receipt is /private/tmp/coupon-input-results/final-receipt.json; adjacent before-final.trx and after-final.trx record 3 failed then 3 passed, with the same test source and framework references. host-fixture/ preserves the narrow SDK wrapper, and /private/tmp/coupon-input-node-library/inputs.json records compiler inputs. These are local investigation artifacts, not deployable dependencies. The durable regressions run through Store/Plugin's normal Tests area in CI. The click case covers the native bound-write-to-action path; a real browser and production redemption remain separate delivery checks because this test deliberately uses a missing code and makes no grant.

Reconnecting…
The server was updated. Reloading the page to pick up the latest version.