From f2cb4ec2ce11bb29444c9aca3c0572c603d48e5e Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Tue, 18 Aug 2026 14:45:27 +0800 Subject: [PATCH 1/2] chore(bundle-budget): re-baseline production after investigating main's 8% drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The production baseline was captured on 2026-08-13 at ca788d41 and never refreshed. By 2026-08-18 main measured +8.03% against it — inside the 10% tolerance, but with about two points of headroom, so the next feature to land would fail Build for weight that was not its own. PR #2096 hit exactly that: 2.7 points of Dictionary pushed the total to +10.5%. AGENTS.md says a production failure means find the regression rather than move the ceiling, so this is the investigation before the move. Two full builds from one worktree with .next removed each time — main at 9d832452d and the baseline commit ca788d41 — attributing chunks to routes through the same _client-reference-manifest.js files the check itself reads. Measuring ca788d41 independently reproduced 1,405,170 bytes against the 1,405,202 recorded in bundle-budget.json, a 32-byte difference, which validates the method. The delta is +110.2 KiB spread across the app: of 101 non-mockup routes, 52 grew, 48 were unchanged and 1 shrank, median +8.2 KiB, maximum +24.5 KiB. No route doubled, no isolated chunk appeared, no new client-bearing route landed, and package-lock.json is byte-identical between the two commits. That is what 374 commits of feature work looks like, not an accidentally-bundled dependency, which would concentrate in one chunk. Refresh production.gzipBytes to 1,518,033 with updatedAt and baselineSource so the next investigation knows where to reproduce from. The five route budgets are left tighter on purpose — each is within its own tolerance and keeps a stricter second guard on the Lighthouse journeys — and the mockups budget and every tolerancePct are untouched. Full measurement in docs/evidence/bundle-budget-production-rebaseline-2026-08-18.md. Queues an outstanding-issues request: nothing schedules a baseline refresh, so the same squeeze recurs for whichever unrelated PR lands last. Co-Authored-By: Claude Opus 5 --- bundle-budget.json | 6 +- ...budget-production-rebaseline-2026-08-18.md | 93 +++++++++++++++++++ .../5d626edd-d62a-42b8-ac47-2e9717c99d33.json | 14 +++ 3 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 docs/evidence/bundle-budget-production-rebaseline-2026-08-18.md create mode 100644 docs/outstanding-issues-inbox/5d626edd-d62a-42b8-ac47-2e9717c99d33.json diff --git a/bundle-budget.json b/bundle-budget.json index 0aa30622d5..f1beb4046c 100644 --- a/bundle-budget.json +++ b/bundle-budget.json @@ -2,7 +2,7 @@ "$comment": "Client JS bundle-size budgets captured from a known-good production build. `production` guards aggregate user-facing chunks, `routes` guards the five Lighthouse journeys against route-local growth, and `mockups` is a looser design-scratch hygiene ceiling. Refresh intentionally with `npm run check:bundle-budget -- --update`.", "enforce": true, "production": { - "gzipBytes": 1405202, + "gzipBytes": 1518033, "tolerancePct": 10 }, "mockups": { @@ -33,6 +33,6 @@ }, "totalGzipBytes": 1708296, "tolerancePct": 10, - "updatedAt": "2026-08-13T14:08:49.522Z", - "baselineSource": "ca788d41e1e6b64dc6b9bc63609074d92470d7e7" + "updatedAt": "2026-08-18T00:00:00.000Z", + "baselineSource": "9d832452dc317844349d178683ba15d185eceb5d" } diff --git a/docs/evidence/bundle-budget-production-rebaseline-2026-08-18.md b/docs/evidence/bundle-budget-production-rebaseline-2026-08-18.md new file mode 100644 index 0000000000..9bc20082f5 --- /dev/null +++ b/docs/evidence/bundle-budget-production-rebaseline-2026-08-18.md @@ -0,0 +1,93 @@ +# Production bundle-budget re-baseline — 2026-08-18 + +`check:bundle-budget` compares the client JavaScript a non-mockup route can reach against a +baseline captured from a known-good build. The `production` baseline in `bundle-budget.json` was +captured on 2026-08-13 at `ca788d41` and never refreshed. By 2026-08-18 `main` measured **+8.03%** +against it — inside the 10% tolerance, but with only ~2 points of headroom left, so the next +feature to land would fail the gate for reasons that were not its own. PR #2096 (Dictionary) hit +exactly that: +2.7 points of its own weight pushed the total to +10.5% and turned `Build` red. + +The rule in `AGENTS.md` is that a production failure means _find the regression_, not move the +ceiling. This document is that investigation. It concludes the growth is distributed feature work +with no regression signature, and refreshes the `production` baseline only. + +## Method + +Two full production builds from the same worktree and the same `node_modules`, with `.next` +removed before each so no cached output could be measured: + +1. `origin/main` at `9d832452d` +2. the recorded baseline commit `ca788d41` + +Client chunks were attributed to routes through the per-route `*_client-reference-manifest.js` +files under `.next/server/app` — the same source `scripts/check-bundle-budget.mjs` uses — and gzip +sizes were measured per chunk. Chunk filenames are content-hashed and therefore not comparable +across builds, so the comparison is per route. + +`package-lock.json` is **byte-identical** between the two commits, so no dependency change +contributes to the delta. + +## Result + +| Measurement | Baseline `ca788d41` | Main `9d832452d` | Delta | +| ----------------- | ------------------- | ---------------- | ------------------- | +| Production gzip | 1372.2 KiB | 1482.5 KiB | +110.2 KiB (+8.03%) | +| Production chunks | 239 | 238 | −1 | + +The reproduction is exact enough to trust: measuring `ca788d41` independently produced +**1,405,170 bytes** against the **1,405,202 bytes** recorded in `bundle-budget.json` — a 32-byte, +0.002% difference, which confirms both the method and that the recorded baseline really was +captured at that commit. + +## Why this is not a regression + +Across the 101 non-mockup routes present in both builds: + +- **52 grew, 48 were unchanged, 1 shrank.** Median growth +8.2 KiB, maximum +24.5 KiB. +- No route doubled, no route gained a large isolated chunk, and no new heavy route appeared. The + only route added since the baseline is `/api/documents/signed-urls`, which ships no client + JavaScript. +- The shape is uniform growth in shared chunks — what 374 commits of feature work looks like, not + what an accidentally-bundled dependency looks like. A regression of that kind concentrates: one + chunk or one route jumps while the rest hold still. + +Largest per-route growth: + +| Route | Baseline KiB | Main KiB | Delta | +| ------------------------------- | ------------ | -------- | ----- | +| `/therapy-compass/[slug]` | 215.7 | 240.1 | +24.5 | +| `/therapy-compass/[slug]/brief` | 215.7 | 240.1 | +24.5 | +| `/therapy-compass/[slug]/sheet` | 215.7 | 240.1 | +24.5 | +| `/calculators` | 230.5 | 251.4 | +21.0 | +| `/specifiers/map` | 246.9 | 264.4 | +17.5 | +| `/therapy-compass/search` | 228.6 | 245.5 | +16.8 | +| `/therapy-compass/compare` | 219.0 | 234.7 | +15.7 | +| `/therapy-compass/recommend` | 218.6 | 232.8 | +14.2 | +| `/therapy-compass/pathways` | 218.1 | 232.2 | +14.1 | +| `/therapy-compass/review` | 217.0 | 231.1 | +14.1 | + +Those routes match where the code actually landed. Between the two commits `src/` changed by +**+16,559 / −6,988 lines across 254 files with 42 new files**, and the largest client-side diffs are +`diagnosis-map-panel.tsx`, `calculators/search-page.tsx`, `favourites-command-library-page.tsx`, +`differentials-home.tsx`, `document-search-results.tsx`, `ClinicalSidebar.tsx`, +`services-navigator-page.tsx` and `globals.css`. + +## What changed here + +Only `production.gzipBytes`, plus `updatedAt` and `baselineSource` so the next investigation knows +which commit to reproduce from. + +Deliberately **not** changed: + +- **The five `routes` budgets.** Each is within its own 10% tolerance right now + (`/` 199.1 → 210.6, `/therapy-compass` 206.1 → 218.9, `/documents/search` 201.7 → 211.3, + `/dsm` 201.7 → 211.2, `/forms` 224.7 → 234.4). Leaving them tighter keeps a second, stricter + guard on the Lighthouse journeys, which is the point of having per-route budgets at all. +- **The `mockups` budget**, which is within tolerance on `main` and is a separate hygiene ceiling. +- **`tolerancePct`.** The tolerance is not the problem; the staleness was. + +## Follow-up + +Nothing schedules a baseline refresh, so the same squeeze will recur — the gate quietly converts +accumulated growth into a failure for whichever unrelated PR lands last. Queued as an +outstanding-issues request alongside this change. diff --git a/docs/outstanding-issues-inbox/5d626edd-d62a-42b8-ac47-2e9717c99d33.json b/docs/outstanding-issues-inbox/5d626edd-d62a-42b8-ac47-2e9717c99d33.json new file mode 100644 index 0000000000..71d4fc32bb --- /dev/null +++ b/docs/outstanding-issues-inbox/5d626edd-d62a-42b8-ac47-2e9717c99d33.json @@ -0,0 +1,14 @@ +{ + "version": 2, + "id": "5d626edd-d62a-42b8-ac47-2e9717c99d33", + "createdOn": "2026-08-18", + "action": "add", + "payload": { + "pri": "P2", + "type": "rec", + "summary": "Nothing schedules a bundle-budget baseline refresh, so accumulated growth fails whichever unrelated PR lands last", + "detail": "The production baseline sat at ca788d41 (2026-08-13) untouched while main grew +8.03% by 2026-08-18, leaving ~2 points of headroom. PR #2096 (Dictionary) then failed Build at +10.5% for 2.7 points of its own weight. Re-baselined once in docs/evidence/bundle-budget-production-rebaseline-2026-08-18.md, but the same squeeze recurs unless a refresh has an owner or a trigger: options are a scheduled job that re-measures and opens a PR, a drift warning threshold below the failure threshold, or recording the baseline commit distance in the check output so staleness is visible before it blocks someone.", + "source": "PR review of #2095/#2096, 2026-08-18", + "issueUlid": "01M09SPZ4QQSHHGK3QG194ARKD" + } +} From 5929f39175bd274d4b65b77b279d93d3bb219087 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Tue, 18 Aug 2026 14:47:58 +0800 Subject: [PATCH 2/2] chore(ledger): record the production bundle-budget re-baseline review Co-Authored-By: Claude Opus 5 --- ...27b9919ddfcf00607246f6490249b5ce4f864db107ad619319d.record.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/branch-review-records/eb993f9206e1027b9919ddfcf00607246f6490249b5ce4f864db107ad619319d.record.md diff --git a/docs/branch-review-records/eb993f9206e1027b9919ddfcf00607246f6490249b5ce4f864db107ad619319d.record.md b/docs/branch-review-records/eb993f9206e1027b9919ddfcf00607246f6490249b5ce4f864db107ad619319d.record.md new file mode 100644 index 0000000000..220f71905b --- /dev/null +++ b/docs/branch-review-records/eb993f9206e1027b9919ddfcf00607246f6490249b5ce4f864db107ad619319d.record.md @@ -0,0 +1 @@ +| 2026-08-18 | claude/bundle-budget-production-baseline | f2cb4ec2ce11bb29444c9aca3c0572c603d48e5e | bundle-budget.json production baseline refresh + measurement evidence doc + outstanding-issues request | Approved — investigated before refreshing: main's +8.03% is diffuse feature growth across 52 of 101 routes with no regression signature and an unchanged lockfile; production baseline moved to the measured 1518033 bytes, route/mockups budgets and tolerances left untouched | two full builds (main 9d832452d and baseline ca788d41) with .next removed each time; baseline reproduced to within 32 bytes of the recorded value; check:bundle-budget passes at the new baseline with all five route budgets and mockups within tolerance; tests/bundle-budget.test.ts 33 passed; outstanding-issues + ledger-write-discipline + docs link guards passed; format clean. Full unit suite, lint and typecheck not run: the diff is one JSON baseline value plus documentation and an inbox request, with no source change and no plausible compile or behaviour path |