From 095791235d58a6309b21b139911a1aad9fe9086b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 7 Aug 2026 18:19:35 +0000 Subject: [PATCH 1/3] Remove redundant Specifiers search-results back breadcrumb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lone ← Specifiers crumb under ModeNav on search results was redundant with Find/Build/More; deep pages keep their trails. Co-authored-by: BigSimmo --- src/components/specifiers/specifiers-home-page.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/specifiers/specifiers-home-page.tsx b/src/components/specifiers/specifiers-home-page.tsx index 0e967c0ee..8ad608a3d 100644 --- a/src/components/specifiers/specifiers-home-page.tsx +++ b/src/components/specifiers/specifiers-home-page.tsx @@ -15,7 +15,6 @@ import { import { CategoryTag, ReviewStatusBadge, - SpecifierBreadcrumbs, SpecifierDiagnosisFilter, SpecifierFamilyFilterChips, SpecifierMatchCard, @@ -215,8 +214,6 @@ function SpecifierResults({ query }: { query: string }) { return ( - - Date: Fri, 7 Aug 2026 18:32:35 +0000 Subject: [PATCH 2/3] Record branch review for Specifiers breadcrumb removal Co-authored-by: BigSimmo --- docs/branch-review-ledger.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index a44da0ff3..0ca3c255c 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -712,3 +712,4 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-08-07 | claude/handover-review-nlhuln | de8b74e2fb94d1ec9b1982c15a2dea43421c3eee | outstanding-issues ledger capture after the mode-nav rollout (PR #1685) | Confirmed #256's two remaining suspected section sets are dead (/forms/ and /differentials/presentations/ draw no section nav; form-decision-context-mobile is a testId not an id; ruled out sectionId indirection in both files). Added #261 (delete-or-keep the consumer-less action kind) and #262 (addon-slot single-owner rule held by two lists agreeing by coincidence). #207/#226/#231 reviewed and deliberately left untouched as existing P1 rows. | check:outstanding-issues passed (260 rows, 119 open, unique ids, no ids deleted from base 1ff9ed206456); prettier --check clean on the changed file; rows written via scripts/outstanding-issues.mjs, never hand-edited; no code gates run - docs-only diff | | 2026-08-07 | claude/handover-review-nlhuln | de8b74e2fb94d1ec9b1982c15a2dea43421c3eee | outstanding-issues ledger capture after the mode-nav rollout (PR #1685) (supersedes 2026-08-07) | Confirmed #256's two remaining suspected section sets are dead (/forms/ and /differentials/presentations/ draw no section nav; form-decision-context-mobile is a testId not an id; ruled out sectionId indirection in both files). Added #271 (delete-or-keep the consumer-less action kind) and #272 (addon-slot single-owner rule held by two lists agreeing by coincidence) — renumbered from this PR's original #261/#262 because main claimed #261-#270 via PR #1678 design-system tracks in the interim. #207/#226/#231 reviewed and deliberately left untouched as existing P1 rows. | check:outstanding-issues passed (270 rows, 129 open, 141 archived, unique ids, next-id=273 above the highest, no ids deleted from base d32dd549a3dd); prettier --check clean on the changed file; rows written via scripts/outstanding-issues.mjs, never hand-edited; no code gates run - docs-only diff | | 2026-08-07 | claude/search-bar-mobile-layout-buu0io | 9d64388c0ce530d0c20bb7efe8ffb32cd928319c | phone results-filter idiom: 7 modes off MobileResultFilterControl onto ResultFilterTrigger + ResultFilterSheet; band, docs, tests | changes-shipped | typecheck; lint; test 5538 passed (1 pre-existing pr-handoff-stop failure, baselined on unmodified tree); build; check:rag:fixtures; check:bundle-budget +6.3% within tolerance; targeted Playwright: ui-accessibility 16, ui-specifiers+ui-formulation 12, ui-tools 5, ui-smoke 2, ui-stress 3 | +| 2026-08-07 | cursor/remove-specifiers-back-arrow-f1c4 | 095791235d58a6309b21b139911a1aad9fe9086b | specifiers-search-results-breadcrumb | removed lone ← Specifiers crumb from search results; deep pages unchanged | format,typecheck,lint,ensure+phone-spot-check | From 372043003a7a70f0b37032a21b2191aa38c38402 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 8 Aug 2026 05:39:26 +0000 Subject: [PATCH 3/3] fix(lighthouse): allow baseline refresh after Chrome drift `--update` treated runner Chrome user-agent mismatches as incomplete evidence, so the documented remediation could not run. Ignore baseline-relative gaps during refresh, then adopt this PR's CI reports (HeadlessChrome/150) as the committed baseline. Co-authored-by: BigSimmo --- lighthouse-budget.json | 88 +++++++++++++-------------- scripts/check-lighthouse-budget.mjs | 22 +++++-- tests/check-lighthouse-budget.test.ts | 27 ++++++++ 3 files changed, 87 insertions(+), 50 deletions(-) diff --git a/lighthouse-budget.json b/lighthouse-budget.json index 112dedb74..f2781e927 100644 --- a/lighthouse-budget.json +++ b/lighthouse-budget.json @@ -20,75 +20,75 @@ }, "baseline": { "desktop-documents-search": { - "lcpMs": 887, - "cls": 0.119, - "tbtMs": 1, - "fcpMs": 404.55240000000003, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "lcpMs": 790.8669, + "cls": 0.1192626548872241, + "tbtMs": 0, + "fcpMs": 390.7482, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "desktop-dsm": { - "lcpMs": 936, - "cls": 0.013, - "tbtMs": 0, - "fcpMs": 399.6637, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "lcpMs": 836.0241999999998, + "cls": 0.01342963896133897, + "tbtMs": 14.999999999999886, + "fcpMs": 381.7212, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "desktop-forms": { - "lcpMs": 870, - "cls": 0.06, + "lcpMs": 870.6212000000005, + "cls": 0.05606642664873546, "tbtMs": 0, - "fcpMs": 393.5287, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "fcpMs": 383.5404, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "desktop-root": { - "lcpMs": 822, - "cls": 0.007, - "tbtMs": 3, - "fcpMs": 358.3345, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "lcpMs": 812.1882499999992, + "cls": 0.006778250591016549, + "tbtMs": 16, + "fcpMs": 340.8753, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "desktop-therapy-compass": { - "lcpMs": 822, + "lcpMs": 895.1419000000001, "cls": 0, "tbtMs": 0, - "fcpMs": 397.3599, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "fcpMs": 389.1834, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "mobile-documents-search": { - "lcpMs": 2311, + "lcpMs": 2314.371, "cls": 0, - "tbtMs": 399, - "fcpMs": 2329.335, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "tbtMs": 383.43999999999915, + "fcpMs": 2314.371, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "mobile-dsm": { - "lcpMs": 2319, + "lcpMs": 2339.109, "cls": 0, - "tbtMs": 322, - "fcpMs": 2325.841, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "tbtMs": 352.6870000000008, + "fcpMs": 2339.109, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "mobile-forms": { - "lcpMs": 2304, - "cls": 0.08, - "tbtMs": 324, - "fcpMs": 2291.215, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "lcpMs": 2280.29, + "cls": 0.08045469317717091, + "tbtMs": 326.0409999999997, + "fcpMs": 2280.29, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "mobile-root": { - "lcpMs": 3274, + "lcpMs": 3929.966, "cls": 0, - "tbtMs": 763, - "fcpMs": 3274, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "tbtMs": 785.6220000000021, + "fcpMs": 3929.966, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" }, "mobile-therapy-compass": { - "lcpMs": 2338, + "lcpMs": 2336.784, "cls": 0, - "tbtMs": 302, - "fcpMs": 2327.357, - "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36" + "tbtMs": 333.18399999999883, + "fcpMs": 2336.784, + "chromeVersion": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/150.0.0.0 Safari/537.36" } }, - "updatedAt": "2026-08-07T13:42:17.043Z" + "updatedAt": "2026-08-08T05:38:39.988Z" } diff --git a/scripts/check-lighthouse-budget.mjs b/scripts/check-lighthouse-budget.mjs index 4b1b4cbec..bc549bd45 100644 --- a/scripts/check-lighthouse-budget.mjs +++ b/scripts/check-lighthouse-budget.mjs @@ -24,6 +24,11 @@ * Refresh the baseline from an intentional, known-good run: * npm run check:lighthouse-budget -- --update * + * `--update` deliberately ignores baseline-relative mismatches (a different Chrome + * user-agent, or a newly added route with no prior row). Those are exactly why the + * baseline is being refreshed; treating them as incomplete evidence made the + * documented remediation unreachable after a runner-image Chrome bump. + * * Flags: --update, --json, --dir , --require-reports (an empty directory is a * failure, not a no-op — used by run-lighthouse-budget.mjs, which owns the reports). */ @@ -67,8 +72,12 @@ export function expectedBudgetRuns(budget) { * * Fails closed and is never downgraded by `enforce` — an ungraded route silently * counted as a pass is exactly how unmeasured latency claims got acted on before. + * + * Pass `{ ignoreBaseline: true }` for `--update`: baseline-relative problems (missing + * prior row, Chrome user-agent drift) are the reason to refresh, not a reason to + * refuse the refresh. Measurement gaps still block. */ -export function incompleteBudgetEvidence(rows, budget) { +export function incompleteBudgetEvidence(rows, budget, { ignoreBaseline = false } = {}) { const tolerance = { ...DEFAULT_TOLERANCE, ...(budget?.tolerance ?? {}) }; const baseline = budget?.baseline ?? null; const hasBaseline = Boolean(baseline) && Object.keys(baseline).length > 0; @@ -100,7 +109,7 @@ export function incompleteBudgetEvidence(rows, budget) { for (const metric of Object.keys(tolerance)) { if (typeof row[metric] !== "number") problems.add(`${run}: report has no ${metric} number`); } - if (!hasBaseline) continue; + if (ignoreBaseline || !hasBaseline) continue; const before = baseline[run]; // A route or strategy added after the baseline was recorded has nothing to // compare against, and gradeRun returns no breaches for a missing row — so an @@ -320,10 +329,11 @@ function main() { const result = compareToLighthouseBudget(rows, budget); if (update) { - if (result.incomplete.length > 0) { - console.error( - `::error::refusing to update the baseline from incomplete evidence: ${result.incomplete.join("; ")}`, - ); + // Only measurement gaps block a refresh. Browser drift / missing prior rows are + // why `--update` exists — see incompleteBudgetEvidence({ ignoreBaseline: true }). + const measurementGaps = incompleteBudgetEvidence(rows, budget, { ignoreBaseline: true }); + if (measurementGaps.length > 0) { + console.error(`::error::refusing to update the baseline from incomplete evidence: ${measurementGaps.join("; ")}`); process.exit(1); } const next = { diff --git a/tests/check-lighthouse-budget.test.ts b/tests/check-lighthouse-budget.test.ts index 31b974118..9f6e1d719 100644 --- a/tests/check-lighthouse-budget.test.ts +++ b/tests/check-lighthouse-budget.test.ts @@ -142,6 +142,33 @@ describe("incompleteBudgetEvidence — completeness derived from what is graded" expect(problems[0]).toContain("measured by a different browser"); }); + it("ignores browser drift and missing baseline rows when refreshing", () => { + // `--update` must remain reachable after a runner Chrome bump; grading still + // fails closed on the same evidence via the default ignoreBaseline:false path. + const rows = completeRows(); + const stale = baselineFromRows( + rows + .filter((entry: Row) => entry.run !== "mobile-forms") + .map((entry: Row) => ({ ...entry, chromeVersion: "HeadlessChrome/131" })), + ); + + expect(incompleteBudgetEvidence(rows, budget({ baseline: stale }), { ignoreBaseline: true })).toEqual([]); + expect(incompleteBudgetEvidence(rows, budget({ baseline: stale }))).toEqual( + expect.arrayContaining([ + expect.stringContaining("measured by a different browser"), + "mobile-forms: no baseline row recorded — refresh with --update", + ]), + ); + }); + + it("still refuses a refresh when a report is missing", () => { + const rows = completeRows().filter((entry: Row) => entry.run !== "mobile-dsm"); + + expect(incompleteBudgetEvidence(rows, budget(), { ignoreBaseline: true })).toEqual([ + "mobile-dsm: no Lighthouse report produced", + ]); + }); + it("accepts a baseline that recorded no browser identity at all", () => { // Older baselines predate the field; absent is not the same as mismatched. const rows = completeRows();