Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/branch-review-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD
| 2026-07-18 | claude/clinical-kb-pwa-review-asi3wb (PR #896, plan Phase 5; content commit + this ledger follow-up) | a6c2b4e92374e9002fb00c547eb5677d01ce538c | Design-polish sweep: audit-then-fix (plan Phase 5, final phase) | Audit on post-#890 main: three strict design guards clean; full re-run of the 07-token-adoption-audit grep method shows all July 3 debt resolved (M1–M3 done, L4 reduced to the deliberate theme-aware `ring-white/N dark:ring-white/10` glass idiom, L5/L7 gone; production hex all legitimate print/brand/console/comment classes); 43-capture live sweep across 15 routes × desktop/phone + 320px spots + dark/reduced-motion/forced-colors spots found 0 overflow and 0 console errors. Three defects found and fixed: (1) forced-colors solid-button labels rendered as blank Canvas-on-Canvas backplate boxes (axe-invisible) — command controls flattened to the native HCM ButtonFace/ButtonText pairing and accent glyph tokens flipped to ButtonText inside the existing forced-colors block, regression-locked by a new ui-accessibility test; (2) tools desktop 6-up quick-action rail truncated card titles at 1440×1000 — card metrics tightened, all six titles verified unclipped; (3) privacy page rendered "systemand" from a JSX newline-adjacent-to-tag drop — explicit space, locked by a privacy-ui assertion. Dated July 18 run appended to docs/redesign/07-token-adoption-audit.md (archived design-qa.md not resurrected). | Guards + focused vitest 14/14; `verify:cheap` chain green to the known container-only pdf-extraction-budget artifact (2806/2809); `verify:ui` 220 passed/2 failed (the two long-baselined container artifacts, hosted-CI-green through #826/#835/#872/#890); `test:e2e:accessibility` 8/8 incl. the new forced-colors token test; production build + client-bundle secret scan passed; `check:bundle-budget` within tolerance vs the Phase 4 ratchet (1290.6 vs 1278.6 KiB baseline); `verify:pr-local` runtime/format/lint/typecheck/build/rag-fixtures green with the same sole unit-suite artifact. `verify:release` not run (provider-backed; awaits explicit confirmation). No provider-backed checks run. |
| 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. |
32 changes: 28 additions & 4 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -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);
/* Keep in sync with mobile-composer-reserve.ts (phone dock clearance). */
--phone-dock-hidden-pad: 0.75rem;
--phone-dock-differentials-compare-clearance: 12.5rem;
--phone-dock-differentials-compare-compact-clearance: 12.25rem;
/* 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. */
Expand Down Expand Up @@ -1802,14 +1806,15 @@ summary::-webkit-details-marker {
height: max(5rem, calc(var(--safe-area-bottom) + 4.4rem));
}

/* Differentials search results: compare action sits above the search pill in the dock. */
/* Differentials search results: compare action sits above the search pill in the dock.
Heights track --phone-dock-differentials-compare-* (same as content reserve). */
.answer-footer-search-dock[data-footer-addon="differentials-compare"] .answer-footer-search-backdrop {
height: max(8.75rem, calc(var(--safe-area-bottom) + 7.5rem));
height: max(var(--phone-dock-differentials-compare-clearance), calc(var(--safe-area-bottom) + 11.25rem));
}

.answer-footer-search-dock.document-mobile-search-compact[data-footer-addon="differentials-compare"]
.answer-footer-search-backdrop {
height: max(8.5rem, calc(var(--safe-area-bottom) + 7.25rem));
height: max(var(--phone-dock-differentials-compare-compact-clearance), calc(var(--safe-area-bottom) + 11rem));
}

.document-mobile-search-pill {
Expand Down Expand Up @@ -2581,18 +2586,37 @@ html[data-motion="reduced"] .source-capsule-hit[aria-expanded="true"]:hover .sou
}
}

