Repository navigation
fix(php-transformer): recognize the current capture disclosure and gallery runtimes - #2729
Merged
Merged
Conversation
…llery runtimes Publish the producer's current runtime bodies as the recognized ones: disclosure b545f43a (ancestor class bindings replayed as tokens) and gallery 456af763 (src-swap sequence mode). One body per runtime; earlier bodies are no longer recognized and keep their captured runtime. The native replacements already do what the new bodies add: the native dialog replays class bindings as token sets, and src-swap galleries become native src-swap carousels. A Chromium parity test compares the recognized disclosure runtime with the native dialog on re-ordered, token-only and empty-class ancestor bindings. The equivalence gate neutralizes the engine_version release stamp and its expectations are regenerated from the pre-move commit with the current digests. Three corpus cases change: they carry the previous disclosure body, which now keeps its captured runtime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs Automattic/data-liberation-agent#787 (follow-up). Follows #2725.
Summary
Blocks Engine recognized the producer's disclosure and gallery runtime bodies from before Data Liberation Agent v0.27.0. The producer's current bodies differ, so its pages kept their captured runtimes. This PR publishes the current bodies as the recognized ones. Each runtime has one recognized body. An earlier body is no longer recognized, and a page that carries it keeps its captured runtime.
3d350f55…b545f43a77b79d075373048431101fe11d7ff8cdfe7987de6d7971512763d88f0a6bf62a…456af76323601e51d851d3a4d6fe4ff6e3989c9969562f425fd72103c5c57c6bI took the bodies from DLA
origin/main(DISCLOSURE_RUNTIMEinsrc/lib/static-dialogs.ts,RUNTIMEinsrc/lib/static-galleries.ts). The template literals were evaluated as emitted, andsha256(trim(body))matches the producer'sCAPTURE_RUNTIME_SHA256.Semantic check: what changed in each body, and whether the native replacement does it
Disclosure. The only change from the previous body is the
classbranch of ancestor replay. The old body setclassto the recorded string as a whole. The new body works on tokens:classTokens()removes the other state's tokens that the target state lacks, adds the target state's tokens, and keeps every other class. It also removes an emptiedclassattribute.CapturedDialogBlockGenerator,replay()) already does exactly this token replay. It finds the ancestor by tag plus closed tokens, which is what Promote Static Site Importer architecture fixture to solved corpus #779's identifying tokens are recorded for.classTokensOnlyrows need nothing extra: they are tag/closed/opened rows that the token replay handles.class=""behind.canReplaceScopedDisclosurerequires dropdowns. Unscoped modals are projected from interaction states, and the native dialog replays their ancestor class bindings.capture-runtime-ancestor-parity-browser.mjsdrives the producer runtime and the native dialog with the same clicks (initial, open, close, reopen, Escape). It compares every recorded token and every authored token on each ancestor, covering re-ordered theme classes, token-only rows and an empty closed class onbody. It passes with the current body. It fails with the previous body, whose whole-attribute replacement wipes unrecorded classes.Gallery. The only change is the src-swap branch. When
…-gallery-sequenceis present, slotiwith offsetogetssequence[(index+o) mod n]and loses itssrcset. Direction controls wrap. Frame mode is byte-for-byte unchanged.AuthoredCarouselBlockGenerator,syncSrcSwap) builds its slides in sequence order and starts at index 0. It wraps, uses the same slot formula, removessrcset, and strips the direction markers, so the runtime it replaces has nothing left to bind.syncSrcSwapover 14 clicks in both directions on the converted slide order, and the slotsrc/srcsetmatched at every step. It is not committed because the native carousel runs on the Interactivity API and needs WordPress. The committed tests cover the conversion shape, the wrap and initial index, and the stripped controls.Both bodies are therefore recognized.
Changes
CaptureEvidence::DISCLOSURE_RUNTIME_SHA256/GALLERY_RUNTIME_SHA256and the two fixtures are replaced, not extended.docs/contracts/capture-evidence.mdgets the new digests, the one-body-per-runtime rule and what each native replacement reproduces.tests/unit/capture-runtime-ancestor-parity.php. A scoped dropdown carrying the current body is retired with a proof whosebody_hashis the published digest, and every ancestor class binding reaches the native dialog. A body with one byte changed keeps its runtime and gets no native dialog.capture-runtime-ancestor-parity-browser.mjs, which is the Chromium parity check above. It is added to the visual-parity job.captured-gallery-contract.php: the coexistence page now carries both current bodies, and both are replaced natively with the published digests. A gallery body with one byte changed keeps the disclosure runtime.authored-carousel-block.php: the src-swap case carries the published gallery body and asserts that the native carousel owns the controls.scoped-mixed-dropdown.phpalready loads the fixture, so it now exercises the current body.Equivalence gate
The expectations were regenerated with the documented procedure:
rename-checkout.phpthenbaseline.phpon a disposable checkout of the pre-move commit44a1eb5e, with the swap now pointing at the current digests. Two things changed, and both are deliberate:engine_versionis neutralized. It is a release stamp, like the*_duration_mstimings. Thev0.38.2release commit changed it after refactor: neutral capture vocabulary for Blocks Engine capture evidence #2725, and the release commit did not run this workflow. Trunk now fails the gate on 68 compile cases. I diffed one of them, and the release stamp was its only difference. With the stamp neutralized, the regenerated pre-move expectations match this branch on all 349 cases. Before neutralizing, the regenerated digests matched the committed CI expectations on 346 of 349 cases, so the pre-move outputs are the same across platforms.ArtifactCompiler::compilecases (17d97f2c,2df01069,52210e3a) carry the previous disclosure body. That body is no longer recognized. Their scoped dropdowns now keep the captured runtime (runtime_dom_contract_preserved) instead of becoming native dialogs. This is the "unknown body keeps the runtime" contract, and the pre-move source with the current digests gives the same output.Known gaps (not new, apply to the previous body too)
These stay out of this PR because each changes gate outputs. Proposed follow-ups:
aria-*/data-*ancestor bindings are dropped natively. The producer recordsclass|style|hidden|aria-*|data-*.CapturedDialogProjector::triggerAncestorState()keeps rows that only useclass/style/hidden, so Promote Static Site Importer architecture fixture to solved corpus #779's header row{class, data-section-theme}loses both changes, while the runtime replays them.<button>trigger becomescore/details.DetailsPattern::matchDisclosureconverts the trigger and its projected in-place dropdown panel tocore/detailsafter the runtime is retired, which drops the ancestor bindings. An icon-only trigger stays a native dialog. The new parity fixture with a text trigger reproduces this.native_navigation_submenu_replaces_capture_disclosure) without comparing the body. I observed this with a one-byte-altered body.native_carousel_and_dialog_replace_capture_gallery). On a page that mixes a frame gallery and a src-swap gallery, the src-swap gallery then depends on its native carousel conversion.Verification (local, macOS, PHP 8.5)
composer install,composer validate --strict,composer lint,composer test:lint: pass.composer test: pass. The gate reports349/349, and the new parity, gallery-contract, scoped-mixed-dropdown and carousel tests pass.php tests/contract/production-acceptance-matrix.php: pass.npm ci,npm run lintandnpm testpass, as dolayout-media-tracks(default and responsive, WordPress 7.0.4), every browser step in the job, and the new ancestor parity step.AI disclosure: written by Claude in OpenCode with Chris Huber (direct implementation authorized by the operator); Claude implemented, tested and opened this PR.