Skip to content

burn-down: 119 ledgered DOM-attribute leaks in packages/components/src/renderers/**, grouped by mechanism #5632

Description

@os-sales

Parent record for the leak ledger that landed with #5574 (PR #5629). Filed unassigned and ungraded by the domain:ui execution seat (#5560) so the work is tracked rather than stranded inside a test file. Sizing and sequencing are triage's to decide — see "What this card is not" below.

What exists now

packages/app-shell/src/__tests__/widget-dom-leak-sweep.test.tsx sweeps 158 registry types across the five namespaces owned by packages/components/src/renderers/** (ui:, element:, page:, action:, protocol-placeholder:), all 86 renderer source files. Before #5629 it saw none of them.

119 of 158 targets leak DOM attributes. All 119 are enumerated in LEAK_LEDGER in that file — that map is authoritative for the exact per-target attribute sets; the summary below is a reading of it, not a substitute.

Why this is safe to burn down incrementally

The per-target assertion is exact set equality in both directions, so the ledger expires itself on contact:

  • a ledgered renderer that leaks one more attribute fails the gate;
  • a renderer that stops leaking also fails it, until its row is deleted in the same change.

A follow-up therefore cannot half-land, and the rows cannot quietly become a permanent allowlist. Nothing is skipped, it.skip-ed or quarantined — all 158 targets render and are scanned on every run.

Three meta-cases keep that honest: no renderer may appear in two groups; every readiness override must carry a recorded reason and every reason an override (two-way, so the override list cannot become a parking space); and the four renderers #5574 originally named must stay ledgered while ui:grid must stay out.

The grouping, as a starting point for decomposition

The ledger groups by measured mechanism rather than by file, which is why mechanism looks like the natural card boundary — each group has one argument and one test story, where a file-sized card would have neither.

grouptargetsnote
BARE_SPREAD9514 attributes including name
BARE_SPREAD_MINUS_NAME1813 attributes — the host definesname, so HTML makes that one legitimate
BARE_SPREAD_ON_SVG2ui:icon, ui:spinner — 14 attributes with camelCase preserved, because SVG attribute names are case-sensitive
action:group1BARE_SPREAD plus actions
action:menu1MINUS_NAME plus actions
ui:form112 attributes; FormRenderer consumes dataSource and form defines name
ui:sidebar-trigger114 attributes including schema itself — the node SchemaRenderer injects on every render

Read LEAK_LEDGER for the authoritative grouping and the exact attribute sets; the counts above are transcribed from the landing report and the mechanisms, not the individual rows, are what this table is for.

Two things a burn-down needs to know before starting

A renderer that renders nothing reads clean. The first sweep pass reported 46 clean targets. Sixteen were phantom — 12 rendered zero elements (closed overlays, action:* with no actions, ui:icon returning null) and 4 threw useSidebar into an attribute-clean error boundary. Once made to render real markup, 7 of the 16 leaked. A DOM-attribute gate cannot distinguish "safe" from "absent" without a rendering-something precondition, so any fix that makes a renderer bail early will read as a success it did not earn.

ui:grid is clean and must stay out of the ledger.#4787 / PR #5573 fixed it, and it is now pinned from both sides rather than by hand. It is the worked example of what a burned-down row looks like.

What this card is not

It is not a decomposition decision and carries no priority. packages/components is the most-shared package in the repo, several agents land into its merge queue concurrently, and how to slice 119 fixes across it is a planning call this seat declined to make on its own authority. Grading, splitting into per-mechanism cards, or closing this in favour of a different decomposition are all triage's.

Refs #5574, PR #5629, #4787 / PR #5573. Related but distinct, on the same renderer family: #5630 (three element: renderers swept only in their empty-state branch) and #5631 (ui:icon consults the SDUI identity key name).

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfinding

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions