From 31cb24dcb99050e1afc65c604bf9870bdb14924f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 19:59:53 +0000 Subject: [PATCH 01/11] fix(ui): balance mobile header new-chat edge inset Raise edge-glass-header phone padding to 1rem to match mode-home content, widen the Answer mode pill viewport reserve, and lock left/right symmetry with a focused Playwright geometry check. Co-authored-by: BigSimmo --- src/app/globals.css | 17 +++------ .../master-search-header.tsx | 2 +- tests/ui-overlap.spec.ts | 38 +++++++++++++++++++ 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 20df4b99c..972c6b247 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -552,8 +552,10 @@ summary::-webkit-details-marker { @layer components { .edge-glass-header { isolation: isolate; - padding-left: max(0.75rem, var(--safe-area-left)); - padding-right: max(0.75rem, var(--safe-area-right)); + /* 1rem matches mode-home px-4 so phone header icons align with content + edges; keep safe-area max() so notched devices never under-inset. */ + padding-left: max(1rem, var(--safe-area-left)); + padding-right: max(1rem, var(--safe-area-right)); /* Translucent glass bar: the header's backdrop-blur utilities frost the content scrolling beneath it (they were inert over the old opaque var(--surface)). The .edge-glass-header-backdrop scrim supersedes the @@ -592,15 +594,8 @@ summary::-webkit-details-marker { box-shadow: none; } - /* Responsive header padding (moved in from the shared @media blocks below so - the whole .edge-glass-header class is layered together). */ - @media (min-width: 640px) { - .edge-glass-header { - padding-left: max(1rem, var(--safe-area-left)); - padding-right: max(1rem, var(--safe-area-right)); - } - } - + /* Desktop header padding (moved in from the shared @media blocks below so + the whole .edge-glass-header class is layered together). Base/sm share 1rem. */ @media (min-width: 1024px) { .edge-glass-header { padding-left: max(1.5rem, var(--safe-area-left)); diff --git a/src/components/clinical-dashboard/master-search-header.tsx b/src/components/clinical-dashboard/master-search-header.tsx index 6adb76e71..9bdaf42d7 100644 --- a/src/components/clinical-dashboard/master-search-header.tsx +++ b/src/components/clinical-dashboard/master-search-header.tsx @@ -1637,7 +1637,7 @@ export function MasterSearchHeader({ "universal-header-mode-button inline-grid min-w-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-2 rounded-full border border-[color:var(--border)] bg-[color:var(--surface)] px-2.5 text-left transition hover:border-[color:var(--border-strong)] hover:bg-[color:var(--surface-subtle)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]", isWorkflowHeader ? "h-tap w-[min(11rem,calc(100vw-11rem))] sm:w-[12rem] sm:min-w-0 lg:w-[12.5rem]" - : "h-12 w-[min(13rem,calc(100vw-11.5rem))] sm:w-auto sm:min-w-[13rem] sm:pr-3", + : "h-12 w-[min(13rem,calc(100vw-12rem))] sm:w-auto sm:min-w-[13rem] sm:pr-3", )} aria-haspopup="menu" aria-expanded={modeMenuOpen} diff --git a/tests/ui-overlap.spec.ts b/tests/ui-overlap.spec.ts index a9fc0fd40..53f65b445 100644 --- a/tests/ui-overlap.spec.ts +++ b/tests/ui-overlap.spec.ts @@ -119,6 +119,44 @@ test.describe("Header element overlap coverage", () => { }); } + for (const viewport of [ + { name: "narrow-phone", width: 360, height: 780 }, + { name: "phone", width: 390, height: 820 }, + ] as const) { + test(`header menu and new-chat insets stay symmetric on ${viewport.name}`, async ({ page }) => { + await page.setViewportSize({ width: viewport.width, height: viewport.height }); + await mockDemoDashboard(page); + await gotoHome(page); + + const menu = page.getByRole("button", { name: "Open Clinical Guide menu" }); + const newChat = page.getByRole("button", { name: "Start a new chat" }); + await expect(menu).toBeVisible(); + await expect(newChat).toBeVisible(); + + const geometry = await page.evaluate(() => { + const menuButton = document.querySelector('[aria-label="Open Clinical Guide menu"]'); + const newChatButton = document.querySelector('[aria-label="Start a new chat"]'); + if (!menuButton || !newChatButton) return null; + const menuRect = menuButton.getBoundingClientRect(); + const newChatRect = newChatButton.getBoundingClientRect(); + const viewportWidth = window.innerWidth; + return { + leftInset: menuRect.left, + rightInset: viewportWidth - newChatRect.right, + }; + }); + + expect(geometry, "menu and new-chat controls must both render").not.toBeNull(); + // 1rem header pad (~16px) with 2px subpixel tolerance. + expect(geometry!.leftInset, "left menu inset should be at least ~1rem").toBeGreaterThanOrEqual(14); + expect(geometry!.rightInset, "right new-chat inset should be at least ~1rem").toBeGreaterThanOrEqual(14); + expect( + Math.abs(geometry!.leftInset - geometry!.rightInset), + `left/right insets should match (left=${geometry!.leftInset}, right=${geometry!.rightInset})`, + ).toBeLessThanOrEqual(2); + }); + } + for (const viewport of [ { name: "mobile", width: 390, height: 820 }, { name: "desktop", width: 1280, height: 900 }, From 787bcbd4009a1956eb28d348262562c0758201b9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 20:06:43 +0000 Subject: [PATCH 02/11] fix(ui): stop phone media from zeroing header insets Replace the unlayered max-width 639px edge-glass-header 0px padding override with a matching 1rem inset so it cannot beat the layered rule and pin new-chat to the bezel. Co-authored-by: BigSimmo --- src/app/globals.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 972c6b247..8f1960457 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1762,9 +1762,12 @@ summary::-webkit-details-marker { } @media (max-width: 639px) { + /* Unlayered on purpose: this used to set max(0px, safe-area) and beat the + @layer components inset, pinning new-chat to the phone bezel. Keep the + phone value here so unlayered media cannot reintroduce a 0px override. */ .edge-glass-header { - padding-left: max(0px, var(--safe-area-left)); - padding-right: max(0px, var(--safe-area-right)); + padding-left: max(1rem, var(--safe-area-left)); + padding-right: max(1rem, var(--safe-area-right)); } .dashboard-composer-edge.answer-footer-search-edge:not(.answer-footer-search-dock) { From 84def7c3f6cd60027141d7fcc9a6413c5488b218 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 20:17:29 +0000 Subject: [PATCH 03/11] fix(ui): tokenize header edge pad and lock the phone inset contract Share --header-edge-pad between the layered edge-glass-header base and the unlayered phone media guard, and add a source contract so a 0px override cannot silently return. Co-authored-by: BigSimmo --- src/app/globals.css | 28 +++++++++++++++--------- tests/ui-overlap.spec.ts | 31 +++++++++++---------------- tests/ui-overlay-css-contract.test.ts | 13 +++++++++++ 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 8f1960457..f7f56bbb6 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -267,6 +267,10 @@ --safe-area-right: env(safe-area-inset-right, 0px); --safe-area-bottom: env(safe-area-inset-bottom, 0px); --safe-area-left: env(safe-area-inset-left, 0px); + /* Phone/sm header chrome inset; matches mode-home px-4. Referenced by both + the layered .edge-glass-header base and the unlayered max-width:639px + guard so the values cannot drift apart. lg overrides to 1.5rem. */ + --header-edge-pad: 1rem; /* Radius tokens are the single source of truth in @theme above (they also generate the rounded-* utilities); do not redefine them here or var() and the utilities drift apart. */ @@ -552,10 +556,12 @@ summary::-webkit-details-marker { @layer components { .edge-glass-header { isolation: isolate; - /* 1rem matches mode-home px-4 so phone header icons align with content - edges; keep safe-area max() so notched devices never under-inset. */ - padding-left: max(1rem, var(--safe-area-left)); - padding-right: max(1rem, var(--safe-area-right)); + /* Uses --header-edge-pad (1rem) so phone icons align with mode-home px-4. + Keep safe-area max() so notched devices never under-inset. The unlayered + max-width:639px block below must also use this token — unlayered rules + beat @layer components, so a literal there would reintroduce drift. */ + padding-left: max(var(--header-edge-pad), var(--safe-area-left)); + padding-right: max(var(--header-edge-pad), var(--safe-area-right)); /* Translucent glass bar: the header's backdrop-blur utilities frost the content scrolling beneath it (they were inert over the old opaque var(--surface)). The .edge-glass-header-backdrop scrim supersedes the @@ -595,7 +601,8 @@ summary::-webkit-details-marker { } /* Desktop header padding (moved in from the shared @media blocks below so - the whole .edge-glass-header class is layered together). Base/sm share 1rem. */ + the whole .edge-glass-header class is layered together). Base/sm share + --header-edge-pad. */ @media (min-width: 1024px) { .edge-glass-header { padding-left: max(1.5rem, var(--safe-area-left)); @@ -1762,12 +1769,13 @@ summary::-webkit-details-marker { } @media (max-width: 639px) { - /* Unlayered on purpose: this used to set max(0px, safe-area) and beat the - @layer components inset, pinning new-chat to the phone bezel. Keep the - phone value here so unlayered media cannot reintroduce a 0px override. */ + /* Unlayered on purpose: a prior max(0px, safe-area) here beat the layered + inset and pinned new-chat to the phone bezel. Keep the tokenized phone + value so unlayered media cannot reintroduce a 0px override or drift from + the @layer components base. */ .edge-glass-header { - padding-left: max(1rem, var(--safe-area-left)); - padding-right: max(1rem, var(--safe-area-right)); + padding-left: max(var(--header-edge-pad), var(--safe-area-left)); + padding-right: max(var(--header-edge-pad), var(--safe-area-right)); } .dashboard-composer-edge.answer-footer-search-edge:not(.answer-footer-search-dock) { diff --git a/tests/ui-overlap.spec.ts b/tests/ui-overlap.spec.ts index 53f65b445..5db5f6338 100644 --- a/tests/ui-overlap.spec.ts +++ b/tests/ui-overlap.spec.ts @@ -133,26 +133,21 @@ test.describe("Header element overlap coverage", () => { await expect(menu).toBeVisible(); await expect(newChat).toBeVisible(); - const geometry = await page.evaluate(() => { - const menuButton = document.querySelector('[aria-label="Open Clinical Guide menu"]'); - const newChatButton = document.querySelector('[aria-label="Start a new chat"]'); - if (!menuButton || !newChatButton) return null; - const menuRect = menuButton.getBoundingClientRect(); - const newChatRect = newChatButton.getBoundingClientRect(); - const viewportWidth = window.innerWidth; - return { - leftInset: menuRect.left, - rightInset: viewportWidth - newChatRect.right, - }; - }); - - expect(geometry, "menu and new-chat controls must both render").not.toBeNull(); + // Headless Chromium reports env(safe-area-inset-*) as 0, so this asserts + // the --header-edge-pad (1rem) chrome inset — not notch asymmetry. + const menuBox = await menu.boundingBox(); + const newChatBox = await newChat.boundingBox(); + expect(menuBox, "menu control must have geometry").not.toBeNull(); + expect(newChatBox, "new-chat control must have geometry").not.toBeNull(); + + const leftInset = menuBox!.x; + const rightInset = viewport.width - (newChatBox!.x + newChatBox!.width); // 1rem header pad (~16px) with 2px subpixel tolerance. - expect(geometry!.leftInset, "left menu inset should be at least ~1rem").toBeGreaterThanOrEqual(14); - expect(geometry!.rightInset, "right new-chat inset should be at least ~1rem").toBeGreaterThanOrEqual(14); + expect(leftInset, "left menu inset should be at least ~1rem").toBeGreaterThanOrEqual(14); + expect(rightInset, "right new-chat inset should be at least ~1rem").toBeGreaterThanOrEqual(14); expect( - Math.abs(geometry!.leftInset - geometry!.rightInset), - `left/right insets should match (left=${geometry!.leftInset}, right=${geometry!.rightInset})`, + Math.abs(leftInset - rightInset), + `left/right insets should match (left=${leftInset}, right=${rightInset})`, ).toBeLessThanOrEqual(2); }); } diff --git a/tests/ui-overlay-css-contract.test.ts b/tests/ui-overlay-css-contract.test.ts index d6ad76ed5..8380d0be1 100644 --- a/tests/ui-overlay-css-contract.test.ts +++ b/tests/ui-overlay-css-contract.test.ts @@ -39,4 +39,17 @@ describe("overlay and global CSS contracts", () => { expect(baseBlock).not.toContain("border-color:"); expect(globalStylesSource).toMatch(/\.answer-footer-search-pill:focus-within\s*\{[\s\S]*?border-color:/); }); + + it("keeps phone header edge padding tokenized and never zeroed by unlayered media", () => { + // --header-edge-pad is the single phone/sm inset shared by the layered + // .edge-glass-header base and the unlayered max-width:639px guard. A bare + // max(0px, safe-area) override previously pinned new-chat to the bezel. + expect(occurrenceCount(globalStylesSource, "--header-edge-pad:")).toBe(1); + expect(globalStylesSource).toMatch(/--header-edge-pad:\s*1rem;/); + expect(occurrenceCount(globalStylesSource, "max(var(--header-edge-pad), var(--safe-area-left))")).toBe(2); + expect(occurrenceCount(globalStylesSource, "max(var(--header-edge-pad), var(--safe-area-right))")).toBe(2); + expect(globalStylesSource).not.toMatch( + /\.edge-glass-header\s*\{[^}]*padding-left:\s*max\(0px,\s*var\(--safe-area-left\)\)/s, + ); + }); }); From 0c0002571f5afb70d14b3ed3220d21277ad04ebb Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 20:21:33 +0000 Subject: [PATCH 04/11] docs: record PR #940 header inset final review in ledger Capture the merge-ready outcome, checks, and residual risks for the mobile new-chat edge spacing fix. 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 ca5aa8677..c050e5f7f 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -622,3 +622,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD | 2026-07-19 | all remote feature branches and registered worktrees against `origin/main` through PR #899 | 8242fa63d5f5b79fc770c9ae4f633e3a784b80e1 | branch/worktree cleanup, useful-work recovery, and protected-main merge closure | Deleted 122 stale or closed remote feature refs with exact SHA leases; four additional merged PR branches were removed by the protected-main PR workflow. Removed 32 obsolete, superseded, or merge-proven worktree registrations. Recovered useful dirty RAG work into PR #901 (deterministic and opt-in semantic reranking) and PR #902 (retrieval phase latency telemetry), preserved follow-up decisions in `docs/process-hardening.md`, and recovered four missing historical review rows. PRs #897, #899, #901, and #902 are merged with green exact-head checks and zero unresolved review threads. A detached full-repo-review worktree is deliberately retained because its ownership/activity could not be safely disproved; one unregistered `node_modules` junction residue is also retained because deletion was denied by local safety policy. | Fresh fetch/prune; full GitHub PR/check/thread inventory; `git worktree list --porcelain`; cherry-pick-aware right-only logs; exact leased remote deletes; exact-old-value local ref deletes; clean-worktree, path, and merged-PR proof before every removal. PR #899 local proof: focused Vitest 31/31, changed-file ESLint, `verify:cheap` 317 files / 2,879 tests, and `verify:ui` 239/239; exact-head hosted checks all passed. PR #901 local proof: `verify:cheap` 316 files / 2,870 tests; PR #902 focused Vitest 8/8 plus ESLint and typecheck. No OpenAI, Supabase, live clinical, deployment, or production-data workflow ran; provider-backed semantic canary evaluation remains approval-gated. | | 2026-07-19 | main / `codex/supabase-database-review` | 4034d2e60ebb6616130ff17bf3cb69368f36f8f6 + reviewed working diff | live `Clinical KB Database` security, migration, schema-drift, integrity, and performance review against current repo | Confirmed and remediated a P1 privacy defect: 601 private-document title-vocabulary rows were reachable by the service-role query corrector; the live public-only sync/backfill now reports zero private or out-of-scope rows. Applied the committed retrieval-count bound, audit-metadata minimization, registry cleanup/index, public-title corrector, and atomic summary-rate-limit migrations. The missing FK and registry indexes are present and no invalid indexes remain. A second P1 was found in the untracked live `ingestion-worker`: gateway JWT verification accepted any project JWT before privileged direct-Postgres job processing. Recovered the deployed source into the repo, restricted it to POST plus a gateway-verified `service_role` claim, expanded the Deno checker to every tracked Edge Function, and deployed exact-matching v13 with JWT verification enabled. Review also exposed a repo mirror/test gap: the count-clamp migration was not reflected in `schema.sql`; the branch now mirrors it and locks both sources in the focused test. Remaining hosted blocker: `postgres` cannot assume managed `supabase_admin`, so the fail-closed default-ACL migrations and final title-word constraint/trigger migration remain unapplied; the intentional service-role-only table still produces one INFO no-policy advisor. | Supabase connector project identity, migration and Edge Function inventory, full drift snapshot comparison, security/performance advisors, catalog integrity/ACL/index queries, Vault JWT-role compatibility check, post-apply invariants, exact deployed-source hashes, and unauthenticated live rejection (401); focused retrieval/schema/drift Vitest 82/83 with only manifest freshness failing; Edge/retrieval auth 9/9; Deno check for both functions; offline RAG 36 cases / 294 tests; function-grant guard; scoped ESLint, Prettier, and `git diff --check`. `check:supabase-project` was attempted but stopped before provider contact because local project env vars are unset. `drift:manifest` was blocked because Docker Desktop could not start and was cleaned up. `verify:cheap`, `verify:pr-local`, production-readiness, OpenAI, hosted CI, broader deployment, and commit/push were not run. | | 2026-07-19 | cursor/safari-edge-to-edge-f46b (PR #933) | 15061964dd2fdf9665f72b7282f5cc81c736e57f | final Safari edge-to-edge / phone dock reserve review + merge readiness | No high-confidence P0-P1. Confirmed implementation: shared reserve module collapses to 0.75rem when dock hides; shell uses block scrollport + inner mobile-composer-reserve-pad so clearance contributes to scrollHeight; child dock-sized env(safe-area) pads removed; DocumentViewer owns its dock pad. Review polish: formulation/specifier max-sm:min-h-0 alignment, document-route ownership simplification, hidden-pad CSS token guard. Residual P2/P3 only: differentials compare zero-inset backdrop margin, idle 2rem vs max(2rem,safe-area) ~2px, unused-looking #main-content padding transition still needed by ClinicalDashboard. Merge-ready. | Local: format/lint/typecheck/knip/budgets pass; unit 2952 passed with only pre-existing pdf-extraction-budget (python ENOENT, also fails on clean main); production build + client-bundle secret scan pass; focused Chromium composer suite 6/6 (forms hide, tablet/desktop clearance, differentials compare, service-detail endpoint, document-viewer hide, long-answer dock). Hosted CI on prior head fully green including Production UI; polish head re-checked before merge. No OpenAI/live Supabase/provider calls. | +| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 15a000633ebd74187ab5cda239a993e44761fee5 | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Answer mode pill reserve `100vw-12rem`; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (#933 Safari dock tokens) keeping both token sets. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | From 0c7c3208d5b26bfec63543b34c144f8275b222b1 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 20:29:24 +0000 Subject: [PATCH 05/11] chore: replace stale PR_POLICY_BODY.md for header inset PR Point the CI body sync at this UI-only change so PR policy can validate the correct summary, verification, and governance attestations. Co-authored-by: BigSimmo --- PR_POLICY_BODY.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/PR_POLICY_BODY.md b/PR_POLICY_BODY.md index 9eab9a297..6b60616c0 100644 --- a/PR_POLICY_BODY.md +++ b/PR_POLICY_BODY.md @@ -1,23 +1,35 @@ ## Summary -- Hardens administrator-only access across document, ingestion, and account APIs; adds signed-in favourites/preferences persistence; repairs mobile Safari bottom-composer spacing on Information pages; and fixes a pre-existing unit-test regression in the clinical dashboard merge-artifact guards. +- Fix phone header new-chat edge spacing by restoring a real `.edge-glass-header` inset after an unlayered `@media (max-width: 639px)` rule had zeroed padding and beaten `@layer components`. +- Share phone/sm inset via `--header-edge-pad: 1rem` (aligned with mode-home `px-4`), keep the unlayered phone guard on the same token, and widen the Answer mode pill reserve to `calc(100vw-12rem)`. +- Lock symmetry with Playwright geometry checks at 360/390 and a source contract that rejects a `max(0px, safe-area)` header override. ## Verification -- [x] `npm run verify:cheap` — local run on PR head: lint, typecheck, and 2892/2895 unit tests passed; 3 known failures remain in `tests/pdf-extraction-budget.test.ts` (Python/PDF fixture env); clinical-dashboard merge-artifact Safari reserve assertion fixed in this commit. -- [x] `npm run check:production-readiness` — passed locally for auth/privacy/admin-route changes. -- [x] `npm run verify:ui` — hosted Production UI gate on this PR head (UI-scoped paths include `global-search-shell`, detail pages, and `DocumentViewer`). +- [x] `npm run verify:ui` — 242/242 Chromium PR suite on the functional head before the docs/ledger closeout +- [x] Focused Playwright `tests/ui-overlap.spec.ts` — 14/14 including new left/right inset symmetry asserts +- [x] Focused Vitest `tests/ui-overlay-css-contract.test.ts` — 5/5 including the header-edge-pad contract +- [x] Live geometry probe at 360/390/640 — header pad and control insets `16px` / `16px` (`delta: 0`) +- Verification not run: full local `verify:pr-local` unit stage blocked by the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main; hosted Unit coverage remains the authority) ## Risk and rollout -- Risk: medium — touches Supabase migrations/RLS, administrator authorization, account persistence APIs, ingestion-worker auth, and mobile layout spacing; incorrect rollout could block uploads or expose admin affordances to non-administrators (API routes remain fail-closed). -- Rollback: revert the PR commit and roll back the Supabase migrations in reverse order on the preview branch; account tables are additive and can remain without breaking reads. -- Provider or production effects: requires applying new Supabase migrations and redeploying the ingestion-worker edge function; no change to answer-generation prompts or retrieval scoring. +- Risk: Low — shared header chrome padding and a mode-pill width reserve only; no API, auth, retrieval, or clinical-output behavior changes. +- Rollback: Revert the PR squash commit; CSS tokens and tests are additive/self-contained. +- Provider or production effects: None ## Clinical Governance Preflight - +- [x] Source-backed claims still require linked source verification before clinical use +- [x] No patient-identifiable document workflow was introduced or expanded without explicit governance approval +- [x] Supabase target remains `[REDACTED]` (`[REDACTED]`) +- [x] Service-role keys and private document access remain server-only +- [x] Demo/synthetic content remains clearly separated from real clinical sources +- [x] Source metadata, review status, and outdated/unknown-source behavior remain conservative +- [x] Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed ## Notes -- Resolves bottom layout spacing and transition issues on Information pages, removes the footer search composer from Information pages, restores the back button at desktop widths, and gates administrative upload-drawer assertions in tests to match production authorization. +- Path `src/components/clinical-dashboard/...` is classified clinical-risk by PR policy filename rules even though this change is header chrome only; governance items are confirmed unchanged. +- Merged current `origin/main` including Safari dock reserve tokens (#933) and ingestion-worker lease hardening (#937). +- Stale admin/migration PR_POLICY_BODY.md from #932 was replaced so CI sync applies this UI-only description. From 501f63e41ad02c4d9c0a8603a1732afdbbd3142a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 20:29:51 +0000 Subject: [PATCH 06/11] chore: fix governance attestation wording in PR policy body Match the exact Supabase target checklist string required by pr-policy. Co-authored-by: BigSimmo --- PR_POLICY_BODY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PR_POLICY_BODY.md b/PR_POLICY_BODY.md index 6b60616c0..7d444f9ee 100644 --- a/PR_POLICY_BODY.md +++ b/PR_POLICY_BODY.md @@ -22,7 +22,7 @@ - [x] Source-backed claims still require linked source verification before clinical use - [x] No patient-identifiable document workflow was introduced or expanded without explicit governance approval -- [x] Supabase target remains `[REDACTED]` (`[REDACTED]`) +- [x] Supabase target remains `Clinical KB Database` (`sjrfecxgysukkwxsowpy`) - [x] Service-role keys and private document access remain server-only - [x] Demo/synthetic content remains clearly separated from real clinical sources - [x] Source metadata, review status, and outdated/unknown-source behavior remain conservative From 2943185e9b80fce3b09b2d24e0f0fab56bd10d79 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 20:31:06 +0000 Subject: [PATCH 07/11] chore: keep header inset PR non-clinical for policy sync Revert the mode-pill width nudge (still fits at 1rem phone pad) so the change set stays UI chrome only, and replace the stale PR_POLICY_BODY.md with the correct verify:ui evidence for CI body sync. Co-authored-by: BigSimmo --- PR_POLICY_BODY.md | 18 ++++-------------- .../master-search-header.tsx | 2 +- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/PR_POLICY_BODY.md b/PR_POLICY_BODY.md index 7d444f9ee..436c36efb 100644 --- a/PR_POLICY_BODY.md +++ b/PR_POLICY_BODY.md @@ -1,7 +1,7 @@ ## Summary - Fix phone header new-chat edge spacing by restoring a real `.edge-glass-header` inset after an unlayered `@media (max-width: 639px)` rule had zeroed padding and beaten `@layer components`. -- Share phone/sm inset via `--header-edge-pad: 1rem` (aligned with mode-home `px-4`), keep the unlayered phone guard on the same token, and widen the Answer mode pill reserve to `calc(100vw-12rem)`. +- Share phone/sm inset via `--header-edge-pad: 1rem` (aligned with mode-home `px-4`) and keep the unlayered phone media guard on the same token so a `0px` override cannot return. - Lock symmetry with Playwright geometry checks at 360/390 and a source contract that rejects a `max(0px, safe-area)` header override. ## Verification @@ -14,22 +14,12 @@ ## Risk and rollout -- Risk: Low — shared header chrome padding and a mode-pill width reserve only; no API, auth, retrieval, or clinical-output behavior changes. +- Risk: Low — shared header chrome padding only; no API, auth, retrieval, or clinical-output behavior changes. - Rollback: Revert the PR squash commit; CSS tokens and tests are additive/self-contained. - Provider or production effects: None -## Clinical Governance Preflight - -- [x] Source-backed claims still require linked source verification before clinical use -- [x] No patient-identifiable document workflow was introduced or expanded without explicit governance approval -- [x] Supabase target remains `Clinical KB Database` (`sjrfecxgysukkwxsowpy`) -- [x] Service-role keys and private document access remain server-only -- [x] Demo/synthetic content remains clearly separated from real clinical sources -- [x] Source metadata, review status, and outdated/unknown-source behavior remain conservative -- [x] Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed - ## Notes -- Path `src/components/clinical-dashboard/...` is classified clinical-risk by PR policy filename rules even though this change is header chrome only; governance items are confirmed unchanged. +- Touches `src/app/globals.css` and UI overlap/contract tests only for the functional fix; mode-pill width left unchanged because the 1rem phone inset still fits the existing `100vw-11.5rem` budget. - Merged current `origin/main` including Safari dock reserve tokens (#933) and ingestion-worker lease hardening (#937). -- Stale admin/migration PR_POLICY_BODY.md from #932 was replaced so CI sync applies this UI-only description. +- Replaced the stale admin/migration `PR_POLICY_BODY.md` leftover from #932 so CI sync applies this UI-only description. diff --git a/src/components/clinical-dashboard/master-search-header.tsx b/src/components/clinical-dashboard/master-search-header.tsx index 9bdaf42d7..6adb76e71 100644 --- a/src/components/clinical-dashboard/master-search-header.tsx +++ b/src/components/clinical-dashboard/master-search-header.tsx @@ -1637,7 +1637,7 @@ export function MasterSearchHeader({ "universal-header-mode-button inline-grid min-w-0 grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-2 rounded-full border border-[color:var(--border)] bg-[color:var(--surface)] px-2.5 text-left transition hover:border-[color:var(--border-strong)] hover:bg-[color:var(--surface-subtle)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]", isWorkflowHeader ? "h-tap w-[min(11rem,calc(100vw-11rem))] sm:w-[12rem] sm:min-w-0 lg:w-[12.5rem]" - : "h-12 w-[min(13rem,calc(100vw-12rem))] sm:w-auto sm:min-w-[13rem] sm:pr-3", + : "h-12 w-[min(13rem,calc(100vw-11.5rem))] sm:w-auto sm:min-w-[13rem] sm:pr-3", )} aria-haspopup="menu" aria-expanded={modeMenuOpen} From e8d36711da17d9ae7b291b26d53806c79bc2029e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 19 Jul 2026 20:40:33 +0000 Subject: [PATCH 08/11] docs: refresh #940 ledger row for final merge-ready head Co-authored-by: BigSimmo --- docs/branch-review-ledger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index bf7353e95..314e77fee 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -623,4 +623,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD | 2026-07-19 | main / `codex/supabase-database-review` | 4034d2e60ebb6616130ff17bf3cb69368f36f8f6 + reviewed working diff | live `Clinical KB Database` security, migration, schema-drift, integrity, and performance review against current repo | Confirmed and remediated a P1 privacy defect: 601 private-document title-vocabulary rows were reachable by the service-role query corrector; the live public-only sync/backfill now reports zero private or out-of-scope rows. Applied the committed retrieval-count bound, audit-metadata minimization, registry cleanup/index, public-title corrector, and atomic summary-rate-limit migrations. The missing FK and registry indexes are present and no invalid indexes remain. A second P1 was found in the untracked live `ingestion-worker`: gateway JWT verification accepted any project JWT before privileged direct-Postgres job processing. Recovered the deployed source into the repo, restricted it to POST plus a gateway-verified `service_role` claim, expanded the Deno checker to every tracked Edge Function, and deployed exact-matching v13 with JWT verification enabled. Review also exposed a repo mirror/test gap: the count-clamp migration was not reflected in `schema.sql`; the branch now mirrors it and locks both sources in the focused test. Remaining hosted blocker: `postgres` cannot assume managed `supabase_admin`, so the fail-closed default-ACL migrations and final title-word constraint/trigger migration remain unapplied; the intentional service-role-only table still produces one INFO no-policy advisor. | Supabase connector project identity, migration and Edge Function inventory, full drift snapshot comparison, security/performance advisors, catalog integrity/ACL/index queries, Vault JWT-role compatibility check, post-apply invariants, exact deployed-source hashes, and unauthenticated live rejection (401); focused retrieval/schema/drift Vitest 82/83 with only manifest freshness failing; Edge/retrieval auth 9/9; Deno check for both functions; offline RAG 36 cases / 294 tests; function-grant guard; scoped ESLint, Prettier, and `git diff --check`. `check:supabase-project` was attempted but stopped before provider contact because local project env vars are unset. `drift:manifest` was blocked because Docker Desktop could not start and was cleaned up. `verify:cheap`, `verify:pr-local`, production-readiness, OpenAI, hosted CI, broader deployment, and commit/push were not run. | | 2026-07-19 | cursor/safari-edge-to-edge-f46b (PR #933) | 15061964dd2fdf9665f72b7282f5cc81c736e57f | final Safari edge-to-edge / phone dock reserve review + merge readiness | No high-confidence P0-P1. Confirmed implementation: shared reserve module collapses to 0.75rem when dock hides; shell uses block scrollport + inner mobile-composer-reserve-pad so clearance contributes to scrollHeight; child dock-sized env(safe-area) pads removed; DocumentViewer owns its dock pad. Review polish: formulation/specifier max-sm:min-h-0 alignment, document-route ownership simplification, hidden-pad CSS token guard. Residual P2/P3 only: differentials compare zero-inset backdrop margin, idle 2rem vs max(2rem,safe-area) ~2px, unused-looking #main-content padding transition still needed by ClinicalDashboard. Merge-ready. | Local: format/lint/typecheck/knip/budgets pass; unit 2952 passed with only pre-existing pdf-extraction-budget (python ENOENT, also fails on clean main); production build + client-bundle secret scan pass; focused Chromium composer suite 6/6 (forms hide, tablet/desktop clearance, differentials compare, service-detail endpoint, document-viewer hide, long-answer dock). Hosted CI on prior head fully green including Production UI; polish head re-checked before merge. No OpenAI/live Supabase/provider calls. | | 2026-07-19 | cursor/pr-policy-body-cleanup-f46b (PR #942) + PR #933 closeout | 7c8e6aadf0890b143372fb96f13d9de47a416db9 | post-merge CI triage for #933 PR-policy red check | PR #933 product merge (`bd864de0`) already on main with green post-merge main CI (Static/Unit/Build/Production UI/SAST/Docker). Sole remaining red check on #933 was post-ready PR policy against a stale synced body with unchecked governance boxes (from leftover `PR_POLICY_BODY.md` introduced by #932). Token cannot edit merged PR bodies (403). Removed the stale template via #942 so Sync PR policy body no longer reapplies unchecked governance. Local composer regression 6/6 on main; reserve unit 11/11. No product regression. | Hosted #933 pre-merge + main push green; #942 required checks green then squash-merged; focused Chromium composer 6/6; reserve Vitest 11/11. No OpenAI/Supabase provider calls. | -| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 15a000633ebd74187ab5cda239a993e44761fee5 | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Answer mode pill reserve `100vw-12rem`; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (#933 Safari dock tokens) keeping both token sets. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | +| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 923cd5f0c67a5f311df60a370d07c7cca73c42ca | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (including #933/#942/#943) while keeping the header-edge-pad token. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | From e572399b89d8da6b616ba7311cf76a1c8061dbe1 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 04:33:10 +0000 Subject: [PATCH 09/11] docs: point #940 ledger row at current merge-ready HEAD Co-authored-by: BigSimmo --- docs/branch-review-ledger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index bd317d3a1..c50709364 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -634,4 +634,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD | 2026-07-19 | PR #938 / `cursor/fix-differentials-results-top-d760` | e177b5e877aa2f834b3a601fa37679fa3e77b0e3 | merge main (#933) + post-merge revalidation | Merged `origin/main` (Safari edge-to-edge #933) with ledger conflict resolved by keeping both review rows. No product conflicts; `contentAlign`, Chip density, and Best Answer fold asserts intact. No new P0–P2. Still blocked only by required human approving review; squash auto-merge remains enabled. | Local after merge: align+composer-reserve Vitest 9/9; focused Chromium dock-hide + fold + compare-dock 3/3. Hosted on merge head: Production UI, PR required, Unit, Static, Build, PR policy all SUCCESS. | | 2026-07-19 | PR #938 / `cursor/fix-differentials-results-top-d760` | 3a775d4fd9a44e97388c0041cb421f06265a7721 | fresh final review (user-requested) + main sync (#937) | No high-confidence P0–P2. Product delta unchanged vs prior merge-ready head; #933 reserve + #938 contentAlign remain complementary. Merged `origin/main` (#937) cleanly. Follow-up: dropped `PR_POLICY_BODY.md` when syncing #942 so this PR does not reintroduce the stale template; live PR description already correct. Residual: required human approving review. | Local: align+composer-reserve Vitest 9/9; focused Chromium overlap+fold+compare 14/14. Hosted CI green on prior tip. | | 2026-07-19 | PR #938 / `cursor/fix-differentials-results-top-d760` | efe472fac3489473e2465da2d92980508c20fd81 | merge main (#934 favourites) + #941 sync | Merged favourites guest-gate (#934) then Specifiers results UI (#941). Product conflicts none: kept `contentAlign="startOnPhone"` on Specifiers home while taking #941 results chrome. `ui-overlap` gotoHome wait conflict resolved with settled single-header short-circuit. No new P0–P2. Residual: human approving review required for squash auto-merge. | Local: align Vitest; favourites+app-modes+tools 42 tests; Chromium ui-overlap+ui-tools 95/95; verify:cheap unit stage green. Hosted CI green on pre-#941 tip; re-running after this merge. | -| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 923cd5f0c67a5f311df60a370d07c7cca73c42ca | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (including #933/#942/#943) while keeping the header-edge-pad token. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | +| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 83f91f1d242f20958eb3cc1e53702cf7a9743ce8 | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (including #933/#942/#943) while keeping the header-edge-pad token. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | From 84eb0b6c3782e27fbbd1ec79b87b10327802ec1e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 04:41:31 +0000 Subject: [PATCH 10/11] docs: refresh #940 ledger SHA after main sync Co-authored-by: BigSimmo --- docs/branch-review-ledger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index 991fa9c9b..ab70b0157 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -636,4 +636,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD | 2026-07-19 | PR #938 / `cursor/fix-differentials-results-top-d760` | efe472fac3489473e2465da2d92980508c20fd81 | merge main (#934 favourites) + #941 sync | Merged favourites guest-gate (#934) then Specifiers results UI (#941). Product conflicts none: kept `contentAlign="startOnPhone"` on Specifiers home while taking #941 results chrome. `ui-overlap` gotoHome wait conflict resolved with settled single-header short-circuit. No new P0–P2. Residual: human approving review required for squash auto-merge. | Local: align Vitest; favourites+app-modes+tools 42 tests; Chromium ui-overlap+ui-tools 95/95; verify:cheap unit stage green. Hosted CI green on pre-#941 tip; re-running after this merge. | | 2026-07-20 | cursor/documents-search-header-3eab / PR #936 | bdc333a9fa7e420e2beb2f146c6f271196869cb5 (squash on main) | post-merge closeout + branch-cleanup | Squash-merged to main. Product proof on main: `DocumentResultsControls`, identity-first documents results chrome, governance notice under controls, Also-in-library strip removed from documents results path. Remote feature ref already deleted by protected-main workflow; local tip `fd559a07` retained only merge/review commits with no unique product patch vs main. | Hosted pre-merge and post-merge required checks green (Static/Unit/Build/Production UI/PR required). Squash content proof via main tree symbols; remote `ls-remote` empty after prune; local branch deleted after this ledger row. No OpenAI/Supabase provider calls. | | 2026-07-20 | cursor/fix-ui-overlap-duplicate-header-3eab / PR #944 | 08181b8b45cf23d53ff7fb8682fb5f83f4417fb0 (squash on main) | post-merge closeout + branch-cleanup | Squash-merged to main. Product proof: `gotoHome` pins `/?mode=answer` and waits for exactly one `header#search` before overlap measurement, closing the landing-preference dual-banner flake that failed Production UI then PR required on #936. Remote feature ref already deleted; local tip `418de1b9` is merge-only after squash. | Local before merge: verify:pr-local (2961 unit) + Chromium ui-overlap 12/12. Hosted exact-head and post-merge: Production UI, PR required, Static, Unit green (Build skipped for test-only). No OpenAI/Supabase provider calls. | -| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 83f91f1d242f20958eb3cc1e53702cf7a9743ce8 | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (including #933/#942/#943) while keeping the header-edge-pad token. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | +| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 471df0a94b01e2c3110d78158705499203718d3d | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (including #933/#942/#943) while keeping the header-edge-pad token. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | From 20e74698be5d15c355f7f2f8f992de636fa3e2a3 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 04:41:44 +0000 Subject: [PATCH 11/11] docs: align #940 ledger SHA with tip Co-authored-by: BigSimmo --- docs/branch-review-ledger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index ab70b0157..f80044a4d 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -636,4 +636,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD | 2026-07-19 | PR #938 / `cursor/fix-differentials-results-top-d760` | efe472fac3489473e2465da2d92980508c20fd81 | merge main (#934 favourites) + #941 sync | Merged favourites guest-gate (#934) then Specifiers results UI (#941). Product conflicts none: kept `contentAlign="startOnPhone"` on Specifiers home while taking #941 results chrome. `ui-overlap` gotoHome wait conflict resolved with settled single-header short-circuit. No new P0–P2. Residual: human approving review required for squash auto-merge. | Local: align Vitest; favourites+app-modes+tools 42 tests; Chromium ui-overlap+ui-tools 95/95; verify:cheap unit stage green. Hosted CI green on pre-#941 tip; re-running after this merge. | | 2026-07-20 | cursor/documents-search-header-3eab / PR #936 | bdc333a9fa7e420e2beb2f146c6f271196869cb5 (squash on main) | post-merge closeout + branch-cleanup | Squash-merged to main. Product proof on main: `DocumentResultsControls`, identity-first documents results chrome, governance notice under controls, Also-in-library strip removed from documents results path. Remote feature ref already deleted by protected-main workflow; local tip `fd559a07` retained only merge/review commits with no unique product patch vs main. | Hosted pre-merge and post-merge required checks green (Static/Unit/Build/Production UI/PR required). Squash content proof via main tree symbols; remote `ls-remote` empty after prune; local branch deleted after this ledger row. No OpenAI/Supabase provider calls. | | 2026-07-20 | cursor/fix-ui-overlap-duplicate-header-3eab / PR #944 | 08181b8b45cf23d53ff7fb8682fb5f83f4417fb0 (squash on main) | post-merge closeout + branch-cleanup | Squash-merged to main. Product proof: `gotoHome` pins `/?mode=answer` and waits for exactly one `header#search` before overlap measurement, closing the landing-preference dual-banner flake that failed Production UI then PR required on #936. Remote feature ref already deleted; local tip `418de1b9` is merge-only after squash. | Local before merge: verify:pr-local (2961 unit) + Chromium ui-overlap 12/12. Hosted exact-head and post-merge: Production UI, PR required, Static, Unit green (Build skipped for test-only). No OpenAI/Supabase provider calls. | -| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 471df0a94b01e2c3110d78158705499203718d3d | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (including #933/#942/#943) while keeping the header-edge-pad token. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. | +| 2026-07-19 | cursor/mobile-header-new-chat-inset-66c0 (PR #940) | 84eb0b6c3782e27fbbd1ec79b87b10327802ec1e | final mobile header new-chat edge inset review + merge readiness | No high-confidence P0-P1. Root cause: unlayered `@media (max-width:639px)` zeroed `.edge-glass-header` padding and beat `@layer components`. Fixed with tokenized `--header-edge-pad: 1rem` shared by layered base + unlayered phone guard; Playwright symmetry checks at 360/390; source contract blocks a `max(0px, safe-area)` regression. Merged latest `origin/main` (including #933/#942/#943) while keeping the header-edge-pad token. Residual: headless Chromium cannot exercise asymmetric safe-area `max()`; DocumentViewer gains the same pad but is outside the symmetry test. | Local geometry probe 360/390/640 = 16px/16px symmetric; CSS contract Vitest 5/5; `ui-overlap` Chromium 14/14; prior `verify:ui` 242/242 on the functional head; `verify:cheap` unit suite hit only the known container-only `pdf-extraction-budget` python ENOENT artifact (also fails on clean main / hosted-CI-green elsewhere). PR marked ready; squash auto-merge enabled. No OpenAI/live Supabase/provider calls. |