test(light): preserve empty render contract and guard late static imports

Follow the render-local barrier wrapper without weakening empty-space or
confirmation assertions. Register the cold-import connection guard mutation.

Issue: #789
User-Visible: no
This commit is contained in:
Matysh
2026-10-04 07:17:00 +03:00
parent 7777b8a0a8
commit d8949cfffc
3 changed files with 19 additions and 3 deletions
@@ -17,8 +17,8 @@ to prove that the Node witness actually kills it.
| Paint, cascade and layer composition | 37 | The invariant depends on computed CSS, SVG paint, clipping, stacking or pixels produced by Chromium. |
| Pointer geometry and trusted interaction | 47 | The invariant depends on hit testing, pointer capture, touch/keyboard dispatch or live DOM geometry. |
| Responsive DOM layout | 38 | The invariant depends on measured element boxes, responsive breakpoints, native/HA dialog shells or focusable target size. |
| Custom-element and HA browser lifecycle | 103 | The invariant crosses Lit/custom-element lifecycle, browser storage/events, lazy loading or a complete HA-card state transition. |
| **Total** | **233 / 200** | Above the guideline `mutation-gate --check` warns rather than fails (#699); each guard above it is held by its own reason in this inventory and its `because`. |
| Custom-element and HA browser lifecycle | 104 | The invariant crosses Lit/custom-element lifecycle, browser storage/events, lazy loading or a complete HA-card state transition. |
| **Total** | **234 / 200** | Above the guideline `mutation-gate --check` warns rather than fails (#699); each guard above it is held by its own reason in this inventory and its `because`. |
## Measured effect
@@ -253,6 +253,7 @@ The invariant crosses Lit/custom-element lifecycle, browser storage/events, lazy
- `french-locale-wrong-dictionary`
- `glow-barrier-render-pass-wiring-skipped`
- `glow-static-led-release-skipped`
- `glow-static-ready-after-disconnect`
- `household-enter-stops-acting`
- `household-marker-drops-keyboard-reach`
- `hp-dialog-escape-does-not-close`
+11
View File
@@ -14267,6 +14267,17 @@ const MUTANT_DEFINITIONS = [
replace: ' // mutant: render the new source fully visible before its entry frame',
}],
},
{
id: 'glow-static-ready-after-disconnect',
guard: 'node demo/smoke_led_strip_glow.mjs',
because: '#789 AC4: a real lazy runtime or field import completing after the static custom element '
+ 'disconnects must not request a late update; the browser smoke holds its network response across removal',
patches: [{
file: 'src/space-render.ts',
find: ' const ledConnected = o.glowRuntime?.host.isConnected ?? (() => false);',
replace: ' const ledConnected = () => true;',
}],
},
{
id: 'glow-static-led-release-skipped',
guard: 'node demo/smoke_led_strip_glow.mjs',
+5 -1
View File
@@ -76,7 +76,11 @@ test('empty render keeps create/import affordances without spatial layers', () =
// Обёртка: настоящий `nothing` пробрасывается как есть. `noChange` вложен в
// стабильный shell: так тело остаётся, а соседний confirm можно убрать.
const wrapper = methodBody('render');
// #789: внешний render ограничивает кэш барьеров одним проходом; контракт
// пустого тела и подтверждения остаётся во внутренней обёртке.
assert.match(methodBody('render'),
/return this\._lightBarrierPass\.run\(\(\) => this\._renderLightPass\(\)\);/);
const wrapper = methodBody('_renderLightPass');
assert.match(wrapper, /const body = this\._renderBody\(\);/);
assert.match(wrapper, /if \(body === nothing\) return body;/);
assert.match(wrapper, /return this\._renderRoot\(body\);/);