Repository navigation
Complete selector matching, specificity, and dependency invalidation coverage #237
Description
Activity
- addedvscode-oss/plannedPlanned for the AppScene/WebScene VS Code OSS integrationPlanned for the AppScene/WebScene VS Code OSS integration
on Sep 17, 2026 Coordination: PR #245 is the existing structural-invalidation implementation under this issue, continuing merged #148 and integrating #234. Head ba468ff covers compiled child-list routes, structural DOM/style checkpoints and directly related scaling/regressions (40/40 WebScene/Chrome; 44-case native matrix). Please consume or coordinate with this implementation instead of creating a second structural invalidation path. Its remaining lane is disconnected/remaining DOM checkpoints, positional sibling-scan costs and unrelated structural-rule scaling. This does not claim ownership or completion of the broader specificity/matching inventory, CSSOM #239, cascade #238, layout #240, responsive #242, or VS Code profiling #243. #235 now records the boundary and evidence.
Installed SDK gate: compiled attribute mutation is not restyled
The exact macOS ARM64 SDK consumer gate reproduces a remaining attribute-invalidation gap on clean main sources:
- AppScene
9f434e0deea632fe28962ce32e2f4ddede4aa14c - WebScene
b81f594cfe0effe742942b8ccf643c2e1f42bc6a - SDK
0.1.0-preview.3, Homebrew LLVM 22.1.8, Node 24.18.1/npm 11.16.0 - WebScene draft Optimize structural CSS invalidation and DOM mutation checkpoints #245 is deliberately excluded.
The installed Kestrel parity consumer creates independent parsed and compiled engines. Both initially agree in dark mode. It then executes:
kestrel.theme = "light"; kestrel.applyTheme();
Both engines report:
kestrel.theme == "light" document.documentElement.dataset.theme == "light" document.documentElement.matches('[data-theme="light"]') == trueThe parsed engine updates
#ribbonto light computed styles:background rgb(243, 246, 249); color rgb(35, 55, 74)The compiled engine retains the original dark computed styles:
background rgb(33, 44, 58); color rgb(220, 228, 237)A subsequent root class mutation does not refresh the compiled result. This causes the installed
hybrid_kestrel_parity.pythird snapshot (1440x900, light, Drafting) to fail while parsed/compiled node counts and geometry still agree.All preceding installed qualifier gates pass: manifest verification; producer source denial; independent hybrid builds; all installed samples; runtime HTML/WebScene contracts; native dependency isolation; incremental CSS/worker/asset/C++ rebuilds; read-only relocated SDK integrity; actual presentation, lifecycle, callback cancellation, and GPU retirement. A repeat with Node 24 removes the earlier npm engine warning but produces the same style mismatch, so Node is not causal.
This fits #237's existing attribute-mutation acceptance scope. It is separate from #245's currently documented structural child-list lane; no draft code was included or modified for this SDK build.
- AppScene
P0 release gate dependency: draft #245 resolves exact installed parity repro
Read-only validation against the current draft #245 head confirms this release blocker is already fixed by that implementation, so no duplicate invalidation patch should be created.
Exact inputs:
- AppScene
9f434e0deea632fe28962ce32e2f4ddede4aa14c - WebScene PR Optimize structural CSS invalidation and DOM mutation checkpoints #245
05aa8f12466bebd8e10ceb7c10915f1f61f2110f(clean detached source) - macOS ARM64 SDK producer/runtime profile passed; 2,859-file manifest verified after the consumer run with zero missing or mismatched files
- SDK was recursively read-only during the independent Kestrel compiled/parsed consumer build and headless execution
- LLVM 22.1.8 and Node 24.18.1
Reduced result:
initial parsed/compiled: data-theme=dark; #ribbon background rgb(33, 44, 58), color rgb(220, 228, 237) after dataset mutation parsed/compiled: data-theme=light; matches([data-theme=light])=true; #ribbon background rgb(243, 246, 249), color rgb(35, 55, 74) after unrelated root class mutation: both engines remain identical and lightThe same probe fails on clean WebScene main
b81f594c: the compiled engine reportsdata-theme=lightand selector matching succeeds, but its computed style remains dark. Draft #245 therefore supplies the missing compiled attribute/style checkpoint needed by the exact AppScene SDK qualification gate.Dependency: the macOS ARM64 SDK release qualification for #237 must be rerun from WebScene main after #245 is ready and merged. #237 remains open for its broader selector/specificity matrix; this P0 installed-theme blocker should be considered owned by #245.
Evidence SHA-256:
- PR Optimize structural CSS invalidation and DOM mutation checkpoints #245 SDK archive:
7d432806687e5c6546623cd9f2a30f8e7772af36a43a3c1b869796e94254613a - reduced diagnostic output:
e0f126a5371d1a8f85dbbc2b2d9265f14a0a2fce64c3dbef1453f83c228387a7
- AppScene
Coordination: #245 is now pushed at 14ca683, with main b81f594 integrated via bc16392. The generated-binding conflict was resolved by regeneration from the merged manifest, retaining HTMLAnchorElement and corrected character-data setters. Cumulative local production/certification validation passes 140 route cases, four stable-text cases, twelve native child-vector cases, 410 related WPT checks, ten focused native groups and parser/generated-binding checks. The new work only bounds safe sibling-vector removal; it does not implement #257 form-state behavior. The exact installed Kestrel parsed/compiled theme probe is still verified only for 05aa8f1 and should be rerun against this cumulative head; no claim of current-head installed qualification or remote CI is made.
Follow-up: WebScene 6da8c56 + AppScene 3b00e895 passes the normal packaged producer, all 16 native AppScene tests, relocated read-only/source-denied consumer qualification, and installed Kestrel smoke plus existing three-snapshot parsed/compiled parity (376/298/311 nodes, zero differences). Optional GPU presentation suite not run. Correct integration uses AppScene #84’s existing codec-enabled renderer/Skia lock; no hash validation weakened. Native Spotify now shows album art/circular artists, but its header remains clipped. Engine source is unchanged by documentation head 33c174c. The user reports excellent ordinary resize with a narrow→wide breakpoint pause; I am profiling that specific transition under #242, not duplicating other CSS lanes. Details: https://github.com/SceneTech/WebScene/blob/33c174c8/docs/validation/spotify-messageport-startup-20260917.md
CharacterData editing checkpoints — 4f9c3ba
Pushed #245 at
4f9c3ba3. This completes the five CharacterData editing/query methods and UTF-16 length exposure in the existing #237 structural-checkpoint lane.appendData,insertData,deleteData,replaceData, andsubstringDatashare the text-setter checkpoint, preserving conversion order/errors, reentrant reparenting/data changes, lone surrogates, node identity, empty/relational selectors, connected stylesheet text and textarea default/dirty values. Stable nonempty edits avoid structural CSS work without suppressing layout.The initial contract passed Chrome and failed native 0/20 before implementation; the final expanded contract passes 23/23 in each engine, plus the existing setter contract 47/47 in each (70/70 combined). Native adjacent verification totals 329 subtests across ten documents, including a passing pseudo-layout reftest. Cumulative scaling passes 172 route cases; all 32 new method-transition cases retain identical eight-counter results as unrelated nodes/rules grow 32→1,024. Eight stable-text cases pass, with up to 102,400 nonempty method edits and zero work across all eight CSS counters. These are deterministic CSS-work assertions, not a wall-clock or Spotify-presentation speedup.
Default generated bindings (24 interfaces/191 members), certification and production builds, and five adjacent runtime groups pass. An optional legacy syntax check fails at generated-only
attr_template/node_templatereferences in unchanged files; legacy build/runtime qualification is not claimed. Existing detached-GC tests passing does not resolve the separate #258 retained-subtree oracle failure.No changes to other agents' #257/#286 implementations, no new SDK/manual app replacement, and no CI monitoring. The open demo remains the media-index qualified package. Remaining
splitText/normalize, complete Range/MutationObserver semantics, #258 owner reconciliation, cascade/layout dependencies and physical/native/Chrome resize acceptance keep the full CSS goal open.Implementation boundaries, checks and exact machine-readable evidence.
Text topology follow-up — PR #292 at
7a8fffb9The structural checkpoint lane now includes browser-compatible
Text.splitText()andNode.normalize(). The parent concatenated text and element-child structure are invariant, so this path dirties layout/paint but deliberately performs no selector invalidation or cascade.The new contract failed native 0/6 before implementation and passes 6/6 Chrome and native after it; adjacent CharacterData remains 70/70. A four-case native gate varies 8/128 affected parents independently of 32/1,024 unrelated nodes/rules and runs 100 split/normalize cycles per parent. All nine selector/cascade/positional/detached-root counter deltas are zero.
The gate also exposed quadratic detached-leaf registration: 12,800 pairs initially took about 307–308 ms because each removed suffix scanned historical roots. An indexed leaf path reduces the same local diagnostic to 23.6–28.7 ms with zero containment comparisons. This timing identifies the algorithmic fix; it is not a cross-machine release benchmark.
Generated bindings, detached-DOM GC, certification and production runtime builds pass. Range boundary adjustment and MutationObserver delivery remain outside this tranche. The original #258 oracle still requires owner requalification. IndexedDB and the independently owned #246/#256/#257/#286 work are unchanged. CI was not monitored.
Evidence: https://github.com/SceneTech/WebScene/blob/7a8fffb9/docs/validation/css-text-topology-20260917.md
Ownership boundary for the next focused slice from exact main
dbdf02c75fa8efcab2eaa145106b985c95feba48:Audit found a product-neutral nested functional-selector gap. Servo parsing and specificity metadata already accept nested
:is()/:where()/:not(), but the native matcher divides each argument with a rawfind(','). A comma inside a nested function is therefore mistaken for an outer-list separator. The bounded fix will reuse the existing depth-aware CSS component-list splitter for functional selector arguments, then add Chromium/native computed-style and mutation coverage plus native invalidation-count, lifecycle, heap/RSS, and timing gates.Planned paths:
webscene_v8_runtime_css_parsing.inc, a dedicated WebPlatformSubset contract/profile entry, and a focused native test source/registration as needed. This has zero changed-path overlap with open #348 (grid/layout), #350 (input/tasks/surfaces), draft #76, and active #248/#270. It will not alter structural child-list routing from merged #245 or cascade behavior from closed #238.Merged focused nested functional selector-list slice via #356 at
615c10bc9dde326a66de730c9d6e8c63576fcf54(exact PR head8d1d715e450db8a00967f17baf17dacdf5c87694, rebased one3fb0ee20430f7d49350298056a6f1b4b13d1ac6). Chromium 153 passed 5/5; native before the fix passed 4/5 and retained styles after the nested[hidden]dependency changed; native after passed 5/5. Exact-head portable V8 and native Linux document contracts passed. The 128-node/1,000-transition gate held identical targeted counters at 32 and 1,024 unrelated rules/nodes (4,000 plan lookups, 256,000 candidate visits, zero fallback visits, 384,000 rule checks, 129,000 cascade applications), completed in 434.131 ms / 687.716 ms, kept heap flat in each run, and returned detach/low-memory/final lifecycle metrics to baseline. This closes only the nested:is()/:where()/:not()list-tokenization gap; #237 remains open for the remaining selector/invalidation matrix.Coordination for #81 follow-up: I am reducing a query-bearing same-origin iframe document-fetch -> nested Worker -> transferred MessagePort failure from main
eb3cfe38. This lane will not touch selector parsing/matching, specificity, invalidation, CSS state, or #237 tests. Planned files are iframe/Worker resource tests, a dedicated WebPlatformSubset contract/profile, and only generic iframe hydration runtime code if required. Please flag any new overlap before merge.Nested
:has()selector-list matching — merged #420PR #420 merged to
mainat19ad3eb229d6c93240f9898c44c70df5cc97ce0bfrom exact tested head4f2b45094fe78ed333ce2703710c6cb961472aec, rebased oneb3cfe38after #418.This closes the smallest residual functional-list gap after #356: unchanged Code OSS
645f29ccuses.monaco-list-row:has(.monaco-icon-label:is(.monaco-decoration-itemColor, .monaco-decoration-badge)), while native still split:has()on every comma. Matching now reuses the existing allocation-free depth-aware list traversal. Parser/specificity and #148/#245 compiled invalidation routes were already correct and remain unchanged.Evidence:
- Chrome 153.0.8010.50: 6/6.
- Native exact Match nested functional selector lists #356 head
8d1d715e: 1/6; candidate: 6/6. - Adjacent native contracts: 5/5 nested functional, 10/10 routed nested selector, 19/19 attribute invalidation, 73/73 child-list.
- Exact-head hosted gates passed: portable V8 run
35364489926, Linux build/test job in35364490038, and native Linux document/compiler run35364489831including the independent native-only SDK. - The 128-node/1,000-transition gate has identical counters at 32 and 1,024 unrelated rules/nodes: 6,000 plan lookups, 518,000 candidates, zero fallbacks, 37,664,000 compound checks, 1,024,000 rule checks, 258,000 cascades, 1,024,000 candidate checks. Isolated runtime is 1,539.88/1,777.78 ms; V8 heap returns byte-exactly after detach/low-memory and RSS remains inside +64 MiB.
Detailed retained evidence: https://github.com/SceneTech/WebScene/blob/19ad3eb229d6c93240f9898c44c70df5cc97ce0b/docs/validation/css-nested-has-selector-lists-20260918.md
#237 remains open. The next inventory must cover relative sibling
:has(+ ...)/:has(~ ...)matching and reverse invalidation (also present in unchanged Code OSS), remaining structural/state/specificity cases not yet browser/native proved, shadow selector boundaries, and cumulative exact-package acceptance. This merge does not close broader CSSOM/layout/paint/scheduling or product gates.Relative sibling
:has()— merged #426PR #426 merged to
mainatf034e70563934b401bf9e0c88d0f29c089366ae8from exact tested heada23325b5d23c4c8b8b72d2ca9bf6135c61b28a8a, rebased one523daa11ae3ac4d06a9cbba64561ec06bd271f3.This closes the next selector slice after #420. Unchanged Code OSS
645f29ccuses.monaco-list-row:has(+ .monaco-list-row.selected)andp:has(+ [data-code] > .chat-codeblock-pill-widget). Native now anchors relative arms at:scope, searches only their descendant or following-sibling region, and reuses the ordinary compiled selector matcher. Existingprevious_sibling/preceding_siblingsdependency routes handle class and attribute changes; a bounded surviving-child route covers final-sibling removal.Evidence:
- Chrome 153: 7/7.
- Native pre-fix control: 1/7; exact-head candidate: 7/7.
- Servo selector/parser and dependency-plan executable: pass.
- Adjacent nested-functional, attribute-invalidation, and structural-scaling filters: pass.
- Exact-head portable V8 passed in run
35367883880; unrelated hosted tails were canceled under the fast-merge policy. - The 128-group/1,000-transition gate has identical counters at 32 and 1,024 unrelated rules/nodes: 512,000 plan lookups, 9,664,000 candidate visits, zero fallbacks, 21,312,000 compound checks, 768,000 rule checks, 512,000 cascades, and 768,000 candidate checks. Runtime was 3,097.37/3,355.65 ms; settled V8 heap returned byte-exactly and native node/RSS bounds passed.
Detailed evidence: https://github.com/SceneTech/WebScene/blob/f034e70563934b401bf9e0c88d0f29c089366ae8/docs/validation/css-relative-sibling-has-20260918.md
#237 remains open for the remaining structural/state/specificity matrix, shadow selector boundaries, and cumulative exact-package acceptance.
Implemented and merged in PR #479 as
4d1a13e281fefa2e168c8506a6e4dd0769dc767c.The runtime now exposes pointer-driven
:activestate for the pressed target and its inclusive ancestor chain, maintains a dedicated dependency index separate from:hover, and recascades only affected subject/descendant/sibling/custom-property scopes. State becomes observable before down-event handlers and clears before up-event handlers while click targeting remains independent. Cascade switching, navigation, teardown, low-memory compaction, and memory accounting carry the new state/index.Per the implementation-throughput directive, native/browser/WPT, performance, memory, lifecycle, exact-package, and CI validation remain explicit debt before release promotion.
- added 6 commits that reference this issue
on Sep 19, 2026 Ownership: CSS Custom Highlight API
Focused child #740 now owns the next one-agent implementation lane from exact WebScene main
6ec61c77d08c11d99229877e840ed3b7fd144a41.The slice covers only the unchanged Code OSS chat-find and Markdown inner-diff paths: retained
Rangeboundary points,Highlight,CSS.highlights, functional::highlight(<custom-ident>)color/background paint, mutation-safe teardown, bounded work, and zero idle demand. It will not modify the merged structural invalidation routes, details-content implementation, form-state work, or broader Selection/Range editing APIs.
Current selector and invalidation checkpoint — 20 September 2026
Exact merged heads: WebScene
a46b62e14eb197603f7e227c1558afb9088633b0; AppScene97702daeb9ad71341ced7226f0aa966dc77ea53c; unchanged Code OSS645f29cc3176500b4b5762ba887cf2a7f0ffdf2c; local vscode-demoe4b98e5470cd7856aff3dfd6843c8e125d7db933(clean, intentionally unpushed). Open consolidations remain WebScene #76085bba760fa571c8f08ea866dc5dd1ec27c4d376, AppScene #65ce66ef6ceb776b3f14e129f853bfc08b5c5e608c, and vscode-demo #1; do not merge them. One-agent mode is active.Focused selector, structural mutation, pseudo-element, state, scoped selection/highlight, scrollbar state, placeholder/details and compiled-selector work recorded by this tracker is merged. The later pointer stack adds generated non-inherited touch-action without reopening selector ownership.
No focused selector branch is active. Continue source work only from a newly reduced current-main selector or invalidation defect. Authored WPT/native/performance and unchanged-product pixel/package gates remain deferred and are not claimed.
Parent tracker: #235
Problem
Dynamic applications depend on exact selector matching and invalidation across class/attribute/state changes. Existing coverage does not yet systematically prove specificity, structural/state pseudo classes, pseudo elements, combinators, ancestor dependencies, detached subtrees, and shadow-related boundaries.
Proposed work
:is(),:where(),:not(), and specificity edge cases.Acceptance