From d80665ff31ad65f825c208b64d5aab11809462c9 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Thu, 29 Oct 2026 14:54:02 -0400 Subject: [PATCH 1/4] Scope emitted core-selector CSS to importer classes (cook candidate, WIP) --- .../ArtifactCompiler/WordPressCompatCss.php | 3 + .../src/HtmlToBlocks/BlockFactory.php | 22 +- .../src/HtmlToBlocks/HtmlCompilation.php | 10 +- .../Session/TransformationEvidenceState.php | 30 + .../Style/AuthorSelectorSemanticPreparer.php | 53 + .../Style/AuthorStylesheetProjector.php | 30 +- .../Style/CoreSelectorScoping.php | 121 + .../HtmlToBlocks/Style/EngineSupportCss.php | 32 +- .../Style/GeneratedBlockStyleProjector.php | 2 +- .../Style/StylesheetAssetStage.php | 7 + .../fixtures/throw-classification.json | 3016 +++++++++++++---- php-transformer/tests/contract/run.php | 8 +- 12 files changed, 2718 insertions(+), 616 deletions(-) create mode 100644 php-transformer/src/HtmlToBlocks/Style/CoreSelectorScoping.php diff --git a/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php b/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php index 778d38c2c..2f7276fe8 100644 --- a/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php +++ b/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php @@ -4,6 +4,7 @@ namespace Automattic\BlocksEngine\PhpTransformer\ArtifactCompiler; use Automattic\BlocksEngine\PhpTransformer\Css\ClassAttributeSelectorProjection; +use Automattic\BlocksEngine\PhpTransformer\HtmlToBlocks\Style\CoreSelectorScoping; use Automattic\BlocksEngine\PhpTransformer\Support\EngineMarker; use Automattic\BlocksEngine\PhpTransformer\Css\CssStylesheetTransformer; @@ -119,6 +120,8 @@ public function asset(array $files, string $staticCss, array $scriptContents): ? return null; } + (new CoreSelectorScoping())->assertScoped($css, 'wordpress-compat'); + $hash = hash('sha256', $css); $path = 'assets/css/wordpress-compat-' . substr($hash, 0, 16) . '.css'; return array( diff --git a/php-transformer/src/HtmlToBlocks/BlockFactory.php b/php-transformer/src/HtmlToBlocks/BlockFactory.php index 8b8499ddc..ef206fbe4 100644 --- a/php-transformer/src/HtmlToBlocks/BlockFactory.php +++ b/php-transformer/src/HtmlToBlocks/BlockFactory.php @@ -297,7 +297,12 @@ private function blockHtml(string $name, array $attrs, array $innerBlocks): stri if ( 'core/code' === $name ) { // `content` is the escaped RichText value (see codeContent()); never // guess from its bytes, or code text that mentions a tag becomes one. - return 'blockSupportAttrs($attrs, 'wp-block-code') . '>' . (string) ($attrs['content'] ?? '') . ''; + // The engine class keys the code-shape support rule in + // EngineSupportCss so the selector does not stand on the bare core + // class alone. + $codeAttrs = $attrs; + $codeAttrs['className'] = SourceDom::mergeClassNames('blocks-engine-source-code', (string) ($attrs['className'] ?? '')); + return 'blockSupportAttrs($codeAttrs, 'wp-block-code') . '>' . (string) ($attrs['content'] ?? '') . ''; } if ( 'core/math' === $name ) { @@ -377,6 +382,10 @@ private function blockHtml(string $name, array $attrs, array $innerBlocks): stri } if ( 'core/accordion-panel' === $name ) { + // The importer class keys the `[hidden]` support rule in + // EngineSupportCss so it does not stand on the bare generated core + // class alone. + $attrs['className'] = SourceDom::mergeClassNames('blocks-engine-accordion-panel', (string) ($attrs['className'] ?? '')); return $this->roleWrapperHtml('region', $attrs, 'wp-block-accordion-panel'); } @@ -476,7 +485,10 @@ private function blockHtml(string $name, array $attrs, array $innerBlocks): stri $justificationClass = in_array($justification, array( 'left', 'center', 'right', 'space-between' ), true) ? 'is-content-justification-' . $justification : ''; $iconColorClass = '' !== trim((string) ($attrs['iconColorValue'] ?? '')) ? 'has-icon-color' : ''; $iconBackgroundClass = '' !== trim((string) ($attrs['iconBackgroundColorValue'] ?? '')) ? 'has-icon-background-color' : ''; - return array( 'opening' => 'blockSupportAttrs($attrs, trim('wp-block-social-links ' . $labelsClass . ' ' . $sizeClass . ' ' . $justificationClass . ' ' . $iconColorClass . ' ' . $iconBackgroundClass)) . '>', 'closing' => '' ); + // The importer class keys the social-links support rules in + // EngineSupportCss so they do not stand on the bare core list class + // alone; every social-links list the importer emits carries it. + return array( 'opening' => 'blockSupportAttrs($attrs, trim('wp-block-social-links blocks-engine-social-source-cluster ' . $labelsClass . ' ' . $sizeClass . ' ' . $justificationClass . ' ' . $iconColorClass . ' ' . $iconBackgroundClass)) . '>', 'closing' => '' ); } if ( 'core/social-link' === $name ) { @@ -806,6 +818,12 @@ private function imageHtml(array $attrs): string $img = 'htmlAttrs($imageAttrs, array( 'alt' )) . '/>'; if ( ! empty($attrs['href']) ) { + // The linked-image relay in EngineSupportCss replicates core's + // `:where(.wp-block-image)>a` geometry inheritance for this + // importer's markup. Keying it on this importer-emitted class + // instead of the bare core class keeps the rule off blocks a + // host adds to the served page later. + $figureAttrs['className'] = SourceDom::mergeClassNames((string) ($figureAttrs['className'] ?? ''), 'blocks-engine-linked-image-figure'); $linkAttrs = array( 'href' => (string) $attrs['href'], 'target' => (string) ($attrs['linkTarget'] ?? ''), diff --git a/php-transformer/src/HtmlToBlocks/HtmlCompilation.php b/php-transformer/src/HtmlToBlocks/HtmlCompilation.php index b71fe9934..b1a8928ee 100644 --- a/php-transformer/src/HtmlToBlocks/HtmlCompilation.php +++ b/php-transformer/src/HtmlToBlocks/HtmlCompilation.php @@ -1910,6 +1910,7 @@ public function transform(string $html, array $options = array()): TransformerRe 'responsive_geometry_ambiguities' => $this->transformationEvidence()->responsiveGeometryAmbiguities(), 'responsive_height_ambiguities' => $this->transformationEvidence()->responsiveHeightAmbiguities(), 'grid_placement_carrier_findings' => $this->transformationEvidence()->gridPlacementCarrierFindings(), + 'unscoped_core_selector_drops' => $this->transformationEvidence()->unscopedCoreSelectorDrops(), 'has_description_list_block' => $this->generatedBlocks()->has(DescriptionListBlockGenerator::class), ), $blockCompilationOutput); } @@ -11904,8 +11905,13 @@ private function imagePresentationAttributes(DOMElement $image, ?DOMElement $fig // Separate source boxes must keep separate selector ownership. Only // inert identities retain the historical class transport. $styledLeaf = $this->imageNeedsSeparateFigureBox($image, $figure); - $marker = $styledLeaf ? $this->session->authorSelectorProjectionState()->ensureImageWrapperMarker($image->getNodePath() ?? '') : ''; - $attrs['className'] = $this->mergeClassNames((string) ($attrs['className'] ?? ''), $this->nonCoreImageFigureClassName($figure), $styledLeaf ? $marker : $this->nonCoreImageClassName($image), ...$this->authorSemanticMarkersForElement($image)); + // A marker allocated by author-selector discovery (an image named + // by a selector with no class of its own) must reach the markup so + // the projection's bridge arms stay bound. + $marker = $styledLeaf + ? $this->session->authorSelectorProjectionState()->ensureImageWrapperMarker($image->getNodePath() ?? '') + : $this->session->authorSelectorProjectionState()->imageWrapperMarker($image->getNodePath() ?? ''); + $attrs['className'] = $this->mergeClassNames((string) ($attrs['className'] ?? ''), $this->nonCoreImageFigureClassName($figure), '' !== $marker ? $marker : $this->nonCoreImageClassName($image), ...$this->authorSemanticMarkersForElement($image)); } else { $attrs['className'] = $this->styleResolver->mergePresentationClassNames((string) ($attrs['className'] ?? ''), $this->styleResolver->injectedFigureHeightClassName($image)); } diff --git a/php-transformer/src/HtmlToBlocks/Session/TransformationEvidenceState.php b/php-transformer/src/HtmlToBlocks/Session/TransformationEvidenceState.php index bae141456..83ecf324c 100644 --- a/php-transformer/src/HtmlToBlocks/Session/TransformationEvidenceState.php +++ b/php-transformer/src/HtmlToBlocks/Session/TransformationEvidenceState.php @@ -35,6 +35,12 @@ final class TransformationEvidenceState /** @var array */ private array $gridPlacementCarrierFindings = array(); + /** @var list */ + private array $unscopedCoreSelectorDrops = array(); + + /** @var array */ + private array $unscopedCoreSelectorDropKeys = array(); + public function recordFormControlEcho(string $text): void { $text = trim($text); @@ -55,6 +61,30 @@ public function recordFrozenHiddenState(array $finding): void $this->frozenHiddenStateFindings[] = $finding; } + /** + * Records an author-selector projection arm dropped because it targeted a + * core block class with no importer-emitted class anywhere in its chain + * and no owner class was available to scope it with. + * + * @param string $selector The authored selector whose arm was dropped. + * @param string $reason Stable machine reason for the drop. + */ + public function recordUnscopedCoreSelectorDrop(string $selector, string $reason): void + { + $key = $reason . "\0" . $selector; + if ( isset($this->unscopedCoreSelectorDropKeys[$key]) ) { + return; + } + $this->unscopedCoreSelectorDropKeys[$key] = true; + $this->unscopedCoreSelectorDrops[] = array('selector' => $selector, 'reason' => $reason); + } + + /** @return list */ + public function unscopedCoreSelectorDrops(): array + { + return $this->unscopedCoreSelectorDrops; + } + /** @return list> */ public function frozenHiddenStateFindings(): array { diff --git a/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php b/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php index f6de3c04f..e002df53b 100644 --- a/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php +++ b/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php @@ -77,6 +77,7 @@ public function prepare( $projections->ensureTagMarker($tagName); } $this->discoverAuthorControlPaths($authorSelectors, $authorStyles, $projections); + $this->discoverAuthorImageIdentityPaths($authorSelectors, $authorStyles, $projections); $applicableAuthorStyleRules = array(); foreach ( $authorStyleRules as $rule ) { $rule['selectors'] = array_values(array_filter( @@ -183,6 +184,58 @@ private function discoverAuthorControlPaths(array $authorSelectors, AuthorStyleA } } + /** @param list}> $authorSelectors */ + /** + * An author selector that names an image without any class of its own — + * by bare element type (`p img`, `figure img`, `img`), by an id, or via + * core block classes — projects onto the generated figure's core class. + * Its bridge arms key on the per-image wrapper marker, so allocate one + * for every matched image up front: the markup carries it on the + * generated figure and the projection scopes each arm with it instead of + * falling back to a selector that stands on the bare core class alone. + * + * Selectors that already name a non-core class keep the ancestor-scoped + * bridge, which is copied onto the emitted markup unchanged. + * + * @param list}> $authorSelectors + */ + private function discoverAuthorImageIdentityPaths(array $authorSelectors, AuthorStyleAnalysis $authorStyles, AuthorSelectorProjectionState $projections): void + { + foreach ( $authorSelectors as $authorSelector ) { + $parsed = $authorSelector['parsed']; + if ( ! $parsed['supported'] ) { + continue; + } + if ( self::selectorCarriesNonCoreClass($authorSelector['selector']) ) { + continue; + } + foreach ( $this->matchingSourceElements($authorStyles, $authorSelector['selector'], $parsed) as $element ) { + if ( 'img' !== strtolower($element->tagName) ) { + continue; + } + $path = $element->getNodePath() ?? ''; + if ( '' === $path ) { + continue; + } + $projections->ensureImageWrapperMarker($path); + } + } + } + + /** Whether any class token in the selector is outside core's block families. */ + private static function selectorCarriesNonCoreClass(string $selector): bool + { + if ( ! preg_match_all('/\\.((?:\\\\.|[^\x00-\x7f]|[^\s.#:>+~,\[\]()\'"\\\\])+)/', $selector, $matches) ) { + return false; + } + foreach ( $matches[1] as $class ) { + if ( ! preg_match('/^(?:wp-block-|has-)/', str_replace('\\', '', $class)) ) { + return true; + } + } + return false; + } + /** @param list}> $authorSelectors */ private function discoverAuthorInlineSemanticPaths(array $authorSelectors, AuthorStyleAnalysis $authorStyles, AuthorSelectorProjectionState $projections): void { diff --git a/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php b/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php index 050b3686f..649cf877c 100644 --- a/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php +++ b/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php @@ -1603,6 +1603,11 @@ private function projectImageFigureSubjectSelector(string $selector, array $pars } } + if ( ! (new CoreSelectorScoping())->selectorIsScoped($projected) ) { + $context->evidence->recordUnscopedCoreSelectorDrop($selector, 'no_importer_class_for_core_image_projection'); + return null; + } + return $projected; } @@ -2613,7 +2618,7 @@ private function projectAuthorImageSelectorPrelude(string $prelude, AuthorStyles // Only the existing fill/flex paths need a synthetic wrapper box. // Ordinary SVG presentation belongs on the replaced image itself. if ( 'svg' === $tagName && ($flexBox || $this->isProjectableFillSvg($imageMatches[0], $declarations)) ) { - $projected[] = $this->projectImageSelector($selector, $parsed, $context, true); + $this->pushScopedImageArm($projected, $selector, $this->projectImageSelector($selector, $parsed, $context, true), $context); } $mediaTextImages = array_values(array_filter( $imageMatches, @@ -2648,12 +2653,33 @@ private function projectAuthorImageSelectorPrelude(string $prelude, AuthorStyles $projected[] = NativeImageLeafPresentation::selectors(':where(.' . $marker . ').wp-block-image', $this->selectorSpecificityShims($parsed, $context) . $suffix); } if ( $hasUnmarkedImage ) { - $projected[] = $this->projectImageSelector($selector, $parsed, $context); + $this->pushScopedImageArm($projected, $selector, $this->projectImageSelector($selector, $parsed, $context), $context); } } return implode(',', array_values(array_unique($projected))); } + /** + * Emits a projected image-rule arm only when every core block class it + * names is reached through an importer-emitted class as well. An arm that + * would stand on the bare core class is dropped and recorded instead of + * leaking onto blocks a host adds to the served page later; discovery + * marks matched images so the scoped marker arm carries the rule instead. + * + * @param list $projected + */ + private function pushScopedImageArm(array &$projected, string $authoredSelector, string $arm, AuthorStylesheetProjectionContext $context): void + { + if ( '' === $arm ) { + return; + } + if ( ! (new CoreSelectorScoping())->selectorIsScoped($arm) ) { + $context->evidence->recordUnscopedCoreSelectorDrop($authoredSelector, 'no_importer_class_for_core_image_projection'); + return; + } + $projected[] = $arm; + } + private function projectMediaTextImagePrelude(string $prelude, AuthorStylesheetProjectionContext $context): string { $selectors = CssStylesheetTransformer::splitSelectorList($prelude); diff --git a/php-transformer/src/HtmlToBlocks/Style/CoreSelectorScoping.php b/php-transformer/src/HtmlToBlocks/Style/CoreSelectorScoping.php new file mode 100644 index 000000000..cdb6437d1 --- /dev/null +++ b/php-transformer/src/HtmlToBlocks/Style/CoreSelectorScoping.php @@ -0,0 +1,121 @@ ++~,\[\]()\'"])+)/'; + + /** + * @throws \RuntimeException When a rule targets a core block class without + * an importer-emitted class in the same compound or ancestor chain. + */ + public function assertScoped(string $css, string $origin): void + { + $violations = $this->violations($css); + if ( array() !== $violations ) { + throw new \RuntimeException(sprintf( + "Emitted CSS targets a core block class without an importer-emitted class in the selector chain (origin: %s):\n - %s", + $origin, + implode("\n - ", $violations) + )); + } + } + + /** @return list Unscoped selectors found in the stylesheet. */ + public function violations(string $css): array + { + $violations = array(); + ( new CssStylesheetTransformer() )->visitStyleRules($css, function (string $selector, string $body) use (&$violations): void { + foreach ( CssStylesheetTransformer::splitSelectorList($selector) as $single ) { + if ( ! $this->selectorIsScoped($single) ) { + $violations[] = $single; + } + } + }); + return array_values(array_unique($violations)); + } + + /** + * A selector is scoped when no core block class in it stands without an + * importer-emitted class anywhere in the same compound or ancestor chain. + */ + public function selectorIsScoped(string $selector): bool + { + $selectors = CssStylesheetTransformer::splitSelectorList($selector); + if ( null === $selectors ) { + return true; + } + foreach ( $selectors as $single ) { + $hasCoreClass = false; + $hasImporterClass = false; + foreach ( $this->classTokens($single) as $class ) { + if ( 1 === preg_match(self::CORE_CLASS_PATTERN, $class) ) { + $hasCoreClass = true; + } else { + $hasImporterClass = true; + } + } + if ( $hasCoreClass && ! $hasImporterClass ) { + return false; + } + } + return true; + } + + /** @return list */ + private function classTokens(string $selector): array + { + $classes = array(); + if ( ! preg_match_all(self::CLASS_TOKEN_PATTERN, $selector, $matches) ) { + return array(); + } + foreach ( $matches[1] as $class ) { + $class = str_replace('\\', '', $class); + if ( '' !== $class ) { + $classes[] = $class; + } + } + return $classes; + } +} diff --git a/php-transformer/src/HtmlToBlocks/Style/EngineSupportCss.php b/php-transformer/src/HtmlToBlocks/Style/EngineSupportCss.php index 86b94347e..232b28b9e 100644 --- a/php-transformer/src/HtmlToBlocks/Style/EngineSupportCss.php +++ b/php-transformer/src/HtmlToBlocks/Style/EngineSupportCss.php @@ -49,11 +49,11 @@ final class EngineSupportCss public function beforeAuthorCss(string $serializedBlocks): array { $parts = array(); - if ( str_contains($serializedBlocks, 'wp-block-accordion-panel') ) { + if ( str_contains($serializedBlocks, 'blocks-engine-accordion-panel') ) { // Core owns the panel's hidden state. Projected source display rules // describe its open box and must not expose padding or borders while // Core has concealed the panel. - $parts[] = ':root .wp-block-accordion-panel[hidden]{display:none!important}'; + $parts[] = ':root .blocks-engine-accordion-panel[hidden]{display:none!important}'; } if (str_contains($serializedBlocks, 'blocks-engine-social-source-row')) { $parts[] = ':root .blocks-engine-social-source-row{font-size:inherit;line-height:inherit}'; @@ -167,7 +167,7 @@ public function beforeAuthorCss(string $serializedBlocks): array // which carries none of them, so the bridge resolves to the initial // value and the source's crop is lost. Relay the figure's values // through the anchor so the bridge lands the same either way. - $parts[] = ':root :where(.wp-block-image)>a{object-fit:inherit;object-position:inherit;border-radius:inherit}'; + $parts[] = ':root :where(.blocks-engine-linked-image-figure)>a{object-fit:inherit;object-position:inherit;border-radius:inherit}'; } if ( str_contains($serializedBlocks, SourceBlockAttributeProjector::SYNTHETIC_INLINE_IMAGE_FIGURE_CLASS) ) { // This figure has no source box. Remove its layout box so image @@ -330,8 +330,10 @@ public function beforeAuthorCss(string $serializedBlocks): array // Core makes the inner code element a full-width break-spaces block. // Source pre/code is inline and inherits the preformatted whitespace // contract; restore that shape while authored code rules remain free - // to choose typography. - $parts[] = ':root :where(.wp-block-code)>code{display:inline;overflow-wrap:normal;text-align:inherit;white-space:inherit;direction:inherit}'; + // to choose typography. The rule keys on the importer class every + // emitted code block carries (BlockFactory), not the bare core + // class, so it cannot reach blocks a host adds later. + $parts[] = ':root :where(.blocks-engine-source-code)>code{display:inline;overflow-wrap:normal;text-align:inherit;white-space:inherit;direction:inherit}'; } if ( str_contains($serializedBlocks, SourceBlockAttributeProjector::SYNTHETIC_IMAGE_GAP_CLASS) ) { // A collapsing space, not an estimated em/ch margin: the browser @@ -480,20 +482,20 @@ public function socialLinkCss(string $serializedBlocks): array // core/social-links paints its own icon for every service. The source // cluster painted icon-font glyphs through pseudo-elements on the very // items core now owns, so both icons would render on each link. - $parts[] = ':root .wp-block-social-links .wp-social-link::before,' - . ':root .wp-block-social-links .wp-social-link:not(:where(.blocks-engine-social-source-item))::after,' - . ':root .wp-block-social-links .wp-social-link:not(:where(.blocks-engine-social-source-glyph))>a::before,' - . ':root .wp-block-social-links .wp-social-link>a::after{content:none}'; + $parts[] = ':root .wp-block-social-links.blocks-engine-social-source-cluster .wp-social-link::before,' + . ':root .wp-block-social-links.blocks-engine-social-source-cluster .wp-social-link:not(:where(.blocks-engine-social-source-item))::after,' + . ':root .wp-block-social-links.blocks-engine-social-source-cluster .wp-social-link:not(:where(.blocks-engine-social-source-glyph))>a::before,' + . ':root .wp-block-social-links.blocks-engine-social-source-cluster .wp-social-link>a::after{content:none}'; // The source cluster was an inline box, so its container's text // alignment placed it. core's list is a full-width flex row, which // packs the items at the start instead. An inline flex row resolves // through that same alignment, for centered and start-aligned // containers alike, while an explicit justification still wins. - $parts[] = ':root ul.wp-block-social-links:not([class*="is-content-justification-"]){display:inline-flex}'; - $parts[] = ':root ul.wp-block-social-links.is-content-justification-left{justify-content:flex-start}' - . ':root ul.wp-block-social-links.is-content-justification-center{justify-content:center}' - . ':root ul.wp-block-social-links.is-content-justification-right{justify-content:flex-end}' - . ':root ul.wp-block-social-links.is-content-justification-space-between{justify-content:space-between}'; + $parts[] = ':root ul.wp-block-social-links.blocks-engine-social-source-cluster:not([class*="is-content-justification-"]){display:inline-flex}'; + $parts[] = ':root ul.wp-block-social-links.blocks-engine-social-source-cluster.is-content-justification-left{justify-content:flex-start}' + . ':root ul.wp-block-social-links.blocks-engine-social-source-cluster.is-content-justification-center{justify-content:center}' + . ':root ul.wp-block-social-links.blocks-engine-social-source-cluster.is-content-justification-right{justify-content:flex-end}' + . ':root ul.wp-block-social-links.blocks-engine-social-source-cluster.is-content-justification-space-between{justify-content:space-between}'; } if (str_contains($serializedBlocks, 'blocks-engine-social-source-row')) { $parts[] = ':root ul.wp-block-social-links.blocks-engine-social-source-row,' @@ -641,7 +643,7 @@ public function secondaryBlockRenderRepairCss(string $serializedBlocks): array $parts[] = '.wp-block-navigation.blocks-engine-native-responsive-navigation.blocks-engine-inline-navigation{display:inline-flex!important}'; } if ( str_contains($serializedBlocks, 'wp:social-links') ) { - $parts[] = '.wp-block-social-links.is-style-logos-only .wp-social-link{background-image:none;background-color:transparent}'; + $parts[] = '.wp-block-social-links.blocks-engine-social-source-cluster.is-style-logos-only .wp-social-link{background-image:none;background-color:transparent}'; } if ( str_contains($serializedBlocks, 'blocks-engine-source-social-item-spacing') ) { $parts[] = '.wp-block-social-links.blocks-engine-source-social-item-spacing{gap:0}'; diff --git a/php-transformer/src/HtmlToBlocks/Style/GeneratedBlockStyleProjector.php b/php-transformer/src/HtmlToBlocks/Style/GeneratedBlockStyleProjector.php index c93fc81eb..280829c83 100644 --- a/php-transformer/src/HtmlToBlocks/Style/GeneratedBlockStyleProjector.php +++ b/php-transformer/src/HtmlToBlocks/Style/GeneratedBlockStyleProjector.php @@ -60,7 +60,7 @@ public function applyDeclaredBlockSupport( $attrs['className'] = SourceDom::mergeClassNames((string) ($attrs['className'] ?? ''), $className); $generatedStyles->registerNavigationSubmenuBackground($className, $submenuBackground); } - $classes = preg_split('/\s+/', trim((string) ($attrs['className'] ?? ''))) ?: array(); + $classes = preg_split('/\s+/', trim((string) ($attrs['className'] ?? '')), -1, PREG_SPLIT_NO_EMPTY) ?: array(); if ( 'core/navigation' === $name && is_array($fallback['spacing']['padding'] ?? null) ) { foreach ( $classes as $class ) { if ( 'blocks-engine-list-navigation' !== $class && ! str_starts_with($class, 'blocks-engine-') ) { diff --git a/php-transformer/src/HtmlToBlocks/Style/StylesheetAssetStage.php b/php-transformer/src/HtmlToBlocks/Style/StylesheetAssetStage.php index 67da90992..1769b5c91 100644 --- a/php-transformer/src/HtmlToBlocks/Style/StylesheetAssetStage.php +++ b/php-transformer/src/HtmlToBlocks/Style/StylesheetAssetStage.php @@ -47,6 +47,8 @@ public function generated(array $cssParts, string $source, string $placement, st return; } + (new CoreSelectorScoping())->assertScoped($css, 'generated:' . $placement); + $content = $css . "\n"; $hash = hash('sha256', $content); $path = 'assets/css/' . $pathPrefix . '-' . substr($hash, 0, 16) . '.css'; @@ -80,6 +82,11 @@ private function authorProjection(array $projection): void return; } + // Deliberately not invariant-checked: projected author stylesheets keep + // authored rules whose selectors matched source markup, and source + // pages legitimately style their own `wp-block-*`-shaped classes. The + // invariant governs compiler-authored CSS, which `generated()` covers. + $content = $css . "\n"; $hash = hash('sha256', $content); $this->session->assetMaterializationState()->register($path, array( diff --git a/php-transformer/tests/contract/fixtures/throw-classification.json b/php-transformer/tests/contract/fixtures/throw-classification.json index fe5dcc821..b37f75c10 100644 --- a/php-transformer/tests/contract/fixtures/throw-classification.json +++ b/php-transformer/tests/contract/fixtures/throw-classification.json @@ -4,658 +4,2494 @@ "representability_pending_max": 9, "sites": { "src/ArtifactCompiler/ArtifactCompiler.php": { - "InvalidArgumentException('Caller runtime declarations cannot provide compiler-reserved script supersession proofs.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('File compilation ownership requires a shared or page scope.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Page file compilation ownership requires a bounded nonblank page id.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Shared file compilation ownership cannot declare a page id.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Caller runtime declarations cannot provide compiler-reserved script supersession proofs.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('File compilation ownership requires a shared or page scope.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Page file compilation ownership requires a bounded nonblank page id.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Shared file compilation ownership cannot declare a page id.')": { + "class": "integrity", + "count": 1 + } }, "src/ArtifactCompiler/HtmlFragmentIncludes.php": { - "InvalidArgumentException('html_include_count_exceeded: '.$path)": {"class": "representability", "count": 3, "unit": "page", "finding": "html_include_budget_exceeded", "test": "tests/contract/html-include-page-local-limits.php"}, - "InvalidArgumentException('html_include_cycle: '.$path)": {"class": "integrity", "count": 1}, - "InvalidArgumentException('html_include_depth_exceeded: '.$path)": {"class": "operational", "count": 2}, - "InvalidArgumentException('html_include_duplicate_path: '.$duplicates[0])": {"class": "integrity", "count": 1}, - "InvalidArgumentException('html_include_file_budget_exceeded: '.$path)": {"class": "representability", "count": 3, "unit": "page", "finding": "html_include_budget_exceeded", "pending": true}, - "InvalidArgumentException('html_include_invalid_directive: '.$path)": {"class": "representability", "count": 1, "unit": "page", "finding": "html_include_directive_ignored", "test": "tests/contract/html-include-page-local-limits.php"}, - "InvalidArgumentException('html_include_missing_path: '.$target)": {"class": "representability", "count": 1, "unit": "page", "finding": "html_include_directive_ignored", "test": "tests/contract/html-include-page-local-limits.php"}, - "InvalidArgumentException('html_include_total_budget_exceeded')": {"class": "operational", "count": 1}, - "InvalidArgumentException('html_include_unsafe_entrypoint')": {"class": "integrity", "count": 1} + "InvalidArgumentException('html_include_count_exceeded: '.$path)": { + "class": "representability", + "count": 3, + "unit": "page", + "finding": "html_include_budget_exceeded", + "test": "tests/contract/html-include-page-local-limits.php" + }, + "InvalidArgumentException('html_include_cycle: '.$path)": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('html_include_depth_exceeded: '.$path)": { + "class": "operational", + "count": 2 + }, + "InvalidArgumentException('html_include_duplicate_path: '.$duplicates[0])": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('html_include_file_budget_exceeded: '.$path)": { + "class": "representability", + "count": 3, + "unit": "page", + "finding": "html_include_budget_exceeded", + "pending": true + }, + "InvalidArgumentException('html_include_invalid_directive: '.$path)": { + "class": "representability", + "count": 1, + "unit": "page", + "finding": "html_include_directive_ignored", + "test": "tests/contract/html-include-page-local-limits.php" + }, + "InvalidArgumentException('html_include_missing_path: '.$target)": { + "class": "representability", + "count": 1, + "unit": "page", + "finding": "html_include_directive_ignored", + "test": "tests/contract/html-include-page-local-limits.php" + }, + "InvalidArgumentException('html_include_total_budget_exceeded')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('html_include_unsafe_entrypoint')": { + "class": "integrity", + "count": 1 + } }, "src/ArtifactCompiler/ResponsiveDocumentVariants.php": { - "InvalidArgumentException('Artifact document variants require an explicit files collection.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Artifact document_variants must be an array.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document variant ids must be bounded lowercase identifiers.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document variant media must be a bounded CSS media query.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document variant primary source must contain a body element.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Each document variant declaration must be an object.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Each document variant declaration must contain variants.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Each document variant must be an object.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Document variant \"%s\" must contain a body element.',$variant['path']))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Document variant %s must be a safe relative path.',$field))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Document variant primary source \"%s\" is missing.',$sourcePath))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Document variant source \"%s\" is missing or aliases its primary.',$variantPath))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Document variant source \"%s\" is not a file record.',$path))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Document variant source \"%s\" requires embedded text content.',$path))": {"class": "integrity", "count": 1} + "InvalidArgumentException('Artifact document variants require an explicit files collection.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Artifact document_variants must be an array.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document variant ids must be bounded lowercase identifiers.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document variant media must be a bounded CSS media query.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document variant primary source must contain a body element.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Each document variant declaration must be an object.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Each document variant declaration must contain variants.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Each document variant must be an object.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Document variant \"%s\" must contain a body element.',$variant['path']))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Document variant %s must be a safe relative path.',$field))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Document variant primary source \"%s\" is missing.',$sourcePath))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Document variant source \"%s\" is missing or aliases its primary.',$variantPath))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Document variant source \"%s\" is not a file record.',$path))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Document variant source \"%s\" requires embedded text content.',$path))": { + "class": "integrity", + "count": 1 + } }, "src/ArtifactCompiler/RuntimeDeclarations.php": { - "InvalidArgumentException(\"Runtime declaration {$index} asset publication has a duplicate reference target.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} asset publication has an invalid reference target.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} asset publication lacks explicit source, destination, or sanitization proof.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} asset publication reference targets must be bounded.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} asset transformation has an unsafe input path.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} asset transformation inputs must be bounded lists.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} asset transformation is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} asset transformation requires declared local CSS and font inputs.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} contains an entity that exceeds the byte limit.\")": {"class": "representability", "count": 1, "unit": "item", "finding": "runtime_entity_dropped", "pending": true}, - "InvalidArgumentException(\"Runtime declaration {$index} entity collections require a typed entities payload.\")": {"class": "integrity", "count": 3}, - "InvalidArgumentException(\"Runtime declaration {$index} entity manifest is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric JSON pointer exceeds its depth limit.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric JSON pointer uses invalid escaping.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric URL must be a public HTTPS JSON resource without credentials or query syntax.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric URL path contains a dot segment.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric URL template has malformed variables.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric URL template is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric anchor must be exactly one native {$block} text block.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric captured fallback is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric edge-character constraint is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric entity identity is invalid or duplicated.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric extraction is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric extraction type descriptor is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric fallback must match its anchored native leaf text.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric fixed query parameters are invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric fixed query value is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric formatting is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric freshness bound is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric header is unsafe or invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric headers are invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric name or aggregation is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric native leaf anchor exceeds its byte limit.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric native text-leaf binding is invalid.\")": {"class": "integrity", "count": 2}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric operator mapping is incomplete.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric prohibited resource value is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric query variable is invalid or duplicated.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric query variables are invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric query variables must be unique.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric request limits or media type are invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric request must explicitly accept JSON.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric requires explicit source provenance.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric requires one native text-leaf binding.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric resource value is invalid or unsafe.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variable constraint is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variable schema does not match request variables.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variable schema is incomplete or over its bound.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variables do not match its request template.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric resources must be a bounded non-empty list.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric resources must be unique.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric source corroboration is incomplete.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric source identity or intent is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metric substitutions must occur only in the bounded URL path.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} external metrics require a bounded non-empty entity list.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} form layout graph must be an object.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} form presentation graph must be an object.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} form steps require an object and their layout graph.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} has a duplicate reconciliation identity.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} has an unsafe or contradictory identity.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} has an unsupported type or capability.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} identity aggregation requires exactly one resource.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} must be an object.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} payload exceeds the byte limit.\")": {"class": "representability", "count": 1, "unit": "item", "finding": "runtime_declaration_dropped", "test": "tests/contract/runtime-entity-budget.php"}, - "InvalidArgumentException(\"Runtime declaration {$index} payload is not serializable.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} payload requires a bounded nonblank schema.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance contains an unsupported value.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance exceeds the key limit of \".self::MAX_PROVENANCE_KEYS.'.')": {"class": "operational", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance exceeds the nesting limit of \".self::MAX_PROVENANCE_DEPTH.'.')": {"class": "operational", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance exceeds the {$bytes}-byte limit of \".self::MAX_PROVENANCE_BYTES.'.')": {"class": "operational", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance has an unsupported key.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance key exceeds the byte limit of \".self::MAX_PROVENANCE_SCALAR_BYTES.'.')": {"class": "operational", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance must be an object.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance must retain its safe source path.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} provenance scalar exceeds the byte limit of \".self::MAX_PROVENANCE_SCALAR_BYTES.'.')": {"class": "operational", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} reconciliation_identity must derive from its source path and kind.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} record manifest has an invalid reference.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} record manifest is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} required_for must be a list of declaration keys.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} required_for must not contain duplicates.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} required_for references unresolved declaration {$required}.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} string metric formatting must not group, add decimals, or append a suffix.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} sum aggregation requires nonnegative integer extraction.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declaration {$index} uses the retired provider-specific external metric shape.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime declarations exceed the aggregate canonical byte limit of \".self::MAX_TOTAL_DECLARATION_BYTES.\" at declaration {$index}.\")": {"class": "operational", "count": 1}, - "InvalidArgumentException(\"Runtime record {$index} has a stale identity or content hash.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"Runtime record {$index} is invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication provenance must exactly match normalized artifact file metadata.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication provenance references an undeclared normalized artifact file.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime declaration payload contains an unsupported value.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('Runtime declaration payload has an unsupported key.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('Runtime declaration payload is not serializable.')": {"class": "integrity", "count": 3}, - "InvalidArgumentException('Runtime declaration record reference is unresolved or stale.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime declarations are not canonically normalized or have stale hashes.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime declarations must be a bounded ordered collection.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime declarations must be provided in exactly one canonical artifact location.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime records must be a bounded ordered collection.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime records must have unique content-addressed ids.')": {"class": "integrity", "count": 1} + "InvalidArgumentException(\"Runtime declaration {$index} asset publication has a duplicate reference target.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} asset publication has an invalid reference target.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} asset publication lacks explicit source, destination, or sanitization proof.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} asset publication reference targets must be bounded.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} asset transformation has an unsafe input path.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} asset transformation inputs must be bounded lists.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} asset transformation is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} asset transformation requires declared local CSS and font inputs.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} contains an entity that exceeds the byte limit.\")": { + "class": "representability", + "count": 1, + "unit": "item", + "finding": "runtime_entity_dropped", + "pending": true + }, + "InvalidArgumentException(\"Runtime declaration {$index} entity collections require a typed entities payload.\")": { + "class": "integrity", + "count": 3 + }, + "InvalidArgumentException(\"Runtime declaration {$index} entity manifest is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric JSON pointer exceeds its depth limit.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric JSON pointer uses invalid escaping.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric URL must be a public HTTPS JSON resource without credentials or query syntax.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric URL path contains a dot segment.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric URL template has malformed variables.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric URL template is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric anchor must be exactly one native {$block} text block.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric captured fallback is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric edge-character constraint is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric entity identity is invalid or duplicated.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric extraction is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric extraction type descriptor is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric fallback must match its anchored native leaf text.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric fixed query parameters are invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric fixed query value is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric formatting is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric freshness bound is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric header is unsafe or invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric headers are invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric name or aggregation is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric native leaf anchor exceeds its byte limit.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric native text-leaf binding is invalid.\")": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric operator mapping is incomplete.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric prohibited resource value is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric query variable is invalid or duplicated.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric query variables are invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric query variables must be unique.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric request limits or media type are invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric request must explicitly accept JSON.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric requires explicit source provenance.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric requires one native text-leaf binding.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric resource value is invalid or unsafe.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variable constraint is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variable schema does not match request variables.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variable schema is incomplete or over its bound.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric resource variables do not match its request template.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric resources must be a bounded non-empty list.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric resources must be unique.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric source corroboration is incomplete.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric source identity or intent is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metric substitutions must occur only in the bounded URL path.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} external metrics require a bounded non-empty entity list.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} form layout graph must be an object.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} form presentation graph must be an object.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} form steps require an object and their layout graph.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} has a duplicate reconciliation identity.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} has an unsafe or contradictory identity.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} has an unsupported type or capability.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} identity aggregation requires exactly one resource.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} must be an object.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} payload exceeds the byte limit.\")": { + "class": "representability", + "count": 1, + "unit": "item", + "finding": "runtime_declaration_dropped", + "test": "tests/contract/runtime-entity-budget.php" + }, + "InvalidArgumentException(\"Runtime declaration {$index} payload is not serializable.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} payload requires a bounded nonblank schema.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance contains an unsupported value.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance exceeds the key limit of \".self::MAX_PROVENANCE_KEYS.'.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance exceeds the nesting limit of \".self::MAX_PROVENANCE_DEPTH.'.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance exceeds the {$bytes}-byte limit of \".self::MAX_PROVENANCE_BYTES.'.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance has an unsupported key.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance key exceeds the byte limit of \".self::MAX_PROVENANCE_SCALAR_BYTES.'.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance must be an object.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance must retain its safe source path.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} provenance scalar exceeds the byte limit of \".self::MAX_PROVENANCE_SCALAR_BYTES.'.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} reconciliation_identity must derive from its source path and kind.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} record manifest has an invalid reference.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} record manifest is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} required_for must be a list of declaration keys.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} required_for must not contain duplicates.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} required_for references unresolved declaration {$required}.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} string metric formatting must not group, add decimals, or append a suffix.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} sum aggregation requires nonnegative integer extraction.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declaration {$index} uses the retired provider-specific external metric shape.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime declarations exceed the aggregate canonical byte limit of \".self::MAX_TOTAL_DECLARATION_BYTES.\" at declaration {$index}.\")": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException(\"Runtime record {$index} has a stale identity or content hash.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"Runtime record {$index} is invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication provenance must exactly match normalized artifact file metadata.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication provenance references an undeclared normalized artifact file.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime declaration payload contains an unsupported value.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('Runtime declaration payload has an unsupported key.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('Runtime declaration payload is not serializable.')": { + "class": "integrity", + "count": 3 + }, + "InvalidArgumentException('Runtime declaration record reference is unresolved or stale.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime declarations are not canonically normalized or have stale hashes.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime declarations must be a bounded ordered collection.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime declarations must be provided in exactly one canonical artifact location.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime records must be a bounded ordered collection.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime records must have unique content-addressed ids.')": { + "class": "integrity", + "count": 1 + } }, "src/ArtifactCompiler/RuntimeEntityManifest.php": { - "InvalidArgumentException('Runtime entity manifest payload is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime entity manifest record exceeds the 5 MiB payload limit.')": {"class": "integrity", "count": 1, "finding": "runtime_entity_dropped", "test": "tests/contract/runtime-entity-budget.php"}, - "InvalidArgumentException('Runtime entity manifest record hashes must be unique.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime entity manifest record is invalid or exceeds the 5 MiB payload limit.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime entity manifest records must be objects.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime entity manifest references an undeclared record.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Runtime entity manifest references exceed the 5 MiB payload limit.')": {"class": "representability", "count": 1, "unit": "item", "finding": "runtime_declaration_dropped", "test": "tests/contract/runtime-entity-budget.php"} + "InvalidArgumentException('Runtime entity manifest payload is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime entity manifest record exceeds the 5 MiB payload limit.')": { + "class": "integrity", + "count": 1, + "finding": "runtime_entity_dropped", + "test": "tests/contract/runtime-entity-budget.php" + }, + "InvalidArgumentException('Runtime entity manifest record hashes must be unique.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime entity manifest record is invalid or exceeds the 5 MiB payload limit.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime entity manifest records must be objects.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime entity manifest references an undeclared record.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Runtime entity manifest references exceed the 5 MiB payload limit.')": { + "class": "representability", + "count": 1, + "unit": "item", + "finding": "runtime_declaration_dropped", + "test": "tests/contract/runtime-entity-budget.php" + } }, "src/ArtifactCompiler/StagedTransport.php": { - "InvalidArgumentException('A compiled page plan contains invalid or duplicate document output.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page plan requires the compiled page receipt schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt cannot omit the entrypoint page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt carries a malformed omitted page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt does not exactly cover its owned HTML documents.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt does not exactly cover its owned transformable sources.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt is bound to another shared reduction.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt omits a page that is undeclared or still compiled.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt requires a complete terminal reduction.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A compiled page receipt requires its omitted pages as a list.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A declared capture report exceeds the compiler per-file report byte limit.')": {"class": "operational", "count": 1}, - "InvalidArgumentException('A payload reference exceeds the compiler per-file byte limit.')": {"class": "representability", "count": 1, "unit": "page", "finding": "page_compile_omitted", "pending": true}, - "InvalidArgumentException('A payload reference requires a schema, id, byte count, and sha256 hex digest.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A reference-backed media payload exceeds the compiler per-file media byte limit.')": {"class": "representability", "count": 1, "unit": "asset", "finding": "wordpress_site_plan_missing_local_media", "pending": true}, - "InvalidArgumentException('A staged page plan must be bound to the supplied shared plan digest.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged page plan must declare the staged page plan schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged page plan requires a nonblank page id.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged page plan requires its serialized artifact payload.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged page plan was prepared with incompatible compiler options or output schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged shared plan must declare the staged shared plan schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged shared plan requires a valid digest-bound shared reduction.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged shared plan requires its serialized artifact payload.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A staged shared plan was prepared with incompatible compiler options.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Compiled terminal receipts require the digest-bound shared reduction supplied by their shared plan.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Composition received more than one omission for the same page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Composition requires a compiled receipt for every page plan.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Composition requires a payload reader for referenced staged payloads.')": {"class": "programmer", "count": 1}, - "InvalidArgumentException('Composition requires exactly one compiled page plan for every page declared by the shared plan.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Declared capture reports exceed the compiler aggregate report byte limit.')": {"class": "operational", "count": 1}, - "InvalidArgumentException('Payload references exceed the compiler aggregate byte limit.')": {"class": "operational", "count": 1}, - "InvalidArgumentException('Prepared page batches require unique page plans with string page ids.')": {"class": "programmer", "count": 1}, - "InvalidArgumentException('Reference-backed media payloads exceed the compiler aggregate media byte limit.')": {"class": "operational", "count": 1}, - "InvalidArgumentException('The payload reader returned bytes that do not match the payload reference.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('The requested page ownership id is not present in the artifact.')": {"class": "programmer", "count": 1}, - "InvalidArgumentException(sprintf('A staged %s plan requires a sha256 hex digest.',$label))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Composed staged plans collide on artifact path \"%s\".',$path))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Composition received more than one staged page plan for page id \"%s\".',$pagePlan['page_id']))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('The staged %s plan digest does not match its serialized artifact payload.',$label))": {"class": "integrity", "count": 1} + "InvalidArgumentException('A compiled page plan contains invalid or duplicate document output.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page plan requires the compiled page receipt schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt cannot omit the entrypoint page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt carries a malformed omitted page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt does not exactly cover its owned HTML documents.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt does not exactly cover its owned transformable sources.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt is bound to another shared reduction.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt omits a page that is undeclared or still compiled.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt requires a complete terminal reduction.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A compiled page receipt requires its omitted pages as a list.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A declared capture report exceeds the compiler per-file report byte limit.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('A payload reference exceeds the compiler per-file byte limit.')": { + "class": "representability", + "count": 1, + "unit": "page", + "finding": "page_compile_omitted", + "pending": true + }, + "InvalidArgumentException('A payload reference requires a schema, id, byte count, and sha256 hex digest.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A reference-backed media payload exceeds the compiler per-file media byte limit.')": { + "class": "representability", + "count": 1, + "unit": "asset", + "finding": "wordpress_site_plan_missing_local_media", + "pending": true + }, + "InvalidArgumentException('A staged page plan must be bound to the supplied shared plan digest.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged page plan must declare the staged page plan schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged page plan requires a nonblank page id.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged page plan requires its serialized artifact payload.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged page plan was prepared with incompatible compiler options or output schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged shared plan must declare the staged shared plan schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged shared plan requires a valid digest-bound shared reduction.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged shared plan requires its serialized artifact payload.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A staged shared plan was prepared with incompatible compiler options.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Compiled terminal receipts require the digest-bound shared reduction supplied by their shared plan.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Composition received more than one omission for the same page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Composition requires a compiled receipt for every page plan.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Composition requires a payload reader for referenced staged payloads.')": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException('Composition requires exactly one compiled page plan for every page declared by the shared plan.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Declared capture reports exceed the compiler aggregate report byte limit.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('Payload references exceed the compiler aggregate byte limit.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('Prepared page batches require unique page plans with string page ids.')": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException('Reference-backed media payloads exceed the compiler aggregate media byte limit.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('The payload reader returned bytes that do not match the payload reference.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('The requested page ownership id is not present in the artifact.')": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException(sprintf('A staged %s plan requires a sha256 hex digest.',$label))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Composed staged plans collide on artifact path \"%s\".',$path))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Composition received more than one staged page plan for page id \"%s\".',$pagePlan['page_id']))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('The staged %s plan digest does not match its serialized artifact payload.',$label))": { + "class": "integrity", + "count": 1 + } }, "src/ArtifactCompiler/ThemePreferenceOwnership.php": { - "InvalidArgumentException('Theme preference declaration control evidence is malformed or out of order.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration explicit transition is malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration has a contradictory light root operation.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration has an invalid root contract.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration has an invalid source, anchor, asset, storage key, or system query.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration has an unsupported evidence schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration observed root state contradicts its operation or duplicates a transition.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration omits a required explicit or system transition.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration requires a captured unset-storage default across both OS schemes.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration requires bounded source stylesheet evidence.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration requires exactly three observed controls.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration requires four browser-observed transitions.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration system transition disagrees with the observed OS scheme.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference declaration transition is missing its observed storage or root state.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference default observation contradicts its root operation or duplicates an OS scheme.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference default observation contradicts the captured default preference.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference default observation is missing unset storage or root state.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Theme preference source stylesheet evidence exceeds its byte budget.')": {"class": "operational", "count": 1}, - "InvalidArgumentException('Theme preference source stylesheet evidence is malformed or stale.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Theme preference declaration control evidence is malformed or out of order.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration explicit transition is malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration has a contradictory light root operation.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration has an invalid root contract.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration has an invalid source, anchor, asset, storage key, or system query.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration has an unsupported evidence schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration observed root state contradicts its operation or duplicates a transition.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration omits a required explicit or system transition.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration requires a captured unset-storage default across both OS schemes.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration requires bounded source stylesheet evidence.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration requires exactly three observed controls.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration requires four browser-observed transitions.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration system transition disagrees with the observed OS scheme.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference declaration transition is missing its observed storage or root state.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference default observation contradicts its root operation or duplicates an OS scheme.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference default observation contradicts the captured default preference.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference default observation is missing unset storage or root state.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Theme preference source stylesheet evidence exceeds its byte budget.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('Theme preference source stylesheet evidence is malformed or stale.')": { + "class": "integrity", + "count": 1 + } }, "src/Contract/ConversionFindingContract.php": { - "InvalidArgumentException(sprintf('%s field \"%s\" must be a string.',ucfirst($label),$field))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s field \"%s\" must be an array.',ucfirst($label),$field))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s field \"observed_block\" must be a string or an array.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s has an unsupported severity.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s is missing a non-empty \"code\"/\"diagnostic_code\" identifier.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s must be a list.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s.%d must be an object.',$label,$index))": {"class": "integrity", "count": 1} + "InvalidArgumentException(sprintf('%s field \"%s\" must be a string.',ucfirst($label),$field))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s field \"%s\" must be an array.',ucfirst($label),$field))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s field \"observed_block\" must be a string or an array.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s has an unsupported severity.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s is missing a non-empty \"code\"/\"diagnostic_code\" identifier.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s must be a list.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s.%d must be an object.',$label,$index))": { + "class": "integrity", + "count": 1 + } }, "src/Contract/TransformerResult.php": { - "InvalidArgumentException('Canonical artifact result font materialization must be an array.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical artifact result is missing source_reports.compiled_site.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical artifact result wordpress site plan must be an array.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result conversion report is missing source_format.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result has an unsupported conversion report schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result has an unsupported schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result has an unsupported status.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result is missing source_reports.conversion_report.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result must not expose compatibility-only legacy_mapping.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result source_reports must be an array.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Canonical transformer result source_reports must not expose compatibility-only legacy_mapping.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Materialization-plan validation was removed; consume wordpress_site_plan/v2 instead.')": {"class": "programmer", "count": 1}, - "InvalidArgumentException(sprintf('Canonical transformer result %s must be an array.',$key))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Canonical transformer result conversion report %s must be an array.',$key))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Canonical transformer result is missing \"%s\".',$key))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Canonical transformer result must expose %s only under source_reports.',$key))": {"class": "integrity", "count": 1} + "InvalidArgumentException('Canonical artifact result font materialization must be an array.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical artifact result is missing source_reports.compiled_site.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical artifact result wordpress site plan must be an array.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result conversion report is missing source_format.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result has an unsupported conversion report schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result has an unsupported schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result has an unsupported status.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result is missing source_reports.conversion_report.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result must not expose compatibility-only legacy_mapping.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result source_reports must be an array.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Canonical transformer result source_reports must not expose compatibility-only legacy_mapping.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Materialization-plan validation was removed; consume wordpress_site_plan/v2 instead.')": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException(sprintf('Canonical transformer result %s must be an array.',$key))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Canonical transformer result conversion report %s must be an array.',$key))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Canonical transformer result is missing \"%s\".',$key))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Canonical transformer result must expose %s only under source_reports.',$key))": { + "class": "integrity", + "count": 1 + } }, "src/Contract/ValidationEvidencePolicy.php": { - "InvalidArgumentException('validation_evidence must be \"full\" or \"compact\".')": {"class": "programmer", "count": 1} + "InvalidArgumentException('validation_evidence must be \"full\" or \"compact\".')": { + "class": "programmer", + "count": 1 + } }, "src/Contract/VisualParityReportContract.php": { - "InvalidArgumentException(\"Visual parity report matches.{$index}.confidence must be numeric.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Visual parity fixture has an unsupported schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Visual parity report has an unsupported schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Visual parity report has an unsupported status.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s has an unsupported component kind.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s has an unsupported severity.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s is missing \"%s\".',ucfirst($label),$key))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s must be an array.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s must be an object.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s must be numeric between 0 and 1.',ucfirst($label)))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('%s.%s must be a string.',ucfirst($label),$field))": {"class": "integrity", "count": 1} + "InvalidArgumentException(\"Visual parity report matches.{$index}.confidence must be numeric.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Visual parity fixture has an unsupported schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Visual parity report has an unsupported schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Visual parity report has an unsupported status.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s has an unsupported component kind.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s has an unsupported severity.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s is missing \"%s\".',ucfirst($label),$key))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s must be an array.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s must be an object.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s must be numeric between 0 and 1.',ucfirst($label)))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('%s.%s must be a string.',ucfirst($label),$field))": { + "class": "integrity", + "count": 1 + } }, "src/Css/CssSelectorMatchCache.php": { - "InvalidArgumentException('A selector match cache must retain at least one result.')": {"class": "programmer", "count": 1} + "InvalidArgumentException('A selector match cache must retain at least one result.')": { + "class": "programmer", + "count": 1 + } }, "src/FormatBridge/FormatBridge.php": { - "InvalidArgumentException(sprintf('No format adapter is registered for format \"%s\".',$from))": {"class": "programmer", "count": 1}, - "InvalidArgumentException(sprintf('No format adapter is registered for format \"%s\".',$to))": {"class": "programmer", "count": 1} + "InvalidArgumentException(sprintf('No format adapter is registered for format \"%s\".',$from))": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException(sprintf('No format adapter is registered for format \"%s\".',$to))": { + "class": "programmer", + "count": 1 + } }, "src/FormatBridge/Normalizer.php": { - "InvalidArgumentException('Declared HTML content contains markdown markers.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Declared HTML content contains serialized block comments.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Declared blocks content contains raw content outside serialized block comments.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('Declared blocks content does not contain serialized block comments.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Declared markdown content contains serialized block comments.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Malformed serialized block comment.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Mismatched serialized block closing comment.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Serialized block markup contains an unclosed block comment.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('No format adapter is registered for format \"%s\".',$format))": {"class": "programmer", "count": 1}, - "InvalidArgumentException(sprintf('Unsupported normalization mode \"%s\".',$mode))": {"class": "programmer", "count": 1} + "InvalidArgumentException('Declared HTML content contains markdown markers.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Declared HTML content contains serialized block comments.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Declared blocks content contains raw content outside serialized block comments.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('Declared blocks content does not contain serialized block comments.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Declared markdown content contains serialized block comments.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Malformed serialized block comment.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Mismatched serialized block closing comment.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Serialized block markup contains an unclosed block comment.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('No format adapter is registered for format \"%s\".',$format))": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException(sprintf('Unsupported normalization mode \"%s\".',$mode))": { + "class": "programmer", + "count": 1 + } }, "src/HtmlToBlocks/Elements/PatternElementConverter.php": { - "InvalidArgumentException('PatternElementConverter requires at least one pattern.')": {"class": "programmer", "count": 1} + "InvalidArgumentException('PatternElementConverter requires at least one pattern.')": { + "class": "programmer", + "count": 1 + } }, "src/HtmlToBlocks/Style/AuthorStyleAnalysis.php": { - "InvalidArgumentException(\"Undeclared engine marker kind: {$kind}. Declare it in EngineMarker::DOCUMENT_KINDS.\")": {"class": "programmer", "count": 1}, - "InvalidArgumentException(\"Undeclared engine marker kind: {$kind}.\")": {"class": "programmer", "count": 1} + "InvalidArgumentException(\"Undeclared engine marker kind: {$kind}. Declare it in EngineMarker::DOCUMENT_KINDS.\")": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException(\"Undeclared engine marker kind: {$kind}.\")": { + "class": "programmer", + "count": 1 + } }, "src/HtmlToBlocks/Style/FormControlTopologyBuilder.php": { - "InvalidArgumentException('Form control topology envelope is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology fieldset semantics must describe a fieldset wrapper.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology group labels must be bounded text on an ARIA group wrapper.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology legends must be bounded labelled-group text.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology must be a wrapper tree with parents before children.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology must cover every flat control exactly once.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology must reference unique flat control indexes.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology node is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology sibling order must be unique.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form control topology wrapper hooks are unsafe.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form sibling relations envelope is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form sibling relations must reference unique flat controls.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Form control topology envelope is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology fieldset semantics must describe a fieldset wrapper.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology group labels must be bounded text on an ARIA group wrapper.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology legends must be bounded labelled-group text.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology must be a wrapper tree with parents before children.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology must cover every flat control exactly once.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology must reference unique flat control indexes.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology node is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology sibling order must be unique.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form control topology wrapper hooks are unsafe.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form sibling relations envelope is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form sibling relations must reference unique flat controls.')": { + "class": "integrity", + "count": 1 + } }, "src/HtmlToBlocks/Style/FormLayoutGraphBuilder.php": { - "InvalidArgumentException('Form layout graph label control reference is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph label reference owner is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph label identity is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph envelope has unknown keys.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph envelope is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph exceeds its node limit.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph exceeds its variant limit.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph has a dangling parent.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph has a parent cycle.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph in-flow child count is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph node identity is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph node is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph parents must precede their children.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph provenance exceeds its limit.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph provenance is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph important facts are invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph sizing evidence is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph value is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph variant is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form layout graph variant precedence is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form source element identity is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form source element identity is unsafe.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form source element presentation owner is invalid.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Form layout graph label control reference is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph label reference owner is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph label identity is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph envelope has unknown keys.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph envelope is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph exceeds its node limit.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph exceeds its variant limit.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph has a dangling parent.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph has a parent cycle.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph in-flow child count is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph node identity is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph node is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph parents must precede their children.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph provenance exceeds its limit.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph provenance is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph important facts are invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph sizing evidence is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph value is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph variant is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form layout graph variant precedence is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form source element identity is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form source element identity is unsafe.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form source element presentation owner is invalid.')": { + "class": "integrity", + "count": 1 + } }, "src/HtmlToBlocks/Style/FormPresentationGraphBuilder.php": { - "InvalidArgumentException('Form element presentation envelope has unknown keys.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form element presentation envelope is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form element presentation precedence has unknown keys.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form element presentation precedence is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form element presentation variant has unknown keys.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form element presentation variant is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation conditional control container has no variants.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation control container is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation control is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation graph envelope is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation group caption is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation precedence is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation provenance exceeds its limit.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation provenance has unknown keys.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation provenance is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation role is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation style is invalid.')": {"class": "integrity", "count": 1, "finding": "style_value_unrepresentable", "test": "tests/unit/form-presentation-unrepresentable-style-value.php"}, - "InvalidArgumentException('Form presentation variant is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual group identity is duplicated.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual group is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual group source CSS is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual group unknown CSS state is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual part dimensions are invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual part identity is duplicated.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual part is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual part source CSS is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form presentation visual part unknown CSS state is invalid.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Form element presentation envelope has unknown keys.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form element presentation envelope is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form element presentation precedence has unknown keys.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form element presentation precedence is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form element presentation variant has unknown keys.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form element presentation variant is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation conditional control container has no variants.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation control container is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation control is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation graph envelope is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation group caption is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation precedence is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation provenance exceeds its limit.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation provenance has unknown keys.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation provenance is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation role is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation style is invalid.')": { + "class": "integrity", + "count": 1, + "finding": "style_value_unrepresentable", + "test": "tests/unit/form-presentation-unrepresentable-style-value.php" + }, + "InvalidArgumentException('Form presentation variant is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual group identity is duplicated.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual group is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual group source CSS is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual group unknown CSS state is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual part dimensions are invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual part identity is duplicated.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual part is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual part source CSS is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form presentation visual part unknown CSS state is invalid.')": { + "class": "integrity", + "count": 1 + } }, "src/HtmlToBlocks/Style/FormStepTrackDetector.php": { - "InvalidArgumentException('Form step track completion must be a container child of the track.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form step track envelope is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form step track navigation must be a form-level container beside the track.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Form step track steps must be distinct container children of the track.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Form step track completion must be a container child of the track.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form step track envelope is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form step track navigation must be a form-level container beside the track.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Form step track steps must be distinct container children of the track.')": { + "class": "integrity", + "count": 1 + } }, "src/StaticSite/FontMaterialization/FontMaterializationPlanBuilder.php": { - "InvalidArgumentException('Font materialization plan CSS and stylesheet projection disagree.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Font materialization plan fonts are malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Font materialization plan fonts are not canonical.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Font materialization plan has an unsupported schema or provider.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Font materialization plan has invalid typed fonts.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Font materialization plan role references an unknown font.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Font materialization plan stylesheet is malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Font materialization plan stylesheets are malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont SVG consumer has stale payload or noncanonical references.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont SVG consumer identity is invalid or duplicated.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont SVG consumer is malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont SVG consumer references an unknown face or receipt.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont SVG consumer references are noncanonical.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont SVG consumers are not canonically sorted.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont contract SVG consumers are malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization contract is malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization face axes are malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization face or receipt graph is inconsistent.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization import is malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization import provider is inconsistent.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization readiness is inconsistent.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization receipt is malformed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Webfont materialization receipts do not cover declared faces.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Font materialization plan CSS and stylesheet projection disagree.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Font materialization plan fonts are malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Font materialization plan fonts are not canonical.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Font materialization plan has an unsupported schema or provider.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Font materialization plan has invalid typed fonts.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Font materialization plan role references an unknown font.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Font materialization plan stylesheet is malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Font materialization plan stylesheets are malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont SVG consumer has stale payload or noncanonical references.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont SVG consumer identity is invalid or duplicated.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont SVG consumer is malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont SVG consumer references an unknown face or receipt.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont SVG consumer references are noncanonical.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont SVG consumers are not canonically sorted.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont contract SVG consumers are malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization contract is malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization face axes are malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization face or receipt graph is inconsistent.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization import is malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization import provider is inconsistent.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization readiness is inconsistent.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization receipt is malformed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Webfont materialization receipts do not cover declared faces.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPress/CoreBlockCapabilityMatrix.php": { - "RuntimeException('Core block capability matrix does not match the bundled metadata snapshot. Missing: '.implode(', ',$missing).'; stale: '.implode(', ',$stale))": {"class": "programmer", "count": 1}, - "RuntimeException('Core block capability matrix has no classification for available runtime block(s): '.implode(', ',$unclassified))": {"class": "programmer", "count": 1}, - "RuntimeException('HTML transformer emitter has no core metadata classification: '.$name)": {"class": "programmer", "count": 1} + "RuntimeException('Core block capability matrix does not match the bundled metadata snapshot. Missing: '.implode(', ',$missing).'; stale: '.implode(', ',$stale))": { + "class": "programmer", + "count": 1 + }, + "RuntimeException('Core block capability matrix has no classification for available runtime block(s): '.implode(', ',$unclassified))": { + "class": "programmer", + "count": 1 + }, + "RuntimeException('HTML transformer emitter has no core metadata classification: '.$name)": { + "class": "programmer", + "count": 1 + } }, "src/WordPress/Runtime.php": { - "RuntimeException('Bundled core block metadata snapshot has no block declarations: '.basename($path))": {"class": "integrity", "count": 1}, - "RuntimeException('Bundled core block metadata snapshot is invalid: '.basename($path))": {"class": "integrity", "count": 1}, - "RuntimeException('Bundled core block metadata snapshot is unavailable: '.basename($path))": {"class": "operational", "count": 1} + "RuntimeException('Bundled core block metadata snapshot has no block declarations: '.basename($path))": { + "class": "integrity", + "count": 1 + }, + "RuntimeException('Bundled core block metadata snapshot is invalid: '.basename($path))": { + "class": "integrity", + "count": 1 + }, + "RuntimeException('Bundled core block metadata snapshot is unavailable: '.basename($path))": { + "class": "operational", + "count": 1 + } }, "src/WordPressSitePlan/AssetReferenceCanonicalizer.php": { - "InvalidArgumentException('WordPress site plan has colliding declared asset source identities.')": {"class": "integrity", "count": 1}, - "ValidationException($error->getMessage())": {"class": "integrity", "count": 2}, - "ValidationException('Gallery sequence must be a JSON list of URL strings.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('WordPress site plan has colliding declared asset source identities.')": { + "class": "integrity", + "count": 1 + }, + "ValidationException($error->getMessage())": { + "class": "integrity", + "count": 2 + }, + "ValidationException('Gallery sequence must be a JSON list of URL strings.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPressSitePlan/DocumentHeadContext.php": { - "InvalidArgumentException('Document head '.$row['tag'].' asset is not bound to a declared write or external URL: '.mb_strcut((string)$reference,0,160,'UTF-8'))": {"class": "integrity", "count": 1, "finding": "wordpress_site_plan_omitted_link_declaration", "test": "tests/contract/unresolved-local-head-links.php"}, - "InvalidArgumentException('Document head attributes are invalid or exceed their budget.')": {"class": "integrity", "count": 1, "finding": "document_head_attribute_dropped", "test": "tests/contract/document-head-unrepresentable-items.php"}, - "InvalidArgumentException('Document head context is invalid or exceeds its element budget.')": {"class": "integrity", "count": 1, "finding": "document_head_element_dropped", "test": "tests/contract/document-head-unrepresentable-items.php"}, - "InvalidArgumentException('Document head data URL exceeds its budget.')": {"class": "integrity", "count": 1, "finding": "document_head_element_dropped", "test": "tests/contract/document-head-unrepresentable-items.php"}, - "InvalidArgumentException('Document head element is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document head inline data declaration is invalid or exceeds its budget.')": {"class": "integrity", "count": 1, "finding": "document_head_element_dropped", "test": "tests/contract/document-head-unrepresentable-items.php"}, - "InvalidArgumentException('Document head inline script lacks a canonical script payload.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document head link lacks source occurrence provenance.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document head must declare a unique viewport.')": {"class": "integrity", "count": 1, "finding": "document_head_duplicate_viewport", "test": "tests/contract/document-head-runtime.php"}, - "InvalidArgumentException('Document head script cannot close its raw-text element.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document head script must declare inline or external source semantics.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document head style lacks a canonical CSS write.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document head style must bind a canonical stylesheet write.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Document head '.$row['tag'].' asset is not bound to a declared write or external URL: '.mb_strcut((string)$reference,0,160,'UTF-8'))": { + "class": "integrity", + "count": 1, + "finding": "wordpress_site_plan_omitted_link_declaration", + "test": "tests/contract/unresolved-local-head-links.php" + }, + "InvalidArgumentException('Document head attributes are invalid or exceed their budget.')": { + "class": "integrity", + "count": 1, + "finding": "document_head_attribute_dropped", + "test": "tests/contract/document-head-unrepresentable-items.php" + }, + "InvalidArgumentException('Document head context is invalid or exceeds its element budget.')": { + "class": "integrity", + "count": 1, + "finding": "document_head_element_dropped", + "test": "tests/contract/document-head-unrepresentable-items.php" + }, + "InvalidArgumentException('Document head data URL exceeds its budget.')": { + "class": "integrity", + "count": 1, + "finding": "document_head_element_dropped", + "test": "tests/contract/document-head-unrepresentable-items.php" + }, + "InvalidArgumentException('Document head element is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document head inline data declaration is invalid or exceeds its budget.')": { + "class": "integrity", + "count": 1, + "finding": "document_head_element_dropped", + "test": "tests/contract/document-head-unrepresentable-items.php" + }, + "InvalidArgumentException('Document head inline script lacks a canonical script payload.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document head link lacks source occurrence provenance.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document head must declare a unique viewport.')": { + "class": "integrity", + "count": 1, + "finding": "document_head_duplicate_viewport", + "test": "tests/contract/document-head-runtime.php" + }, + "InvalidArgumentException('Document head script cannot close its raw-text element.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document head script must declare inline or external source semantics.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document head style lacks a canonical CSS write.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document head style must bind a canonical stylesheet write.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPressSitePlan/DocumentRootContext.php": { - "InvalidArgumentException('Document root context must be an attribute map.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Document root selector identity is invalid.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Document root context must be an attribute map.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Document root selector identity is invalid.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPressSitePlan/ListingFieldProjection.php": { - "InvalidArgumentException('Source-backed excerpts must be strings.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A featured image handoff names a plan asset token, its alt text and, once resolved, its theme target path.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Source-backed post metadata must be a string map.')": {"class": "integrity", "count": 2} + "InvalidArgumentException('Source-backed excerpts must be strings.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A featured image handoff names a plan asset token, its alt text and, once resolved, its theme target path.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Source-backed post metadata must be a string map.')": { + "class": "integrity", + "count": 2 + } }, "src/WordPressSitePlan/NavigationEntityProjection.php": { - "InvalidArgumentException('WordPress site plan contains an undeclared navigation reference.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan navigation entities require explicit owned references.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan navigation entity declaration is invalid or duplicated.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan navigation reference contract is unsupported.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan navigation references must belong to navigation blocks.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('WordPress site plan contains an undeclared navigation reference.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan navigation entities require explicit owned references.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan navigation entity declaration is invalid or duplicated.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan navigation reference contract is unsupported.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan navigation references must belong to navigation blocks.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPressSitePlan/SyncedPatternProjection.php": { - "InvalidArgumentException('WordPress site plan contains an undeclared synced pattern reference.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan synced pattern contract is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan synced pattern declaration is invalid or duplicated.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan synced pattern references must belong to core/block blocks.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan synced patterns require explicit owned references.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('WordPress site plan contains an undeclared synced pattern reference.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan synced pattern contract is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan synced pattern declaration is invalid or duplicated.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan synced pattern references must belong to core/block blocks.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan synced patterns require explicit owned references.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPressSitePlan/WordPressSitePlan.php": { - "InvalidArgumentException('WordPress site plan page override must resolve to a materialized page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan synthetic parent must have a materialized child.')": {"class": "integrity", "count": 1}, - "DocumentIdentityException($failures)": {"class": "integrity", "count": 1}, - "DocumentIdentityException($identityFailures)": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"WordPress site plan resolved {$kind} payload is not canonical.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"WordPress site plan {$kind} has invalid {$field}.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"WordPress site plan {$kind} is structurally invalid.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"WordPress site plan {$kind} lacks {$field}.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException(\"WordPress site plan {$kind} must be an array.\")": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A declared template surface collides with a generated template.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A global asset scope cannot declare page fields.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A page asset scope does not match its canonical page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A page asset scope is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A page-owned compiled asset must resolve to a canonical page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A provider script supersession proof does not match its source inline-script asset and document metadata.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A provider script supersession proof is malformed or detached from its bound form.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A runtime entity binding has ambiguous canonical source-page anchors.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('A runtime entity binding has an invalid emitted block position.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A runtime entity binding lacks an exact emitted block anchor.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A runtime entity binding no longer has its declared source document block anchor after shell extraction: '.(is_string($source)?$source:'unknown').' ('.(is_string($binding['role']??null)?$binding['role']:'unknown').').')": {"class": "integrity", "count": 1, "finding": "runtime_entity_binding_unanchored", "test": "tests/contract/unanchored-runtime-entity-binding.php"}, - "InvalidArgumentException('A runtime entity binding no longer identifies an emitted canonical block.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A runtime entity binding no longer identifies one exact emitted canonical block.')": {"class": "integrity", "count": 3}, - "InvalidArgumentException('A runtime entity binding resolved to empty canonical block markup.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A runtime entity binding source anchor is ambiguous after reprojection.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('A native archive template collides with a declared template.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication SVG payload is unsafe.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication declaration does not match its declared source asset hashes or provenance.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication declaration does not resolve to its declared asset write.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication declaration reference context does not match its CSS token occurrence.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication declaration references an unbound destination token occurrence.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('Asset publication plain source hash must match its canonical payload.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication references an undeclared asset.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication requires a sanitized SVG source.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation CSS has duplicate properties.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation CSS input has no local font-face payload.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation CSS property is not allowed.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation CSS source is not a declared font asset.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation CSS source must be a local font path.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation CSS value is not safe.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation content hash does not match its declaration.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation final hash is contradictory.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation font-face is incomplete.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation has an unbound CSS input.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation has an unbound font input.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation inputs do not match their declared hash.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation inputs have stale hashes.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation references an undeclared local CSS input.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation references an undeclared local font input.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation rejects unsafe or non-font CSS inputs.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication transformation requires a sanitized SVG source.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Compiled site asset lacks a safe source identity.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Compiled site asset lacks a safe target identity.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('Compiled site assets must be an array.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Compiled site document is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Compiled site document is outside the entrypoint content root.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Compiled site documents must be an array.')": {"class": "integrity", "count": 4}, - "InvalidArgumentException('Compiled site route source is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Compiled site source document catalog entry is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Only stylesheet assets may declare runtime scopes.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Only stylesheet resources may declare ordered instances.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Stylesheet assets must declare a supported target.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Stylesheet instance must identify a canonical document, order and conditions.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Two stylesheet instances claim one document position.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Whole-page candidate must name one canonical source page and producer entity row.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Whole-page candidates are stale, duplicated, or detached from their canonical source pages.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Whole-page candidates must be unique by source page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan asset is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan asset lacks a write.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan asset scope is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan asset scopes must be a nonempty array.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan binary write cannot carry a resolution projection.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan contains an undeclared reference token.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan content decision evidence is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan structured page evidence is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan content decision is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan content decision provenance is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan content decision timestamp is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan create_page operation is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan declared template surface is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan diagnostic linkage is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan diagnostics are not linked to reporting.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan document canvas is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan document metadata is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan external metadata URL must not carry a resolved alias.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan font materialization is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan functions.php bootstrap is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan has an invalid reference token declaration.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan has an unproven template part binding.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan has an unsafe explicit page route.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan has an unsupported schema.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan identity is missing, malformed, or stale.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan must declare exactly one token for each asset.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan must export every canonical page route.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan operation is invalid.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('WordPress site plan operation references an invalid front page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan operations are incomplete.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan page has a stale content hash.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan page lacks a canonical route.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan page route is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan page routes reject encoded path separators and dot segments.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan payload references are limited to non-SVG binary assets.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan publication resolution is malformed or stale.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('WordPress site plan publication timestamp is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan quality is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan reference asset and write do not match.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan reference capability semantics are invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan reporting metric is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan reporting summary is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan requires a compiled-site report.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan requires a versioned editability policy.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolution is malformed or fabricated.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolved metadata URL is missing, stale, or tampered.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolved metadata declaration is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolved navigation content is not canonical.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolved write payload is not canonical.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan routes do not match canonical page routes.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan runtime entity records are not canonically normalized.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan runtime records are not canonically normalized.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan source document catalog is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan source document catalog must be sorted.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan source document summaries do not match materialized documents.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan source document summary is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan source identity is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan style.css scaffold is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan synthetic route source collides with a document.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy archive is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan native archive must name a captured source without a materialized page.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy entity count exceeds its bound.')": {"class": "operational", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy entity is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy slug does not match its archive route.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy parent is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy parent is not a proven immediate ancestor.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan hierarchical category lacks its parent.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan native archive entity lacks its source-owned archive template.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy evidence is incomplete.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy membership does not name a canonical post.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan taxonomy membership list is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan template is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan template lacks its canonical write.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan template part binding is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan template part has a stale content hash.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan template part identity is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan template part lacks its canonical write.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan template part placement is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan theme is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan theme.json is not valid JSON.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan theme.json scaffold is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan theme.json shape is unsupported.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan webfont SVG consumer is detached from canonical assets or writes.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan write has a stale payload hash or invalid structure.')": {"class": "integrity", "count": 2}, - "InvalidArgumentException('WordPress site plan write has an invalid payload reference.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan write has invalid base64 payload.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException(mb_strcut($message,0,256,'UTF-8'))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('Compiled site asset %s lacks a materializable payload.',$asset['source_path']))": {"class": "representability", "count": 1, "unit": "asset", "finding": "wordpress_site_plan_missing_local_media", "pending": true}, - "InvalidArgumentException(sprintf('WordPress site plan %s must be an array.',$key))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('WordPress site plan has colliding page routes: %s and %s both declare %s.',$taken[$path],(string)$documents[$order]['source_path'],$path))": {"class": "representability", "count": 1, "unit": "route", "finding": "wordpress_site_plan_colliding_page_route", "pending": true}, - "InvalidArgumentException(sprintf('WordPress site plan has colliding page routes: %s and %s both resolve to %s.',$routePaths[$page['route']['path']],(string)$page['source_path'],(string)$page['route']['path']))": {"class": "integrity", "count": 1}, - "InvalidArgumentException(sprintf('WordPress site plan has colliding page routes: %s and %s both resolve to %s.',(string)($pages[$byRoute[$path]]['source_path']??''),(string)$page['source_path'],$path))": {"class": "integrity", "count": 1}, - "ValidationException(\"WordPress site plan {$label} is invalid: {$reason}.\")": {"class": "integrity", "count": 1}, - "ValidationException('A declared template surface must have coherent versioned identity and declaration provenance.')": {"class": "integrity", "count": 1}, - "ValidationException('A declared template surface source provenance is detached from its selected source.')": {"class": "integrity", "count": 1}, - "ValidationException('A declared template surface variant provenance is detached from its source.')": {"class": "integrity", "count": 1}, - "ValidationException('Declared template surface variants have different block markup.')": {"class": "integrity", "count": 1}, - "ValidationException(sprintf('WordPress site plan contains unresolved local browser reference %s.',$url))": {"class": "integrity", "count": 1, "finding": "wordpress_site_plan_unresolved_navigation_link", "test": "tests/contract/relative-form-action.php"}, - "invalidDeclaration('head script declaration','head',$index,$sourcePath,$documentKind,'unbound_script_loading_contract',$element)": {"class": "integrity", "count": 1}, - "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'invalid_order',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'invalid_placement',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'invalid_structure',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'unresolved_local_url',$row)": {"class": "integrity", "count": 1, "finding": "wordpress_site_plan_omitted_link_declaration", "test": "tests/contract/unresolved-local-head-links.php"}, - "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'unsupported_field',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'invalid_order',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'invalid_placement',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'invalid_structure',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'unsupported_field',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_loading_semantics',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_order',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_placement',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_structure',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_supersession_metadata',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'undeclared_asset_token',$row)": {"class": "integrity", "count": 1}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'unresolved_local_url',$row)": {"class": "representability", "count": 1, "unit": "item", "finding": "wordpress_site_plan_script_url_unsupported", "pending": true}, - "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'unsupported_field',$row)": {"class": "integrity", "count": 1}, - "unique($assetIdentities,$asset['reconciliation_identity'],'asset reconciliation identity')": {"class": "integrity", "count": 1}, - "unique($assetTargets,$asset['target_path'],'asset target',(string)$asset['source_path'])": {"class": "integrity", "count": 1, "finding": "wordpress_site_plan_colliding_asset_target", "test": "tests/contract/colliding-asset-targets.php"}, - "unique($documentIdentities,$page['reconciliation_identity'],'page reconciliation identity')": {"class": "integrity", "count": 1}, - "unique($memberSet,$sourcePath,'taxonomy membership')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan fallback archive must not have a per-entity template.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan author archive is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan author entity count or list is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan author entity is structurally invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan author evidence is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan author membership list is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan author membership must be sorted.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan author membership must name a canonical post.')": {"class": "integrity", "count": 1}, - "unique($slugs,$entity['slug'],'author nicename')": {"class": "integrity", "count": 1}, - "unique($claimed,$source,'post author membership')": {"class": "integrity", "count": 1}, - "unique($pagePaths,$page['source_path'],'page source')": {"class": "integrity", "count": 1}, - "unique($partSlugs,$part['slug'],'template part slug')": {"class": "integrity", "count": 1}, - "unique($routeSources,$route['source_path'],'route source')": {"class": "integrity", "count": 1}, - "unique($seen,$entity['taxonomy'].':'.$entity['slug'],'taxonomy term')": {"class": "integrity", "count": 1}, - "unique($sources,$document['source_path'],'source document')": {"class": "integrity", "count": 1}, - "unique($templateTargets,$template['target_path'],'template target')": {"class": "integrity", "count": 1}, - "unique($tokens,$reference['token'],'reference token')": {"class": "integrity", "count": 1}, - "unique($writeTargets,$write['target_path'],'write target',(string)($write['source_path']??''))": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset consumers or destination are stale.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('WordPress site plan page override must resolve to a materialized page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan synthetic parent must have a materialized child.')": { + "class": "integrity", + "count": 1 + }, + "DocumentIdentityException($failures)": { + "class": "integrity", + "count": 1 + }, + "DocumentIdentityException($identityFailures)": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"WordPress site plan resolved {$kind} payload is not canonical.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"WordPress site plan {$kind} has invalid {$field}.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"WordPress site plan {$kind} is structurally invalid.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"WordPress site plan {$kind} lacks {$field}.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(\"WordPress site plan {$kind} must be an array.\")": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A declared template surface collides with a generated template.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A global asset scope cannot declare page fields.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A page asset scope does not match its canonical page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A page asset scope is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A page-owned compiled asset must resolve to a canonical page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A provider script supersession proof does not match its source inline-script asset and document metadata.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A provider script supersession proof is malformed or detached from its bound form.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A runtime entity binding has ambiguous canonical source-page anchors.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('A runtime entity binding has an invalid emitted block position.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A runtime entity binding lacks an exact emitted block anchor.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A runtime entity binding no longer has its declared source document block anchor after shell extraction: '.(is_string($source)?$source:'unknown').' ('.(is_string($binding['role']??null)?$binding['role']:'unknown').').')": { + "class": "integrity", + "count": 1, + "finding": "runtime_entity_binding_unanchored", + "test": "tests/contract/unanchored-runtime-entity-binding.php" + }, + "InvalidArgumentException('A runtime entity binding no longer identifies an emitted canonical block.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A runtime entity binding no longer identifies one exact emitted canonical block.')": { + "class": "integrity", + "count": 3 + }, + "InvalidArgumentException('A runtime entity binding resolved to empty canonical block markup.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A runtime entity binding source anchor is ambiguous after reprojection.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('A native archive template collides with a declared template.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication SVG payload is unsafe.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication declaration does not match its declared source asset hashes or provenance.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication declaration does not resolve to its declared asset write.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication declaration reference context does not match its CSS token occurrence.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication declaration references an unbound destination token occurrence.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('Asset publication plain source hash must match its canonical payload.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication references an undeclared asset.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication requires a sanitized SVG source.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation CSS has duplicate properties.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation CSS input has no local font-face payload.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation CSS property is not allowed.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation CSS source is not a declared font asset.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation CSS source must be a local font path.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation CSS value is not safe.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation content hash does not match its declaration.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation final hash is contradictory.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation font-face is incomplete.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation has an unbound CSS input.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation has an unbound font input.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation inputs do not match their declared hash.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation inputs have stale hashes.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation references an undeclared local CSS input.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation references an undeclared local font input.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation rejects unsafe or non-font CSS inputs.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication transformation requires a sanitized SVG source.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Compiled site asset lacks a safe source identity.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Compiled site asset lacks a safe target identity.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('Compiled site assets must be an array.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Compiled site document is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Compiled site document is outside the entrypoint content root.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Compiled site documents must be an array.')": { + "class": "integrity", + "count": 4 + }, + "InvalidArgumentException('Compiled site route source is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Compiled site source document catalog entry is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Only stylesheet assets may declare runtime scopes.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Only stylesheet resources may declare ordered instances.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Stylesheet assets must declare a supported target.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Stylesheet instance must identify a canonical document, order and conditions.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Two stylesheet instances claim one document position.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Whole-page candidate must name one canonical source page and producer entity row.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Whole-page candidates are stale, duplicated, or detached from their canonical source pages.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Whole-page candidates must be unique by source page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan asset is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan asset lacks a write.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan asset scope is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan asset scopes must be a nonempty array.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan binary write cannot carry a resolution projection.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan contains an undeclared reference token.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan content decision evidence is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan structured page evidence is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan content decision is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan content decision provenance is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan content decision timestamp is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan create_page operation is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan declared template surface is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan diagnostic linkage is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan diagnostics are not linked to reporting.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan document canvas is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan document metadata is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan external metadata URL must not carry a resolved alias.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan font materialization is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan functions.php bootstrap is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan has an invalid reference token declaration.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan has an unproven template part binding.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan has an unsafe explicit page route.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan has an unsupported schema.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan identity is missing, malformed, or stale.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan must declare exactly one token for each asset.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan must export every canonical page route.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan operation is invalid.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('WordPress site plan operation references an invalid front page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan operations are incomplete.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan page has a stale content hash.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan page lacks a canonical route.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan page route is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan page routes reject encoded path separators and dot segments.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan payload references are limited to non-SVG binary assets.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan publication resolution is malformed or stale.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('WordPress site plan publication timestamp is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan quality is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan reference asset and write do not match.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan reference capability semantics are invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan reporting metric is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan reporting summary is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan requires a compiled-site report.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan requires a versioned editability policy.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolution is malformed or fabricated.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolved metadata URL is missing, stale, or tampered.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolved metadata declaration is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolved navigation content is not canonical.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolved write payload is not canonical.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan routes do not match canonical page routes.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan runtime entity records are not canonically normalized.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan runtime records are not canonically normalized.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan source document catalog is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan source document catalog must be sorted.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan source document summaries do not match materialized documents.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan source document summary is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan source identity is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan style.css scaffold is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan synthetic route source collides with a document.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy archive is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan native archive must name a captured source without a materialized page.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy entity count exceeds its bound.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy entity is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy slug does not match its archive route.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy parent is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy parent is not a proven immediate ancestor.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan hierarchical category lacks its parent.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan native archive entity lacks its source-owned archive template.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy evidence is incomplete.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy membership does not name a canonical post.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan taxonomy membership list is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan template is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan template lacks its canonical write.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan template part binding is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan template part has a stale content hash.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan template part identity is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan template part lacks its canonical write.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan template part placement is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan theme is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan theme.json is not valid JSON.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan theme.json scaffold is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan theme.json shape is unsupported.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan webfont SVG consumer is detached from canonical assets or writes.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan write has a stale payload hash or invalid structure.')": { + "class": "integrity", + "count": 2 + }, + "InvalidArgumentException('WordPress site plan write has an invalid payload reference.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan write has invalid base64 payload.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(mb_strcut($message,0,256,'UTF-8'))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('Compiled site asset %s lacks a materializable payload.',$asset['source_path']))": { + "class": "representability", + "count": 1, + "unit": "asset", + "finding": "wordpress_site_plan_missing_local_media", + "pending": true + }, + "InvalidArgumentException(sprintf('WordPress site plan %s must be an array.',$key))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('WordPress site plan has colliding page routes: %s and %s both declare %s.',$taken[$path],(string)$documents[$order]['source_path'],$path))": { + "class": "representability", + "count": 1, + "unit": "route", + "finding": "wordpress_site_plan_colliding_page_route", + "pending": true + }, + "InvalidArgumentException(sprintf('WordPress site plan has colliding page routes: %s and %s both resolve to %s.',$routePaths[$page['route']['path']],(string)$page['source_path'],(string)$page['route']['path']))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException(sprintf('WordPress site plan has colliding page routes: %s and %s both resolve to %s.',(string)($pages[$byRoute[$path]]['source_path']??''),(string)$page['source_path'],$path))": { + "class": "integrity", + "count": 1 + }, + "ValidationException(\"WordPress site plan {$label} is invalid: {$reason}.\")": { + "class": "integrity", + "count": 1 + }, + "ValidationException('A declared template surface must have coherent versioned identity and declaration provenance.')": { + "class": "integrity", + "count": 1 + }, + "ValidationException('A declared template surface source provenance is detached from its selected source.')": { + "class": "integrity", + "count": 1 + }, + "ValidationException('A declared template surface variant provenance is detached from its source.')": { + "class": "integrity", + "count": 1 + }, + "ValidationException('Declared template surface variants have different block markup.')": { + "class": "integrity", + "count": 1 + }, + "ValidationException(sprintf('WordPress site plan contains unresolved local browser reference %s.',$url))": { + "class": "integrity", + "count": 1, + "finding": "wordpress_site_plan_unresolved_navigation_link", + "test": "tests/contract/relative-form-action.php" + }, + "invalidDeclaration('head script declaration','head',$index,$sourcePath,$documentKind,'unbound_script_loading_contract',$element)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'invalid_order',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'invalid_placement',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'invalid_structure',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'unresolved_local_url',$row)": { + "class": "integrity", + "count": 1, + "finding": "wordpress_site_plan_omitted_link_declaration", + "test": "tests/contract/unresolved-local-head-links.php" + }, + "invalidDeclaration('link declaration','link',$index,$sourcePath,$documentKind,'unsupported_field',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'invalid_order',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'invalid_placement',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'invalid_structure',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('meta declaration','meta',$index,$sourcePath,$documentKind,'unsupported_field',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_loading_semantics',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_order',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_placement',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_structure',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'invalid_supersession_metadata',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'undeclared_asset_token',$row)": { + "class": "integrity", + "count": 1 + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'unresolved_local_url',$row)": { + "class": "representability", + "count": 1, + "unit": "item", + "finding": "wordpress_site_plan_script_url_unsupported", + "pending": true + }, + "invalidDeclaration('script declaration','script',$index,$sourcePath,$documentKind,'unsupported_field',$row)": { + "class": "integrity", + "count": 1 + }, + "unique($assetIdentities,$asset['reconciliation_identity'],'asset reconciliation identity')": { + "class": "integrity", + "count": 1 + }, + "unique($assetTargets,$asset['target_path'],'asset target',(string)$asset['source_path'])": { + "class": "integrity", + "count": 1, + "finding": "wordpress_site_plan_colliding_asset_target", + "test": "tests/contract/colliding-asset-targets.php" + }, + "unique($documentIdentities,$page['reconciliation_identity'],'page reconciliation identity')": { + "class": "integrity", + "count": 1 + }, + "unique($memberSet,$sourcePath,'taxonomy membership')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan fallback archive must not have a per-entity template.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan author archive is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan author entity count or list is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan author entity is structurally invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan author evidence is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan author membership list is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan author membership must be sorted.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan author membership must name a canonical post.')": { + "class": "integrity", + "count": 1 + }, + "unique($slugs,$entity['slug'],'author nicename')": { + "class": "integrity", + "count": 1 + }, + "unique($claimed,$source,'post author membership')": { + "class": "integrity", + "count": 1 + }, + "unique($pagePaths,$page['source_path'],'page source')": { + "class": "integrity", + "count": 1 + }, + "unique($partSlugs,$part['slug'],'template part slug')": { + "class": "integrity", + "count": 1 + }, + "unique($routeSources,$route['source_path'],'route source')": { + "class": "integrity", + "count": 1 + }, + "unique($seen,$entity['taxonomy'].':'.$entity['slug'],'taxonomy term')": { + "class": "integrity", + "count": 1 + }, + "unique($sources,$document['source_path'],'source document')": { + "class": "integrity", + "count": 1 + }, + "unique($templateTargets,$template['target_path'],'template target')": { + "class": "integrity", + "count": 1 + }, + "unique($tokens,$reference['token'],'reference token')": { + "class": "integrity", + "count": 1 + }, + "unique($writeTargets,$write['target_path'],'write target',(string)($write['source_path']??''))": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset consumers or destination are stale.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPressSitePlan/WordPressSitePlanResolver.php": { - "InvalidArgumentException('Attachment resolutions must be a token map.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Invalid attachment resolution or non-media asset token.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('Asset publication reference token is not declared.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan cannot prove dynamic client asset references.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan contains unresolved reference tokens.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan does not match the externally approved plan identity.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan identity is stale.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan is already a resolved projection.')": {"class": "programmer", "count": 1}, - "InvalidArgumentException('WordPress site plan requires an unsupported runtime capability.')": {"class": "operational", "count": 1}, - "InvalidArgumentException('WordPress site plan resolution requires a valid theme_uri.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolution requires an absolute http(s) theme_uri without credentials, query, or fragment.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolution theme_uri has an ambiguous path.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan resolution theme_uri has an invalid port.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan runtime binding cannot be resolved from its canonical source document anchor.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan runtime binding resolved anchor is detached from its source document.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan runtime capabilities must be a unique bounded list.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('Attachment resolutions must be a token map.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Invalid attachment resolution or non-media asset token.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('Asset publication reference token is not declared.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan cannot prove dynamic client asset references.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan contains unresolved reference tokens.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan does not match the externally approved plan identity.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan identity is stale.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan is already a resolved projection.')": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan requires an unsupported runtime capability.')": { + "class": "operational", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolution requires a valid theme_uri.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolution requires an absolute http(s) theme_uri without credentials, query, or fragment.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolution theme_uri has an ambiguous path.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan resolution theme_uri has an invalid port.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan runtime binding cannot be resolved from its canonical source document anchor.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan runtime binding resolved anchor is detached from its source document.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan runtime capabilities must be a unique bounded list.')": { + "class": "integrity", + "count": 1 + } }, "src/WordPressSitePlan/WordPressSitePlanView.php": { - "InvalidArgumentException('WordPress site plan view compaction requires the canonical v1 view.')": {"class": "programmer", "count": 1}, - "InvalidArgumentException('WordPress site plan view has an invalid canonical plan.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan view materialization requires the compact v2 view.')": {"class": "programmer", "count": 1}, - "InvalidArgumentException('WordPress site plan view payload is invalid.')": {"class": "integrity", "count": 1}, - "InvalidArgumentException('WordPress site plan view payload transport is invalid.')": {"class": "integrity", "count": 1} + "InvalidArgumentException('WordPress site plan view compaction requires the canonical v1 view.')": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan view has an invalid canonical plan.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan view materialization requires the compact v2 view.')": { + "class": "programmer", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan view payload is invalid.')": { + "class": "integrity", + "count": 1 + }, + "InvalidArgumentException('WordPress site plan view payload transport is invalid.')": { + "class": "integrity", + "count": 1 + } + }, + "src/HtmlToBlocks/Style/CoreSelectorScoping.php": { + "RuntimeException(sprintf(\"Emitted CSS targets a core block class without an importer-emitted class in the selector chain (origin: %s):\\n - %s\",$origin,implode(\"\\n - \",$violations)))": { + "class": "integrity", + "count": 1 + } } } } diff --git a/php-transformer/tests/contract/run.php b/php-transformer/tests/contract/run.php index 858fef218..71b0dd6ce 100644 --- a/php-transformer/tests/contract/run.php +++ b/php-transformer/tests/contract/run.php @@ -915,12 +915,12 @@ public function recognize(DOMElement $element, PatternContext $context): ?Patter $assert(str_contains((string) ($socialLinksBlock['attrs']['className'] ?? ''), 'blocks-engine-source-social-item-spacing'), 'structural social items mark the wrapper so source item spacing remains authoritative'); $socialLinksCss = implode("\n", array_column($socialLinksResult['assets'] ?? array(), 'content')); $assert(str_contains($socialLinksCss, '.wp-block-social-links.blocks-engine-source-social-item-spacing{gap:0}'), 'engine support CSS neutralizes the core default gap without adding invalid saved styles'); -$assert(str_contains($socialLinksCss, '.wp-block-social-links.is-style-logos-only .wp-social-link{background-image:none;background-color:transparent}'), 'logos-only social links drop source sprite backgrounds without !important'); +$assert(str_contains($socialLinksCss, '.wp-block-social-links.blocks-engine-social-source-cluster.is-style-logos-only .wp-social-link{background-image:none;background-color:transparent}'), 'logos-only social links drop source sprite backgrounds without !important'); $assert(! str_contains($socialLinksMarkup, 'style="gap:') && ! str_contains($socialLinksMarkup, '
  • transform('')->toArray(); -$assert(str_contains((string) ($visibleSocialLabels['serialized_blocks'] ?? ''), 'class="wp-block-social-links has-visible-labels social-links"'), 'social-links save markup carries the canonical has-visible-labels class when labels are shown'); +$assert(str_contains((string) ($visibleSocialLabels['serialized_blocks'] ?? ''), 'class="wp-block-social-links blocks-engine-social-source-cluster has-visible-labels social-links"'), 'social-links save markup carries the canonical has-visible-labels class when labels are shown'); $spanSocialSource = ''; $spanSocialResult = ( new HtmlTransformer() )->transform($spanSocialSource)->toArray(); @@ -2830,7 +2830,7 @@ public function recognize(DOMElement $element, PatternContext $context): ?Patter $syntaxCodeCss = implode("\n", array_column($syntaxCodeResult['assets'] ?? array(), 'content')); $assert(str_contains($syntaxCodeMarkup, '# npm') && str_contains($syntaxCodeMarkup, 'install'), 'core code preserves sanitized syntax-token markup'); $assert(str_contains($syntaxCodeCss, '.token.comment{color:#8ea0c8}') && str_contains($syntaxCodeCss, '.token.function{color:#7dd3fc}'), 'syntax-token selectors remain targeted at their preserved core code descendants'); -$assert(1 === preg_match('/code:not\(\.be-c-[^)]+\)\{/', $syntaxCodeCss) && str_contains($syntaxCodeCss, ':where(.wp-block-code)>code{display:inline;overflow-wrap:normal;text-align:inherit;white-space:inherit;direction:inherit}'), 'native code keeps source inline preformatted geometry and authored code typography precedence'); +$assert(1 === preg_match('/code:not\(\.be-c-[^)]+\)\{/', $syntaxCodeCss) && str_contains($syntaxCodeCss, ':where(.blocks-engine-source-code)>code{display:inline;overflow-wrap:normal;text-align:inherit;white-space:inherit;direction:inherit}'), 'native code keeps source inline preformatted geometry and authored code typography precedence'); $assert('pass' === ($syntaxCodeResult['source_reports']['wp_block_validity']['status'] ?? ''), 'syntax-token core code remains editor-valid'); $linkedLogoResult = ( new HtmlTransformer() )->transform( @@ -3852,7 +3852,7 @@ public function recognize(DOMElement $element, PatternContext $context): ?Patter $assert(str_contains((string) ($centeredSocialLinks['serialized_blocks'] ?? ''), '"justifyContent":"center"'), 'social links inherit explicit alignment from their source wrapper'); $assert(str_contains((string) ($centeredSocialLinks['serialized_blocks'] ?? ''), 'is-content-justification-center'), 'social link justification is present in rendered save markup'); $centeredSocialLinksCss = implode("\n", array_column($centeredSocialLinks['assets'] ?? array(), 'content')); -$assert(str_contains($centeredSocialLinksCss, '.wp-block-social-links.is-content-justification-center{justify-content:center}'), 'social link justification renders without depending on theme block CSS'); +$assert(str_contains($centeredSocialLinksCss, '.wp-block-social-links.blocks-engine-social-source-cluster.is-content-justification-center{justify-content:center}'), 'social link justification renders without depending on theme block CSS'); $deduplicatedNestedNavigation = ( new HtmlTransformer() )->transform( '

    Services

    Copy

    ' From 162dae481cc81d57533cdda15c448ff4f90f05d5 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Thu, 29 Oct 2026 18:13:12 -0400 Subject: [PATCH 2/4] Preserve image cascade while scoping core selectors --- .../ArtifactCompiler/WordPressCompatCss.php | 15 ++++++ .../src/HtmlToBlocks/BlockFactory.php | 3 ++ .../src/HtmlToBlocks/HtmlCompilation.php | 9 +--- .../Style/AuthorSelectorSemanticPreparer.php | 53 ------------------- .../Style/AuthorStylesheetProjector.php | 16 ++++-- .../core-code-literal-markup-text.php | 2 +- .../contract/core-code-save-supports.php | 11 ++-- php-transformer/tests/contract/run.php | 4 +- .../contract/source-responsive-cascade.php | 17 ++++++ .../parity/html-expanded-gap-primitives.json | 2 +- .../parity/html-figure-quote-media.json | 4 +- ...ed-fill-image-percentage-height-chain.json | 2 +- ...oduct-grid-catalog-image-without-cart.json | 10 ++-- .../tests/unit/engine-support-css-asset.php | 4 +- .../unit/linked-image-whitespace-gap.php | 2 +- .../tests/unit/media-text-pattern.php | 2 +- .../tests/unit/wordpress-70-save-shapes.php | 8 ++- 17 files changed, 78 insertions(+), 86 deletions(-) diff --git a/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php b/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php index 2f7276fe8..daa28de88 100644 --- a/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php +++ b/php-transformer/src/ArtifactCompiler/WordPressCompatCss.php @@ -116,6 +116,21 @@ private function siteMarker(string $kind, string $css, array $htmlTexts): string public function asset(array $files, string $staticCss, array $scriptContents): ?array { $css = trim($this->css($staticCss, $files, $scriptContents)); + // ID-only source navigation has no copied author class to scope its + // runtime replay. Both native navigation routes already stamp these + // importer classes; a weightless gate preserves the source cascade. + $css = (new CssStylesheetTransformer())->transform($css, static function (string $prelude): string { + $selectors = CssStylesheetTransformer::splitSelectorList($prelude); + if ( null === $selectors ) { + return $prelude; + } + foreach ( $selectors as &$selector ) { + if ( ! (new CoreSelectorScoping())->selectorIsScoped($selector) ) { + $selector = preg_replace('/\.wp-block-navigation(?![\w-])/', '.wp-block-navigation:where(.blocks-engine-list-navigation,.blocks-engine-direct-navigation)', $selector) ?? $selector; + } + } + return implode(',', $selectors); + }); if ( '' === $css ) { return null; } diff --git a/php-transformer/src/HtmlToBlocks/BlockFactory.php b/php-transformer/src/HtmlToBlocks/BlockFactory.php index ef206fbe4..01b794c05 100644 --- a/php-transformer/src/HtmlToBlocks/BlockFactory.php +++ b/php-transformer/src/HtmlToBlocks/BlockFactory.php @@ -791,6 +791,9 @@ private function tableHtml(array $attrs): string private function imageHtml(array $attrs): string { $figureAttrs = $attrs; + // A scope key only: unlike semantic markers, this must not change + // which source box owns an author's image declarations. + $figureAttrs['className'] = SourceDom::mergeClassNames((string) ($figureAttrs['className'] ?? ''), 'blocks-engine-image'); $baseClass = 'wp-block-image'; $border = is_array($attrs['style']['border'] ?? null) ? $attrs['style']['border'] : array(); $borderSupport = $this->styleSupport(array( 'border' => $border )); diff --git a/php-transformer/src/HtmlToBlocks/HtmlCompilation.php b/php-transformer/src/HtmlToBlocks/HtmlCompilation.php index b1a8928ee..e382bfaad 100644 --- a/php-transformer/src/HtmlToBlocks/HtmlCompilation.php +++ b/php-transformer/src/HtmlToBlocks/HtmlCompilation.php @@ -11905,13 +11905,8 @@ private function imagePresentationAttributes(DOMElement $image, ?DOMElement $fig // Separate source boxes must keep separate selector ownership. Only // inert identities retain the historical class transport. $styledLeaf = $this->imageNeedsSeparateFigureBox($image, $figure); - // A marker allocated by author-selector discovery (an image named - // by a selector with no class of its own) must reach the markup so - // the projection's bridge arms stay bound. - $marker = $styledLeaf - ? $this->session->authorSelectorProjectionState()->ensureImageWrapperMarker($image->getNodePath() ?? '') - : $this->session->authorSelectorProjectionState()->imageWrapperMarker($image->getNodePath() ?? ''); - $attrs['className'] = $this->mergeClassNames((string) ($attrs['className'] ?? ''), $this->nonCoreImageFigureClassName($figure), '' !== $marker ? $marker : $this->nonCoreImageClassName($image), ...$this->authorSemanticMarkersForElement($image)); + $marker = $styledLeaf ? $this->session->authorSelectorProjectionState()->ensureImageWrapperMarker($image->getNodePath() ?? '') : ''; + $attrs['className'] = $this->mergeClassNames((string) ($attrs['className'] ?? ''), $this->nonCoreImageFigureClassName($figure), $styledLeaf ? $marker : $this->nonCoreImageClassName($image), ...$this->authorSemanticMarkersForElement($image)); } else { $attrs['className'] = $this->styleResolver->mergePresentationClassNames((string) ($attrs['className'] ?? ''), $this->styleResolver->injectedFigureHeightClassName($image)); } diff --git a/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php b/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php index e002df53b..f6de3c04f 100644 --- a/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php +++ b/php-transformer/src/HtmlToBlocks/Style/AuthorSelectorSemanticPreparer.php @@ -77,7 +77,6 @@ public function prepare( $projections->ensureTagMarker($tagName); } $this->discoverAuthorControlPaths($authorSelectors, $authorStyles, $projections); - $this->discoverAuthorImageIdentityPaths($authorSelectors, $authorStyles, $projections); $applicableAuthorStyleRules = array(); foreach ( $authorStyleRules as $rule ) { $rule['selectors'] = array_values(array_filter( @@ -184,58 +183,6 @@ private function discoverAuthorControlPaths(array $authorSelectors, AuthorStyleA } } - /** @param list}> $authorSelectors */ - /** - * An author selector that names an image without any class of its own — - * by bare element type (`p img`, `figure img`, `img`), by an id, or via - * core block classes — projects onto the generated figure's core class. - * Its bridge arms key on the per-image wrapper marker, so allocate one - * for every matched image up front: the markup carries it on the - * generated figure and the projection scopes each arm with it instead of - * falling back to a selector that stands on the bare core class alone. - * - * Selectors that already name a non-core class keep the ancestor-scoped - * bridge, which is copied onto the emitted markup unchanged. - * - * @param list}> $authorSelectors - */ - private function discoverAuthorImageIdentityPaths(array $authorSelectors, AuthorStyleAnalysis $authorStyles, AuthorSelectorProjectionState $projections): void - { - foreach ( $authorSelectors as $authorSelector ) { - $parsed = $authorSelector['parsed']; - if ( ! $parsed['supported'] ) { - continue; - } - if ( self::selectorCarriesNonCoreClass($authorSelector['selector']) ) { - continue; - } - foreach ( $this->matchingSourceElements($authorStyles, $authorSelector['selector'], $parsed) as $element ) { - if ( 'img' !== strtolower($element->tagName) ) { - continue; - } - $path = $element->getNodePath() ?? ''; - if ( '' === $path ) { - continue; - } - $projections->ensureImageWrapperMarker($path); - } - } - } - - /** Whether any class token in the selector is outside core's block families. */ - private static function selectorCarriesNonCoreClass(string $selector): bool - { - if ( ! preg_match_all('/\\.((?:\\\\.|[^\x00-\x7f]|[^\s.#:>+~,\[\]()\'"\\\\])+)/', $selector, $matches) ) { - return false; - } - foreach ( $matches[1] as $class ) { - if ( ! preg_match('/^(?:wp-block-|has-)/', str_replace('\\', '', $class)) ) { - return true; - } - } - return false; - } - /** @param list}> $authorSelectors */ private function discoverAuthorInlineSemanticPaths(array $authorSelectors, AuthorStyleAnalysis $authorStyles, AuthorSelectorProjectionState $projections): void { diff --git a/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php b/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php index 649cf877c..f756d4a5b 100644 --- a/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php +++ b/php-transformer/src/HtmlToBlocks/Style/AuthorStylesheetProjector.php @@ -2663,8 +2663,8 @@ private function projectAuthorImageSelectorPrelude(string $prelude, AuthorStyles * Emits a projected image-rule arm only when every core block class it * names is reached through an importer-emitted class as well. An arm that * would stand on the bare core class is dropped and recorded instead of - * leaking onto blocks a host adds to the served page later; discovery - * marks matched images so the scoped marker arm carries the rule instead. + * leaking onto blocks a host adds to the served page later. Ordinary + * image arms carry a zero-specificity factory scope, not a semantic marker. * * @param list $projected */ @@ -3435,7 +3435,17 @@ private function projectImageSelector(string $selector, array $parsed, AuthorSty ); } } - $projected[] = $this->replaceSelectorSpans($selector, $replacements); + $arm = $this->replaceSelectorSpans($selector, $replacements); + if ( ! (new CoreSelectorScoping())->selectorIsScoped($arm) ) { + // The factory class is only a scope key, never a semantic + // subject. Replacing * with :where() keeps its zero weight + // and leaves the declaration on the same native image leaf. + $arm = str_replace('*.wp-block-image', ':where(.blocks-engine-image).wp-block-image', $arm); + if ( ! (new CoreSelectorScoping())->selectorIsScoped($arm) ) { + $arm = str_replace('.wp-block-image', ':where(.blocks-engine-image).wp-block-image', $arm); + } + } + $projected[] = $arm; } return implode(',', $projected); } diff --git a/php-transformer/tests/contract/core-code-literal-markup-text.php b/php-transformer/tests/contract/core-code-literal-markup-text.php index f5efcf2c5..33c644293 100644 --- a/php-transformer/tests/contract/core-code-literal-markup-text.php +++ b/php-transformer/tests/contract/core-code-literal-markup-text.php @@ -85,7 +85,7 @@ // Plain code without markup in its text keeps the byte-identical saved shape. $plain = ( new HtmlTransformer() )->transform('
    if (a < b && c > d) { run("x"); }
    ')->toArray(); $assert( - '
    if (a < b && c > d) { run("x"); }
    ' === (string) ($plain['blocks'][0]['innerHTML'] ?? ''), + '
    if (a < b && c > d) { run("x"); }
    ' === (string) ($plain['blocks'][0]['innerHTML'] ?? ''), 'plain code keeps its exact saved markup', (string) ($plain['blocks'][0]['innerHTML'] ?? '') ); diff --git a/php-transformer/tests/contract/core-code-save-supports.php b/php-transformer/tests/contract/core-code-save-supports.php index 7cf76dd1a..7cbddfd18 100644 --- a/php-transformer/tests/contract/core-code-save-supports.php +++ b/php-transformer/tests/contract/core-code-save-supports.php @@ -63,7 +63,7 @@ (string) json_encode($code['attrs'] ?? array()) ); $assert( - str_starts_with($wrapper, '
    ')
    +    str_starts_with($wrapper, '
    ')
             && str_ends_with($wrapper, '
    '), 'the saved wrapper serializes the generated class, support classes, projected class, and inline support style the canonical native serializer emits everywhere else', $wrapper @@ -101,17 +101,16 @@ $assert( 'core/code' === ($parsedCode['blockName'] ?? '') && 'prompt-code' === ($parsedCode['attrs']['className'] ?? '') - && str_contains((string) ($parsedCode['innerHTML'] ?? ''), 'has-text-color has-background has-border-color prompt-code'), + && str_contains((string) ($parsedCode['innerHTML'] ?? ''), 'has-text-color has-background has-border-color blocks-engine-source-code prompt-code'), 'parsing the saved markup restores the block comment supports and the serialized wrapper verbatim', (string) json_encode(array($parsedCode['attrs'] ?? array(), $parsedCode['innerHTML'] ?? '')) ); -// An unstyled code block keeps the byte-identical canonical shape core saves -// with no supports, so the repair changes nothing for plain markup. +// An unstyled code block keeps the canonical shape plus the importer scope. $plain = ( new HtmlTransformer() )->transform('
    plain code
    ')->toArray(); $assert( - '
    plain code
    ' === (string) (($plain['blocks'][0]['innerHTML'] ?? '')), - 'an unstyled code block keeps the exact canonical wrapper core save() emits without supports', + '
    plain code
    ' === (string) (($plain['blocks'][0]['innerHTML'] ?? '')), + 'an unstyled code block keeps the canonical wrapper with its importer scope', (string) ($plain['blocks'][0]['innerHTML'] ?? '') ); diff --git a/php-transformer/tests/contract/run.php b/php-transformer/tests/contract/run.php index 71b0dd6ce..05ffe4a58 100644 --- a/php-transformer/tests/contract/run.php +++ b/php-transformer/tests/contract/run.php @@ -3142,7 +3142,7 @@ public function recognize(DOMElement $element, PatternContext $context): ?Patter '
    ' )->toArray(); $emptyCoverCandidateSerialized = (string) ($emptyCoverCandidate['serialized_blocks'] ?? ''); -$expectedEmptyCoverCandidateSerialized = '
    '; +$expectedEmptyCoverCandidateSerialized = '
    '; $assert($expectedEmptyCoverCandidateSerialized === $emptyCoverCandidateSerialized, 'empty background container preserves exact tagged core/image serialization', $emptyCoverCandidateSerialized); $assert('core/image' === ($emptyCoverCandidate['blocks'][0]['innerBlocks'][0]['blockName'] ?? null) && 'blocks-engine-background-image blocks-engine-background-image-cover blocks-engine-synthetic-image-figure' === ($emptyCoverCandidate['blocks'][0]['innerBlocks'][0]['attrs']['className'] ?? null) && ! str_contains($emptyCoverCandidateSerialized, '(.*?)/s', static function (array $m): string { diff --git a/php-transformer/tests/fixtures/parity/html-expanded-gap-primitives.json b/php-transformer/tests/fixtures/parity/html-expanded-gap-primitives.json index a03cc422a..1ae5f6121 100644 --- a/php-transformer/tests/fixtures/parity/html-expanded-gap-primitives.json +++ b/php-transformer/tests/fixtures/parity/html-expanded-gap-primitives.json @@ -50,7 +50,7 @@ { "path": "source_reports.runtime_islands", "assert": "count", "count": 1 }, { "path": "source_reports.runtime_islands.0.kind", "assert": "equals", "value": "script" }, { "path": "source_reports.runtime_islands.0.attributes.src", "assert": "equals", "value": "/widget.js" }, - { "path": "serialized_blocks", "assert": "contains", "value": "
    \"Logo\"
    " }, + { "path": "serialized_blocks", "assert": "contains", "value": "
    \"Logo\"
    " }, { "path": "serialized_blocks", "assert": "contains", "value": "
  • Parent" }, { "path": "serialized_blocks", "assert": "contains", "value": "" }, diff --git a/php-transformer/tests/fixtures/parity/html-figure-quote-media.json b/php-transformer/tests/fixtures/parity/html-figure-quote-media.json index 400adfc72..aff541268 100644 --- a/php-transformer/tests/fixtures/parity/html-figure-quote-media.json +++ b/php-transformer/tests/fixtures/parity/html-figure-quote-media.json @@ -29,8 +29,8 @@ { "path": "serialized_blocks", "assert": "contains", "value": "
    " }, { "path": "serialized_blocks", "assert": "contains", "value": "Ada, Founder
    " }, { "path": "serialized_blocks", "assert": "contains", "value": "

    Pull this.

    Editor
    " }, - { "path": "serialized_blocks", "assert": "contains", "value": "
    \"Photo\"
    Image caption
    " }, - { "path": "serialized_blocks", "assert": "contains", "value": "
    \"Wrapped
    Wrapped caption
    " }, + { "path": "serialized_blocks", "assert": "contains", "value": "
    \"Photo\"
    Image caption
    " }, + { "path": "serialized_blocks", "assert": "contains", "value": "
    \"Wrapped
    Wrapped caption
    " }, { "path": "fallbacks", "assert": "count", "count": 0 }, { "path": "coverage.0.fallback_count", "assert": "equals", "value": 0 } ] diff --git a/php-transformer/tests/fixtures/parity/html-linked-fill-image-percentage-height-chain.json b/php-transformer/tests/fixtures/parity/html-linked-fill-image-percentage-height-chain.json index 0ff201f55..1331815d2 100644 --- a/php-transformer/tests/fixtures/parity/html-linked-fill-image-percentage-height-chain.json +++ b/php-transformer/tests/fixtures/parity/html-linked-fill-image-percentage-height-chain.json @@ -65,7 +65,7 @@ { "path": "serialized_blocks", "assert": "contains", - "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " + "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " }, { "path": "fallbacks.0.products.1.binding.search_block_markup", "assert": "equals", - "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " + "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " }, { "path": "fallbacks.0.products.2.binding.search_block_markup", "assert": "equals", - "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " + "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " }, { "path": "fallbacks.0.products.3.binding.search_block_markup", "assert": "equals", - "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " + "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " }, { "path": "serialized_blocks", "assert": "contains", - "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " + "value": "
    \"Solaris

    Solaris Ring

    $64.99

    \"Prism

    Prism Wave

    $54.99

    \"Green

    Green Pulse

    $29.99

    \"Apex

    Apex Dynamics

    $49.99

    " } ] } diff --git a/php-transformer/tests/unit/engine-support-css-asset.php b/php-transformer/tests/unit/engine-support-css-asset.php index 636a51860..a16fc9e1b 100644 --- a/php-transformer/tests/unit/engine-support-css-asset.php +++ b/php-transformer/tests/unit/engine-support-css-asset.php @@ -191,10 +191,10 @@ 'non-overlay list-navigation transport' => '.wp-block-navigation.blocks-engine-list-navigation:not(.blocks-engine-native-responsive-navigation)>.wp-block-navigation__container{display:contents!important}', 'nativeSearchTriggerCssRules' => 'flex:0 0 24px!important;width:24px!important;height:80px!important', ); -$assert(str_contains((string) ($syntheticImageFigure['serialized_blocks'] ?? ''), '
    Portrait
    '), 'direct source images mark their introduced core/image figure for margin normalization'); +$assert(str_contains((string) ($syntheticImageFigure['serialized_blocks'] ?? ''), '
    Portrait
    '), 'direct source images mark their introduced core/image figure for margin normalization'); $assert(! str_contains((string) ($syntheticImageFigure['serialized_blocks'] ?? ''), 'authored-figure blocks-engine-synthetic-image-figure'), 'authored source figures retain their own spacing contract'); $afterFamilies = array( - 'logos-only social sprite neutralize' => '.wp-block-social-links.is-style-logos-only .wp-social-link{background-image:none;background-color:transparent}', + 'logos-only social sprite neutralize' => '.wp-block-social-links.blocks-engine-social-source-cluster.is-style-logos-only .wp-social-link{background-image:none;background-color:transparent}', 'list-navigation host' => '@media(max-width:599px){.wp-block-navigation.blocks-engine-list-navigation.blocks-engine-native-responsive-navigation{display:flex!important}}', 'native-responsive desktop wrappers' => '.wp-block-navigation__responsive-container:not(.is-menu-open)', 'list-navigation mobile overlay' => '.wp-block-navigation.blocks-engine-list-navigation .wp-block-navigation__responsive-container.is-menu-open{background:rgba(0,0,0,.9)!important}', diff --git a/php-transformer/tests/unit/linked-image-whitespace-gap.php b/php-transformer/tests/unit/linked-image-whitespace-gap.php index 6fc302a14..6347372eb 100644 --- a/php-transformer/tests/unit/linked-image-whitespace-gap.php +++ b/php-transformer/tests/unit/linked-image-whitespace-gap.php @@ -37,7 +37,7 @@ foreach ($site['assets'] as $asset) { if ('css' === $asset['kind']) $css .= $asset['content'] . "\n"; } -if (5 !== substr_count($markup, '