/* iOS Safari bottom padding transitions to match the composer's hide/show motion */
/* iOS Safari bottom reserve transitions to match the composer's hide/show motion.
Shell routes animate the inner reserve pad; dashboard/answer animates
#main-content padding; DocumentViewer animates its own content pad. */
@media (max-width: 639px) {
#main-content {
transition: padding-bottom 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
#main-content[data-bottom-composer-hidden="true"] {
transition: padding-bottom 240ms cubic-bezier(0.4, 0, 0.2, 1);
}
#main-content [data-testid="mobile-composer-reserve-pad"] {
transition: padding-bottom 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
#main-content[data-bottom-composer-hidden="true"] [data-testid="mobile-composer-reserve-pad"] {
transition: padding-bottom 240ms cubic-bezier(0.4, 0, 0.2, 1);
}
[data-testid="document-viewer-content"] {
transition: padding-bottom 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
[data-testid="document-viewer-content"][data-scroll-hidden="true"] {
transition: padding-bottom 240ms cubic-bezier(0.4, 0, 0.2, 1);
}
}

@media (max-width: 639px) and (prefers-reduced-motion: reduce) {
#main-content,
#main-content[data-bottom-composer-hidden="true"],
#main-content [data-testid="mobile-composer-reserve-pad"],
#main-content[data-bottom-composer-hidden="true"] [data-testid="mobile-composer-reserve-pad"],
[data-testid="document-viewer-content"],
[data-testid="document-viewer-content"][data-scroll-hidden="true"] {
transition: none;
}
}
27 changes: 14 additions & 13 deletions src/components/ClinicalDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ import {
} from "@/components/clinical-dashboard/answer-progress";
import { evidenceMapRowsFromRenderModel } from "@/components/clinical-dashboard/evidence-map-model";
import { MasterSearchHeader } from "@/components/clinical-dashboard/master-search-header";
import {
resolveDashboardVisibleMobileComposerReserve,
resolveMobileComposerReserve,
} from "@/components/clinical-dashboard/mobile-composer-reserve";
import { UniversalSearchAlsoMatches } from "@/components/clinical-dashboard/universal-search-also-matches";
import { useScrollHideReporter } from "@/components/clinical-dashboard/use-hide-on-scroll";
import { SearchCommandProvider } from "@/components/clinical-dashboard/search-command-context";
Expand Down Expand Up @@ -3249,19 +3253,16 @@ export function ClinicalDashboard({
const compactMobileBottomSearch = hasMobileBottomSearch && modeSearchSubmitted;
const differentialsCompareAddonActive =
searchMode === "differentials" && modeSearchSubmitted && Boolean(query.trim());
const visibleMobileComposerReserve =
searchMode === "answer"
? answerFollowUpSuggestions.length > 0
? "calc(7.5rem + var(--safe-area-bottom))"
: "calc(5.25rem + var(--safe-area-bottom))"
: differentialsCompareAddonActive
? "calc(8.75rem + var(--safe-area-bottom))"
: compactMobileBottomSearch
? "calc(5rem + var(--safe-area-bottom))"
: "calc(5.25rem + var(--safe-area-bottom))";
const mobileComposerReserve = bottomComposerHidden
? "max(0.75rem, env(safe-area-inset-bottom))"
: visibleMobileComposerReserve;
// Hidden dock pad must stay at 0.75rem — Safari toolbar safe-area recreates a blank band.
const mobileComposerReserve = resolveMobileComposerReserve(
bottomComposerHidden,
resolveDashboardVisibleMobileComposerReserve({
searchMode,
hasAnswerFollowUps: answerFollowUpSuggestions.length > 0,
differentialsCompareAddonActive,
compactMobileBottomSearch,
}),
);
const renderDegradedNotice = () => (
<UtilityDrawer
icon={!isOnline ? WifiOff : CircleAlert}
Expand Down
5 changes: 4 additions & 1 deletion src/components/DocumentViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3120,7 +3120,10 @@ export function DocumentViewer({
}}
className={cn(
glassOverlaySurface,
"document-viewer-composer floating-composer-edge dashboard-composer-edge fixed z-40 mx-auto flex min-h-[56px] max-w-3xl items-center gap-2 rounded-full bg-[color:var(--surface-lux)] px-2 shadow-[var(--shadow-lux)] max-sm:transition-transform max-sm:duration-200 max-sm:ease-out motion-reduce:transition-none",
"document-viewer-composer floating-composer-edge dashboard-composer-edge fixed z-40 mx-auto flex min-h-[56px] max-w-3xl items-center gap-2 rounded-full bg-[color:var(--surface-lux)] px-2 shadow-[var(--shadow-lux)] max-sm:transition-transform motion-reduce:transition-none",
composerScrollHidden
? "max-sm:duration-[240ms] max-sm:ease-[cubic-bezier(0.4,0,0.2,1)]"
: "max-sm:duration-200 max-sm:ease-[cubic-bezier(0.22,1,0.36,1)]",
)}
>
<button
Expand Down
1 change: 0 additions & 1 deletion src/components/applications-launcher-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,6 @@ export function ApplicationsLauncherWorkspace({
aria-labelledby="tools-home-title"
className={cn(
"mx-auto w-full max-w-[90rem] overflow-x-hidden px-4 pb-8 text-[color:var(--text)] sm:px-6 lg:px-8",
"pb-[calc(12rem+env(safe-area-inset-bottom))] sm:pb-8",
"pt-5 sm:pt-8 lg:pt-10",
className,
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/clinical-dashboard/differentials-home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ function SearchResultsView({
// this results canvas into a nested phone scrollport, stealing scroll from
// #main-content. The fixed compare FAB and shell hide-on-scroll both assume
// #main-content owns vertical scroll.
className="mx-auto grid w-full max-w-[86rem] min-w-0 gap-3 overflow-x-clip px-4 pb-[calc(12.5rem+env(safe-area-inset-bottom))] min-[390px]:gap-4 sm:px-4 lg:px-0 lg:pb-0"
className="mx-auto grid w-full max-w-[86rem] min-w-0 gap-3 overflow-x-clip px-4 pb-4 min-[390px]:gap-4 sm:px-4 lg:px-0 lg:pb-0"
>
{/* Query context lives here on every breakpoint — on phones this is the
only place the submitted query is visible above the fold. */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ export function FavouritesCommandLibraryPage({ query = "", demoMode }: { query?:
return (
<main
data-testid="favourites-hub"
className="min-h-0 overflow-x-clip bg-[color:var(--background)] pb-[calc(6rem+env(safe-area-inset-bottom))] text-[color:var(--text)] sm:min-h-[calc(100dvh-4rem)] sm:pb-32 md:pb-0"
className="min-h-0 overflow-x-clip bg-[color:var(--background)] pb-4 text-[color:var(--text)] sm:min-h-[calc(100dvh-4rem)] sm:pb-32 md:pb-0"
>
<span data-testid="favourites-command-library" className="sr-only">
Favourites command library
Expand Down Expand Up @@ -1128,7 +1128,7 @@ export function FavouritesCommandLibraryPage({ query = "", demoMode }: { query?:
return (
<main
data-testid="favourites-hub"
className="min-h-0 overflow-x-clip bg-[color:var(--background)] pb-[calc(6rem+env(safe-area-inset-bottom))] text-[color:var(--text)] sm:min-h-[calc(100dvh-4rem)] sm:pb-32 md:pb-0"
className="min-h-0 overflow-x-clip bg-[color:var(--background)] pb-4 text-[color:var(--text)] sm:min-h-[calc(100dvh-4rem)] sm:pb-32 md:pb-0"
>
<span data-testid="favourites-command-library" className="sr-only">
Favourites command library
Expand Down
Loading
Loading