Cover actions keep the same view identity as their state changes. Get can become Repair or Update, and Resume can appear ahead of Start, without moving the install action to another address. Navigation identities follow their destinations, including folded menu entries; translated labels do not change them. Equivalent repeated links retain distinct view slots.

The cover previously assigned positional view IDs. Its first owner frame could be Start at 1 and Get or Repair at 2. A later progress record prepended Resume: Start then occupied 2 and Repair moved to 3. A click retained from the browser's first frame still addressed 2. The framework resolves ClickedEvent.Area against the owner's current control; the new Start control carries client navigation but no server ClickAction, so that event was processed without opening a dialog. Waiting for an installed-state Repair label alone does not prevent this race: Resume can arrive afterward.

The production CtaRow query pipeline still uses the same entitlement, manifest, source and progress streams. Its existing projection is extracted as BuildCtaRow, used by both the live row and the regression. Rendering assigns IDs from the action (install mode or navigation destination), with an occurrence suffix for equivalent duplicate links. It does not change entitlement decisions, install behavior, button order, labels, or destinations.

Executed causal proof — 11 September 2026

The local source base is Plugins b09e2d0f892f0b0fc0f154f1f8291c82a6494c0d, which includes the coupon-input correction. The isolated SDK host uses core b65c1957de948673c997c0584f13773c41c3e101. The core's canonical compiler emits the declared Store/Plugin source, tests and configuration as one library; the existing HubTestBase wrapper renders the committed native cases through a real LayoutAreaHost.

CtaActionIdentityTests covers two distinct initial states: fresh Get, and already-installed Repair. Each retains the initial action's actual rendered area, then renders real-shaped install and CourseProgress records through the production projection. It posts the retained ClickedEvent, followed by a second owner-dispatched fence. The fence queues a read after the first action and its queued updates, and requires the actual Repair DialogControl. The test also checks both navigation destinations and the retained Start identity. Dialog data and any previous dialog are restored on the owner's queue; no entitlement or persistent learner data is written, and no install action is executed.

With the unchanged positional IDs (only the projection extracted), both cases failed at the owner fence: “The retained install click was processed without opening its dialog.” The failures took 334 ms and 84 ms, rather than waiting for a timeout. The same cases passed after assigning action identities (2/2, 441 ms). The final tightened cases and the three existing coupon owner/input regressions passed together (5/5, 683 ms); the SDK build had zero warnings or errors. The fixture also confirms the shared dialog slots are absent again after completion.

The mandatory node compile gate passed all 89 types against the existing implementation refs. Repository validation passed 261 nodes across 60 packages, and all 60 content locks matched. The supported native Store runner passed all 871 pure tests in this isolated coupon branch (the separate privacy branch adds another pure case). Its standalone build still reports the pre-existing nullable warning in the contact-label code, now at PluginLayoutAreas.cs:1905; no suppression or unrelated source correction was added.

Validation commands from the Plugins checkout:

python3 scripts/compile-check.py --refs /Users/roland/.cache/meshweaver/roadmap-validation-refs
python3 scripts/run-node-tests.py Store --refs /private/tmp/coupon-input-b65-refs --keep
python3 scripts/gen-manifests.py
python3 scripts/validate-repos.py
python3 scripts/gen-manifests.py --check

The host wrapper build/test commands use src/MeshWeaver.PluginCatalog.Test with -p:MeshWeaverRoot=/Users/roland/code/MeshWeaver-coupon-input-core/, Release, -warnaserror for build, and --no-build --no-restore for test. The focused filter is FullyQualifiedName~CouponInputStateTest. Its temporary project reference targets the emitted Store library, not another test executable. The wrapper and compiler inputs are retained beside the receipts; normal CI runs the two committed native cases through the Store/Plugin Tests area.

Local detailed receipts are under /private/tmp/coupon-input-results/: cta-before.trx, cta-after.trx, cta-final.trx, their build/test logs, cta-before-source/receipt.json, and cta-host-fixture/. These paths identify retained local evidence, not portable dependencies. The committed native cases are registered in the normal Store/Plugin Tests area; the SDK wrapper is only an independent execution host for those same cases.

Browser evidence and acceptance boundary

Education run 34554516873, source 415030795d11bb2169f39f871e972e42a85bc73b, used core b65 and framework s97d409b0b43a45d5386a9313d514e2c8. Its failed cold cover click shows Start/Get becoming Resume/Start/Repair without a reconnect. The later local coupon acceptance also shows Start/Repair before its missed click and Resume/Start/Repair afterward. The traces do not record owner dispatch ordering, so they are consistent with the proven defect rather than proof that this was the sole cause of either particular browser failure. The retained CI artifacts identify the portal digest and core, but do not establish an exact Plugins source commit; the unrelated local preview's PDB receipt must not be substituted for that provenance.

Routes 9c45a6df12da901a64e31ad6580b0e8911b7281d preserves page state through same-URI authentication refresh and fragment navigation. That is a separate fix: it does not change positional control dispatch. The coupon correction changes form state and submission, not cover action identities.

After a coherent Routes/coupon/Store release, acceptance must include a fresh context on an already-installed cover: click its first enabled Get or Repair before Resume has settled, without a sleep, retry, or prerequisite wait for Resume. Require the real appropriate dialog from that single click, retaining the clicked area, owner dispatch/control identity and circuit state if it fails. A stable cover and the ordinary install/reset/idempotence journey remain controls. This local proof does not claim browser or production acceptance has completed.

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