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
2 changes: 2 additions & 0 deletions docs/branch-review-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -560,5 +560,7 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD
| 2026-07-15 | codex/outstanding-work-cleanup | 0c56f27a37af88a073d2bb695d2cf4c05067ff4f + working-tree diff | repo-wide outstanding-work reconciliation and cleanup | No high-confidence P0/P1 remained in the locally executable scope. Fixed the stale architecture index for DSM/specifier routes, pruned redundant Knip configuration, removed the unused `SignedImage` default export, and reconciled maintained docs so completed/superseded plans no longer present as active work. Retained explicitly blocked work: provider-gated operator actions, the live-eval shadow reindex harness, deep-memory section-ownership design, and RAG follow-ups that require live evidence or product/security decisions. Full Knip findings were triaged rather than mass-deleted; unresolved-import scan is clean. | Offline `npm run verify:cheap` passed with 2,417 tests/1 skipped; docs links 806, script refs 264, codebase index 35/35; Knip unresolved scan clean; typecheck clean; focused Vitest 15/15; env-name parity clean; `git diff --check`. Provider-backed Supabase/OpenAI/GitHub/Railway, dependency audit, browser, build, drift, and release gates not run. |
| 2026-07-15 | codex/design-polish-pass | 0c56f27a37af88a073d2bb695d2cf4c05067ff4f + reviewed working diff | full live design, responsive, UX, accessibility, design-system, routing, performance, lint, testing, documentation, and release-readiness review | No P0/P1 reproduced. Fixed the P2 duplicate phone scroll surface in the shared standalone shell and added a regression test; fixed mode-menu Tab dismissal; explicitly hid decorative dynamic icons; restricted press scaling to motion-safe environments; moved sheet backdrops and forced-colour glass/backdrop behavior onto design tokens. External target fidelity remains blocked because no independent Figma/mockup source was supplied. | Live 30-route desktop + 21-route phone sweep; targeted 320/390/639/768/1440/1920 proofs; `npm run verify:cheap` (2417 passed/1 skipped); `npm run verify:ui` (175/175); focused keyboard 1/1; accessibility media/axe 5/5; scoped Prettier, ESLint, TypeScript, type-scale, and icon-scale passed. Provider-backed checks not run. |
| 2026-07-15 | codex/documents-closed-default | 49f63791bced2b1764a11ab723aea94b45b026b6 | documents viewer disclosure defaults and related defect hunt | Fixed the inconsistent default-open document viewer sections by making indexed text, high-yield summary, tables/diagrams, and indexing details a native mutually exclusive closed disclosure group. The section navigation opens its requested disclosure and deep-linked evidence still reveals its target. The hunt also removed the explicitly open nested table-review queue, preserved printable summary content through the browser print lifecycle, and added cold-server readiness guards to the affected viewer tests. No other high-confidence default-open defect remains in the live Documents scope. | `npm run verify:cheap`; TypeScript; focused ESLint/Prettier; clean-worktree mocked Chromium coverage for deep-linked evidence, structured summary, closed/mutually-exclusive disclosures, navigation opening, and print state restore; `git diff --check`. Turbopack could not run through the local external `node_modules` junction, so clean browser verification used Next's supported Webpack dev mode. No Supabase/OpenAI/live-provider checks run. |
| 2026-07-17 | codex/scroll-geometry-stability-20260717 | f88a41ae5fb62ae39d5d1d33fd5e21490e1ea60e | phone scroll geometry and boundary stability review | Confirmed two coupled P2 interaction defects: hiding the fixed bottom composer removed its reserved space and changed the scroll viewport, while collapsing the in-flow header at the bottom produced a browser-driven scrollTop clamp that was misread as an upward gesture. The dock now keeps stable clearance, hide/reveal uses directional hysteresis, and geometry clamps are rebased without revealing chrome. No other high-confidence defect remains in the changed scope. | Focused Vitest 8/8; TypeScript; scoped ESLint; Prettier; `git diff --check`. `npm run verify:cheap` reached the full Vitest phase but was stopped after making no progress under concurrent local Vitest workloads. Turbopack rejected the external node_modules junction and Webpack did not reach the identity endpoint, so exact-head hosted UI and required CI remain the merge gates. No Supabase/OpenAI/live-provider checks run. |
| 2026-07-17 | codex/header-footer-scroll-timing-20260717 | 8298bfdcb40c207dbac1128e83c07b4aba782e32 | header and bottom-composer scroll timing, motion, responsive behavior, and merge readiness | Added deliberate hide/reveal travel thresholds with direction-reset handling, aligned header and composer easing/durations, and preserved reduced-motion and breakpoint behavior. No remaining high-confidence P0-P2 defect was found in the scoped diff or focused live behavior. | Focused Vitest 7/7; targeted Chromium UI 5/5; scoped ESLint; Prettier; full TypeScript; full lint; `git diff --check`. `verify:cheap` reached the aggregate Vitest phase, where two repository graph scans exceeded their 30-second test timeout under local disk contention; isolated assertions passed until the same timeout. No Supabase/OpenAI/live-provider checks run. |
| 2026-07-15 | HEAD / main snapshot (detached review worktree) | 0c56f27a37af88a073d2bb695d2cf4c05067ff4f | comprehensive repository review | Changes requested: two P1 defects (high-risk clinical claim support can accept a different trigger condition on lexical overlap; document-mode URL auto-run loops on navigation and leaves search loading indefinitely), one P2 supply-chain guard gap (the action-pin checker accepts mutable major tags and ignores SHA-pinned major versions), and one P3 orientation-doc gap (DSM and legacy specifier routes are absent from the codebase index). No P0 found. | Node 24/npm 11 and `npm ls --depth=0`; format, runtime, lint, TypeScript, sitemap/brand/icon/type-scale, docs links/scripts, CI/action/Codex guards; coverage 259 files passed/1 skipped and 2,417 tests passed/1 skipped; offline RAG 36 fixtures plus 282 tests; production build/client-secret scan; deployment boot smoke; critical Chromium 8/10 with two reproducible document-search failures; accessibility 5/5; viewport/focus checks through 1920x1080. Provider-backed governance, quality, drift, tenancy, hosted CI, and the cross-browser matrix were blocked or skipped by policy/targeted failures. |
| 2026-07-17 | PR #704 / codex/scroll-geometry-stability-20260717 | 35e74ddbd61bacc5b34f06efbd58091f092665fd | nested scroll-source review follow-up | Confirmed the outside-diff CodeRabbit finding: the standalone shell shared one intent history across main and descendant scroll containers, so a switch from a deep main offset to a near-zero nested offset could falsely reveal chrome. Scroll metrics now identify their source, source changes rebase direction and travel while preserving visibility, and unit/UI regressions cover the switch. No unresolved actionable review finding remains. | Focused Vitest 9/9; TypeScript; scoped ESLint; Prettier; `git diff --check`. Exact-head hosted CI and UI remain required after push. No Supabase/OpenAI/live-provider checks run. |
47 changes: 21 additions & 26 deletions src/components/ClinicalDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,6 @@ export function ClinicalDashboard({
mainRef.current = node;
setMainScrollRoot(node);
}, []);
const [bottomSearchScrollHidden, setBottomSearchScrollHidden] = useState(false);
const composerInputRef = useRef<HTMLInputElement>(null);
const scrollFrameRef = useRef<number | null>(null);
const navSyncLockRef = useRef<number | null>(null);
Expand Down Expand Up @@ -2831,7 +2830,11 @@ export function ClinicalDashboard({
if (frame) return;
frame = window.requestAnimationFrame(() => {
frame = 0;
reportPhoneScrollHideRef.current(main.scrollTop);
reportPhoneScrollHideRef.current({
offset: main.scrollTop,
maxOffset: Math.max(0, main.scrollHeight - main.clientHeight),
source: main,
});
});
};

Expand Down Expand Up @@ -3352,7 +3355,6 @@ export function ClinicalDashboard({
? { strategy: "overlay", allBreakpoints: true, scrollHidden: phoneScrollHide.hidden }
: { strategy: "collapse", scrollHidden: phoneScrollHide.hidden }
}
onBottomComposerScrollHiddenChange={setBottomSearchScrollHidden}
/>

<main
Expand All @@ -3378,30 +3380,23 @@ export function ClinicalDashboard({
? compactMobileModeHome
? "mb-0"
: // Phone answer view: the "Ask a follow-up" dock is fixed to the
// bottom, so <main> reserves room for it. When that dock hides on
// scroll, reclaim the reserved strip too — otherwise the near-black
// shell background shows through as an empty band. (sm+ is inert:
// bottomSearchScrollHidden only ever goes true on phones.) The
// reserve hugs the real dock height (follow-up scroll row + composer
// pill ≈ 6rem measured); the old 18rem reserve just painted extra
// shell background as a black band above the dock.
bottomSearchScrollHidden
? "mb-0 sm:mb-24"
: answerFollowUpSuggestions.length > 0
? "mb-[calc(7.5rem+env(safe-area-inset-bottom))] sm:mb-24"
: "mb-[calc(5.25rem+env(safe-area-inset-bottom))] sm:mb-24"
// bottom, so <main> reserves room for it. Keep that geometry stable
// while the dock translates off-screen: changing the flex item's
// margin alters its client height and clamps scrollTop near the
// bottom, feeding a false upward movement into hide-on-scroll.
answerFollowUpSuggestions.length > 0
? "mb-[calc(7.5rem+env(safe-area-inset-bottom))] sm:mb-24"
: "mb-[calc(5.25rem+env(safe-area-inset-bottom))] sm:mb-24"
: hasMobileBottomSearch
? bottomSearchScrollHidden
? "mb-0 sm:mb-0"
: compactMobileBottomSearch
? differentialsCompareAddonActive
? "mb-[calc(8.75rem+env(safe-area-inset-bottom))] sm:mb-0"
: "mb-[calc(5rem+env(safe-area-inset-bottom))] sm:mb-0"
: // Mode homes keep the composer in the hero (in-flow at every
// width), so phones need no bottom-dock clearance on them.
compactMobileModeHome || showDesktopHomeComposer
? "mb-0"
: "mb-[calc(5.25rem+env(safe-area-inset-bottom))] sm:mb-0"
? compactMobileBottomSearch
? differentialsCompareAddonActive
? "mb-[calc(8.75rem+env(safe-area-inset-bottom))] sm:mb-0"
: "mb-[calc(5rem+env(safe-area-inset-bottom))] sm:mb-0"
: // Mode homes keep the composer in the hero (in-flow at every
// width), so phones need no bottom-dock clearance on them.
compactMobileModeHome || showDesktopHomeComposer
? "mb-0"
: "mb-[calc(5.25rem+env(safe-area-inset-bottom))] sm:mb-0"
: "mb-0",
)}
>
Expand Down
27 changes: 16 additions & 11 deletions src/components/clinical-dashboard/global-search-shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ function GlobalStandaloneSearchShellClient({
}),
[query, searchMode, commandScopes, removeCommandScope, clearCommandScopes],
);
const [bottomSearchScrollHidden, setBottomSearchScrollHidden] = useState(false);
const { theme, toggleTheme } = useTheme();
const auth = useAuthSession();
const sidebarIdentity = useMemo(() => deriveSidebarIdentity(auth.session?.user.email), [auth.session?.user.email]);
Expand Down Expand Up @@ -430,7 +429,12 @@ function GlobalStandaloneSearchShellClient({
}

function handleMainScroll(event: UIEvent<HTMLDivElement>) {
phoneScrollHide.reportScroll(event.currentTarget.scrollTop);
const target = event.currentTarget;
phoneScrollHide.reportScroll({
offset: target.scrollTop,
maxOffset: Math.max(0, target.scrollHeight - target.clientHeight),
source: target,
});
}

const mainRefCallback = (node: HTMLDivElement | null) => {
Expand All @@ -448,7 +452,11 @@ function GlobalStandaloneSearchShellClient({
const target = event.target;
if (!(target instanceof HTMLElement) || !main.contains(target)) return;
if (target.scrollHeight <= target.clientHeight + 1) return;
reportPhoneScrollHideRef.current(target.scrollTop);
reportPhoneScrollHideRef.current({
offset: target.scrollTop,
maxOffset: Math.max(0, target.scrollHeight - target.clientHeight),
source: target,
});
};

main.addEventListener("scroll", onScrollCapture, { capture: true, passive: true });
Expand Down Expand Up @@ -564,7 +572,6 @@ function GlobalStandaloneSearchShellClient({
// Phone-only: #main-content owns vertical scroll, so hide-on-scroll
// collapses the header/composer to hand space back to content.
hideOnScroll={{ strategy: "collapse", scrollHidden: phoneScrollHide.hidden }}
onBottomComposerScrollHiddenChange={setBottomSearchScrollHidden}
queryInputAutoFocus={searchParams.get("focus") === "1"}
/>
</div>
Expand All @@ -582,13 +589,11 @@ function GlobalStandaloneSearchShellClient({
"min-w-0 focus:outline-none max-sm:flex max-sm:min-h-0 max-sm:flex-1 max-sm:flex-col max-sm:overflow-x-hidden max-sm:overflow-y-auto max-sm:overscroll-contain max-sm:[-webkit-overflow-scrolling:touch] sm:min-h-[calc(100dvh-4rem)] sm:overflow-x-clip",
!reservesFloatingComposer
? "max-sm:pb-[var(--mobile-composer-reserve)] sm:pb-8"
: bottomSearchScrollHidden
? "max-sm:pb-8 sm:pb-8"
: searchMode === "answer"
? "max-sm:pb-[var(--mobile-composer-reserve)] sm:pb-[calc(9rem+env(safe-area-inset-bottom))]"
: useCompactBottomSearch
? "max-sm:pb-[var(--mobile-composer-reserve)] sm:pb-8"
: "max-sm:pb-[var(--mobile-composer-reserve)] sm:pb-[calc(9rem+env(safe-area-inset-bottom))] sm:pb-8",
: searchMode === "answer"
? "max-sm:pb-[var(--mobile-composer-reserve)] sm:pb-[calc(9rem+env(safe-area-inset-bottom))]"
: useCompactBottomSearch
? "max-sm:pb-[var(--mobile-composer-reserve)] sm:pb-8"
: "max-sm:pb-[var(--mobile-composer-reserve)] sm:pb-[calc(9rem+env(safe-area-inset-bottom))] sm:pb-8",
)}
>
<div className="max-sm:flex max-sm:min-h-0 max-sm:flex-1 max-sm:flex-col">
Expand Down
7 changes: 0 additions & 7 deletions src/components/clinical-dashboard/master-search-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ export function MasterSearchHeader({
mobileLeadingAction = "menu",
onMobileBack,
hideOnScroll,
onBottomComposerScrollHiddenChange,
}: {
documents: ClinicalDocument[];
documentTotal?: number;
Expand Down Expand Up @@ -257,8 +256,6 @@ export function MasterSearchHeader({
/** Parent-owned hidden state for hosts that report scroll via React `onScroll`. */
scrollHidden?: boolean;
};
/** Fired when the phone bottom search dock enters or leaves the scroll-hidden state. */
onBottomComposerScrollHiddenChange?: (hidden: boolean) => void;
}) {
const visibleAppModeOptions = defaultVisibleAppModeOptions;
const trimmedQuery = query.trim();
Expand Down Expand Up @@ -333,10 +330,6 @@ export function MasterSearchHeader({
!scopeSheetOpen &&
!composerChromeFocused;

useEffect(() => {
onBottomComposerScrollHiddenChange?.(bottomComposerHidden);
}, [bottomComposerHidden, onBottomComposerScrollHiddenChange]);

useEffect(() => {
if (!loading || !commandDropdownOpen) return undefined;
const frame = window.requestAnimationFrame(() => setCommandDropdownOpen(false));
Expand Down
Loading