0065: Layout fail gates require conclusive results
Status: accepted (2026-08-09) · Scope: toolkit tier (lib/browser, browse CLI)
Context
Section titled “Context”ADR 0030 kept most layout unknown outcomes as report-only evidence. That
avoided noisy failures from rounded containers and two-item gap checks, but it
also let automation treat an inconclusive check as a pass. One page check
reported 13 unsupported desktop shapes and 14 unsupported mobile shapes while
both commands returned zero. An earlier capture on the same page had reported
24 clipping issues with a worst overrun of 111.9 CSS pixels. A caller that read
only the process status could not distinguish those outcomes from a clean page.
The --check-*-fail flags are used as release gates. A release gate must prove
its condition or stop. JSON still preserves unknown as the measurement
result, but the process status no longer certifies it.
Alternatives considered
Section titled “Alternatives considered”- Keep
unknownreport-only and require callers to parse JSON. Rejected because the fail flags exist so shell scripts and CI do not need a second result parser. - Convert
unknowntofailin the JSON model. Rejected because it would erase the difference between a measured defect and unsupported geometry. - Add another opt-in flag for strict unknown handling. Rejected because a flag
named
--check-*-failshould already fail when the requested check cannot reach a conclusion. - Keep every rounded clipping ancestor as unknown. Rejected because the clipping rule is explicitly rectangular. A normal border radius does not prevent the rule from measuring the ancestor’s rectangular padding box.
Decision
Section titled “Decision”Every enabled layout fail gate now exits 2 when its result is fail, unknown,
or missing. This applies to alignment, gap, clipping, overlap, crowd, and target
size. The JSON outcome remains unchanged. The warning says result unknown, so
callers know why the gate stopped.
The rectangular clipping check no longer marks border-radius as unsupported.
It measures the rounded container by its rectangular padding box. Arbitrary
clip-path, transforms that cannot be certified by axis-aligned geometry,
closed shadow roots, and cross-origin frames remain unknown and therefore
fail an enabled gate.
Two-item gap checks without --check-gap-expected also fail closed. Callers
must provide the intended gap before the check can pass.
Result
Section titled “Result”The layout fixture now proves both sides of the contract. Rounded containers
with visible or clipped overflow return pass when their rectangular bounds
hold. A clip-path fixture remains unknown, and a two-item gap without an
expectation remains unknown; both commands exit 2 when their fail gates are
enabled.
The consumer page that exposed the bug now reports zero unknown shapes at its desktop and mobile viewports. The same command exits 2 against the explicit unknown fixtures.
A follow-up audit found two more ways to produce misleading evidence. Fail flags could be passed without their check flag, which returned zero without placing a result in JSON. The clipping sweep also treated normal vertical font paint and fractional Chromium geometry as defects. The original consumer page accumulated six 27.2px false text leaks from a valid hanging indent.
Fail flags now have one of two explicit behaviors. Whole-document gates enable their measurement, including overflow, runts, content, target size, and critique. Selector-based gates reject a missing selector before Chromium opens; assertion and visual-diff gates likewise require their paired input. Unknown content and skipped critiques fail rather than certifying an incomplete review. Runt results distinguish missing, incomplete, passing, and failing sweeps. Clipping ignores sub-half-pixel rasterization differences and compares ordinary text horizontally to its block owner; vertical glyph overhang is measured only where a real ancestor clips that axis. The full consumer verifier then passed four desktop/mobile and light/dark contexts with zero layout issues.