Grid plan equality guard, named-token px validation, breakpoint-ordered source variants, hidden-text diagnostic

- A grid-cols-N recipe plan may only override the authored template when
  computed tracks are near-equal - asymmetric sidebar templates
  (260px 1fr) keep their authored geometry
- Source-intent named tokens (max-w-md etc.) re-emit only when their
  Tailwind-4 value matches the captured computed px; mismatches (older
  token scales) emit the captured value instead
- Per-axis source-variant selection keeps the highest-min-width active
  variant instead of last-in-class-order, matching real Tailwind cascade
  (lg:grid-cols-3 no longer loses to a later md:grid-cols-2 at desktop) -
  latent since the initial commit
- New non-blocking textHiddenInClone metric in the dom gate: counts
  capture-visible text that renders hidden in the clone, so silent
  disappearances surface in reports

435 tests pass (10 new), typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samraaj Bath
2026-07-04 06:11:14 -07:00
co-authored by Claude Fable 5
parent f16c3aa4e8
commit 5b60ded62d
6 changed files with 384 additions and 7 deletions
+79 -1
View File
@@ -1,6 +1,8 @@
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { letterSpacingEquivalent, normHref } from "../src/validate/gates.js";
import { letterSpacingEquivalent, normHref, countVisibleInCaptureHiddenInClone } from "../src/validate/gates.js";
import type { IR, IRNode } from "../src/normalize/ir.js";
import type { PageSnapshot } from "../src/capture/walker.js";
// FIX 5 — the link gate must not fail a javascript: source href against the clone's sanitized value.
// Generation emits an inert `#` for a `javascript:*` href (React blocks the literal), so normHref
@@ -54,3 +56,79 @@ describe("gate4 letterSpacing normal ↔ 0px normalization", () => {
assert.ok(letterSpacingEquivalent(undefined, "0px"));
});
});
// A capture-visible text node that the clone renders hidden (off-screen-shifted / banded /
// width-frozen subtree) is the emil-banner / maxbo-feed regression class. The diagnostic counts
// DISTINCT source cids whose gen counterpart exists but reports visible:false. Non-blocking; it
// only has to be a faithful, deterministic count.
describe("countVisibleInCaptureHiddenInClone diagnostic", () => {
// Minimal IR text leaf: `text` at every listed vp, visible per `vis`.
const leaf = (id: string, text: string, vis: Record<number, boolean>): IRNode => {
const vps = Object.keys(vis).map(Number);
const rec = <T,>(v: T): Record<number, T> => Object.fromEntries(vps.map((vp) => [vp, v]));
return {
id, tag: "a", attrs: {},
visibleByVp: vis,
bboxByVp: rec({ x: 0, y: 0, width: 100, height: 16 }),
computedByVp: rec({} as Record<string, string>),
children: [{ text }],
} as unknown as IRNode;
};
const makeIR = (leaves: IRNode[]): IR => ({
doc: {} as IR["doc"],
root: { id: "n0", tag: "body", attrs: {}, visibleByVp: {}, bboxByVp: {}, computedByVp: {}, children: leaves } as unknown as IRNode,
});
// Minimal clone snapshot: one node per (cid, visible) with matching direct text.
const snap = (nodes: Array<{ cid: string; text: string; visible: boolean }>): PageSnapshot => ({
root: {
tag: "body", attrs: { "data-cid": "n0" }, computed: {}, bbox: { x: 0, y: 0, width: 100, height: 100 }, visible: true,
children: nodes.map((n) => ({
tag: "a", attrs: { "data-cid": n.cid }, computed: {}, bbox: { x: 0, y: 0, width: 100, height: 16 },
visible: n.visible, children: [{ text: n.text }],
})),
},
} as unknown as PageSnapshot);
it("counts a source-visible text node the clone renders hidden", () => {
const ir = makeIR([leaf("n4", "Enrollment open!", { 375: true })]);
const gen = { 375: snap([{ cid: "n4", text: "Enrollment open!", visible: false }]) };
assert.equal(countVisibleInCaptureHiddenInClone(ir, gen, [375]), 1);
});
it("does NOT count a node visible in both source and clone", () => {
const ir = makeIR([leaf("n4", "Enrollment open!", { 375: true })]);
const gen = { 375: snap([{ cid: "n4", text: "Enrollment open!", visible: true }]) };
assert.equal(countVisibleInCaptureHiddenInClone(ir, gen, [375]), 0);
});
it("does NOT count a node the SOURCE itself hid (faithful hide)", () => {
// maxbo n192 @375: source already off-screen (visible:false) — the clone hiding it is correct.
const ir = makeIR([leaf("n192", "Avatar: Fire and Ash", { 375: false, 768: true })]);
const gen = {
375: snap([{ cid: "n192", text: "Avatar: Fire and Ash", visible: false }]),
768: snap([{ cid: "n192", text: "Avatar: Fire and Ash", visible: true }]),
};
assert.equal(countVisibleInCaptureHiddenInClone(ir, gen, [375, 768]), 0);
});
it("counts a node once even when hidden at several viewports (distinct cids)", () => {
const ir = makeIR([leaf("n4", "Enrollment open!", { 375: true, 768: true })]);
const gen = {
375: snap([{ cid: "n4", text: "Enrollment open!", visible: false }]),
768: snap([{ cid: "n4", text: "Enrollment open!", visible: false }]),
};
assert.equal(countVisibleInCaptureHiddenInClone(ir, gen, [375, 768]), 1);
});
it("ignores whitespace-only text nodes", () => {
const ir = makeIR([leaf("n5", " ", { 375: true })]);
const gen = { 375: snap([{ cid: "n5", text: " ", visible: false }]) };
assert.equal(countVisibleInCaptureHiddenInClone(ir, gen, [375]), 0);
});
it("does not count when the clone has no node for the cid (a different miss)", () => {
const ir = makeIR([leaf("n4", "Enrollment open!", { 375: true })]);
const gen = { 375: snap([]) };
assert.equal(countVisibleInCaptureHiddenInClone(ir, gen, [375]), 0);
});
});