Skip to content

fix(chrome): overlay the phone header so hiding it never moves content - #1396

Merged
BigSimmo merged 43 commits into
mainfrom
claude/latency-findings-impl-s8g01v
Jul 30, 2026
Merged

fix(chrome): overlay the phone header so hiding it never moves content#1396
BigSimmo merged 43 commits into
mainfrom
claude/latency-findings-impl-s8g01v

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

Reported symptom: the phone header bar is choppy when it hides, and content is pushed up and down with it.

The cause was the hide mechanism, not its timing. Phones used collapse, which is a 1fr → 0fr grid on the header row plus a height transition on chrome-safe-area-top plus the reserve-pad padding-bottom transition. Every hide animated three heights and handed that layout back to the scroller, so content slid up underneath the animation. No amount of easing fixes that — the layout genuinely moves.

Overlay motion already existed, was already proven, and was gated to isDocumentViewerOwnedRoute(pathname). It translates the whole stack instead and charges zero released top geometry in readChromeCollapseMetrics, so content geometry never changes. Phones now use it on every route, which is why document detail already felt right and everything else did not.

  • global-search-shell.tsxphoneMotion: "overlay" unconditionally.
  • use-phone-overlay-chrome-reserve.ts (new) — overlay takes the stack out of flow (.phone-overlay-header is fixed in browser tabs, absolute in standalone), so content needs clearance or the first row sits under the chrome at scroll top. Publishes the measured stack height as --phone-overlay-chrome-h; the shell reserve pad reads it. It is measured, not tokenised, because the collapse row grows with page navigation portaled into header-collapse-addon and a fixed 4rem would clip those routes. It never varies with hide stateoffsetHeight ignores the hide transform, so one value is correct in both states, and a reserve that animated would reintroduce the exact shift this removes. It is only visible near scroll top, where the header is always revealed, so it costs no usable height.
  • master-search-header.tsx — portals the phone bottom dock out of the transformed layer. See below; this fixes a regression the overlay switch introduced.
  • docs/search-chrome-behaviour.md — the contract, since this is a governed surface.
  • header-scroll-hide-contract.test.ts — re-pointed at the new invariant, plus two new guards.

Correction — the overlay switch regressed the phone bottom dock

The first commit broke phone bottom search dock stays edge-to-edge with safe-area padding inside the form. This is worth recording because the failure mode is genuinely counter-intuitive.

The overlay hide translates the header stack, and a non-none transform — including translateY(0) at rest — makes an element a containing block for position: fixed descendants. searchComposer renders inside that stack, so on non-document routes the dock's bottom: 0 resolved against the ~72px header rather than the viewport and landed near the top of the screen. bottom still computed to 0px, which is what makes this read as a positioning puzzle rather than a CSS error. Measured as a form bottom 772px from the viewport bottom at 390×844 — exactly 844 − 72.

Document routes never hit it because their composer is DocumentViewer-owned and already portals to the frame footer host.

Fix: wrap the composer in PhoneFooterLayerPortal when phoneOverlayMotion && usesPhoneBottomDock. Phones host it on the footer layer; sm+ keeps it inline in the sticky [top bar | search] stack. That split matters — tablet may not double-sticky the composer, and a breakpoint-aware portal is the one mechanism satisfying both constraints. It is also the mechanism invariant 21 already requires of the DocumentViewer, calculator and differential footers, so this aligns the shell dock with the three footers that already do it.

Two alternatives were considered and rejected. Rendering the composer twice per breakpoint would satisfy the CSS but duplicate page-root data-testids, which is its own failure mode (invariant 17, and the live #093). Animating top instead of transform avoids the containing block, but changes the already-proven document-route path for no gain.

Verification

  • npm run verify:cheapTest Files 432 passed (432), Tests 4452 passed | 4 skipped (4456).
  • Focused Chromium phone-chrome journeys — 13 passed (34.0s), the exact set verify:phone-chrome selects for these files. Includes the dock-geometry test that caught the regression above, and both document detail header overlay and footer follow tests (browser + standalone PWA) that were failing in CI on Implement the free and flag-gated latency audit findings #1377.
  • typecheck, lint, prettier --check clean.
  • Both new guards were checked against the broken shape rather than assumed non-vacuous: reverting to the route-conditional collapse fails 3 assertions, and removing the portal fails the dock guard.

UI verification not run: npm run verify:ui could not execute in this container. npm run verify:phone-chrome escalates to it, and the container's Playwright browsers are build 1194 while the repo's client expects 1234, so every browser test failed at launch with Executable doesn't exist … chrome-headless-shell. I bridged that locally with symlinks under /opt/pw-browsers to obtain the focused proof above; nothing in the repo changed. The full verify:ui sweep and physical-device acceptance (docs/phone-chrome-physical-acceptance.md) are still outstanding — local Chromium cannot certify Safari or cold-launch PWA paint, and this change alters shared safe-area/ownership behaviour, so that checklist genuinely applies before merge.

Separately, and worth fixing independently of this PR: verify:phone-chrome exited 0 while reporting 13 failed tests, because every failure was a browser-launch error. A gate that returns success when no test ran is a green-when-broken gate on the phone-chrome path.

eval:retrieval:quality, eval:rag, eval:quality, check:production-readiness and check:supabase-project were not run: no retrieval, ranking, selection, chunking, scoring, answer-generation, privacy, Supabase or deployment behaviour changed. check:drift was not run because supabase/** is untouched.

Risk and rollout

  • Risk: Moderate, and concentrated in shared phone chrome rather than in any one page. Every phone route changes hide mechanism at once, which is the point but also the exposure. Mitigations: the mechanism being switched to is the one already shipping on document routes rather than a new one; content geometry is now provably constant across hide/reveal, which removes a whole class of clamp/oscillation risk the collapse budget existed to contain; and the 13 focused journeys cover browser and standalone PWA, answer, forms, differentials, calculators and document detail.
  • Residual risk is what local Chromium cannot see: Safari's own chrome minimisation and cold-launch PWA paint. Invariant 23 and the physical checklist exist precisely for this, and both remain to be done.
  • Rollback: revert the two commits. No migration, no schema change, no data change, no configuration change.
  • Provider or production effects: None. No OpenAI, Supabase or hosted-CI call was made in producing or verifying this change.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed

Notes on the above: this change moves chrome, not content. No answer generation, citation, verification, source-governance or document-access logic is touched, so source-backed claims and conservative source-metadata behaviour are unchanged by construction. No Supabase configuration is touched, so the pinned target is unaffected, and no credential enters the client graph — the new hook reads only element geometry and writes one CSS custom property. Nothing alters clinical decision-support behaviour, so the SaMD classification is unaffected. The one clinically-relevant property is legibility of the document surface, which improves: the reading position no longer shifts when chrome hides.

Notes

  • phoneMediaQuery is now exported from use-hide-on-scroll.ts rather than duplicated in the new hook, so the phone breakpoint keeps a single definition.
  • The reserve is applied to mobile-composer-reserve-pad rather than #main-content, matching the existing comment there: padding on the scrollport itself is omitted from scrollHeight in some flex/overflow combinations, while the inner block box includes it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Phone header motion now uses a consistent overlay experience across all phone routes.
    • Added automatic top-clearance measurement to keep page content positioned correctly as the header moves.
    • Improved phone search composer and bottom-dock behavior by keeping docked controls outside the animated header layer.
  • Bug Fixes

    • Reduced layout shifts and protected against incorrect content overlap during phone header transitions.
    • Documented and tracked browser verification issues, including false-success results and browser version mismatches.
  • Tests

    • Expanded coverage for universal phone overlay behavior, clearance handling, and bottom-dock placement.

claude added 2 commits July 30, 2026 02:35
Reported symptom: the header bar is choppy when it hides, and content gets
pushed up and down with it.

Cause: phones used the collapse mechanism, which is a 1fr -> 0fr grid on the
header row PLUS a height transition on chrome-safe-area-top PLUS the
reserve-pad padding-bottom transition. Every hide animated three heights and
handed that layout back to the scroller, so content slid under the animation.
No timing tuning fixes that -- the layout genuinely moves.

Overlay motion already existed and was already proven, but was gated to
isDocumentViewerOwnedRoute(pathname). It translates the whole stack instead
and charges zero released top geometry in readChromeCollapseMetrics, so
content geometry never changes. Phones now use it on every route.

Overlay takes the stack out of flow (.phone-overlay-header is fixed in
browser tabs, absolute in standalone), so content needs clearance or the
first row sits under the chrome at scroll top.
usePhoneOverlayChromeReserve publishes the measured stack height as
--phone-overlay-chrome-h and the shell reserve pad reads it.

Two properties of that reserve are load-bearing:
- measured, not tokenised, because the collapse row grows with page
  navigation portaled into header-collapse-addon and a fixed 4rem would clip
  those routes;
- never varies with hide state. offsetHeight ignores the hide transform, so
  one value is correct in both states; a reserve that animated or zeroed on
  hide would reintroduce the exact shift this removes. It is only visible
  near scroll top, where the header is always revealed.

Verified: typecheck clean; phone-chrome contract tests 67 passed; the new
guard was checked against the reverted route-conditional shape and fails
there (3 failures), so it is not vacuous. The browser gate
(verify:phone-chrome, which escalates to verify:ui) is still running at
commit time and its result is not yet included.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
Follow-up to the overlay switch in the parent commit, which regressed the
shell's phone bottom search dock.

The overlay hide translates the header stack, and a non-none transform --
including translateY(0) at rest -- makes an element a containing block for
position: fixed descendants. searchComposer rendered inside that stack, so on
non-document routes the dock's `bottom: 0` resolved against the ~72px header
instead of the viewport and landed near the top of the screen. `bottom` still
computed to 0px, which is what makes this read as a positioning puzzle rather
than a CSS error. Measured as formBottom 772px from the viewport bottom at
390x844 (844 - 72).

Document routes never hit it because their composer is DocumentViewer-owned
and already portals to the frame footer host.

Fix: wrap the composer in PhoneFooterLayerPortal when phoneOverlayMotion &&
usesPhoneBottomDock. Phones host it on the footer layer, sm+ keeps it inline
in the sticky [top bar | search] stack -- tablet may not double-sticky the
composer, and the portal is breakpoint-aware, which is the one mechanism that
satisfies both. Same approach invariant 21 already requires of the
DocumentViewer, calculator and differential footers.

Rejected: rendering the composer twice per breakpoint (duplicate page-root
data-testids are their own failure mode, invariant 17), and animating `top`
instead of transform (would change the already-proven document-route path for
no gain).

Verified with real Chromium: the 13 focused phone-chrome journeys all pass,
including both `document detail header overlay and footer follow` tests that
were failing in CI, and the dock geometry test that caught this regression.
verify:cheap: Test Files 432 passed, Tests 4452 passed | 4 skipped. New guard
checked against the un-portalled shape and fails there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 10 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 97d2199b-1d1b-43d5-a64e-aafecd377716

📥 Commits

Reviewing files that changed from the base of the PR and between 9c922c3 and 746a88e.

📒 Files selected for processing (11)
  • docs/branch-review-ledger.md
  • docs/outstanding-issues.md
  • docs/search-chrome-behaviour.md
  • scripts/phone-chrome-plan.mjs
  • src/app/globals.css
  • src/components/clinical-dashboard/global-search-shell.tsx
  • src/components/clinical-dashboard/master-search-header.tsx
  • src/components/clinical-dashboard/mobile-composer-reserve.ts
  • tests/header-scroll-hide-contract.test.ts
  • tests/ui-phone-scroll.spec.ts
  • tests/verify-phone-chrome.test.ts
📝 Walkthrough

Walkthrough

Phone search headers now use overlay motion on all phone routes, reserve measured top clearance, and portal bottom-docked composers outside transformed layers. Documentation, contract tests, issue records, and review ledger entries were updated accordingly.

Changes

Phone search chrome

Layer / File(s) Summary
Overlay clearance contract
src/app/globals.css, src/components/clinical-dashboard/use-phone-overlay-chrome-reserve.ts, src/components/clinical-dashboard/global-search-shell.tsx, src/components/clinical-dashboard/use-hide-on-scroll.ts, tests/header-scroll-hide-contract.test.ts
Adds the --phone-overlay-chrome-h token, measures it through a client hook, and applies the reserve to the phone search shell.
Universal phone overlay motion
src/components/clinical-dashboard/global-search-shell.tsx, docs/search-chrome-behaviour.md, tests/header-scroll-hide-contract.test.ts
Configures overlay motion for every phone route and updates the geometry and resting-state contract.
Bottom-dock composer portalling
src/components/clinical-dashboard/master-search-header.tsx, tests/header-scroll-hide-contract.test.ts
Portals the phone bottom-docked composer when overlay motion is active.
Review and issue records
docs/branch-review-ledger.md, docs/outstanding-issues.md
Adds reconciliation ledger rows and records two phone verification and browser-version issues.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GlobalStandaloneSearchShellBody
  participant usePhoneOverlayChromeReserve
  participant MasterSearchHeader
  participant PhoneFooterLayerPortal
  GlobalStandaloneSearchShellBody->>usePhoneOverlayChromeReserve: measure and publish phone overlay clearance
  GlobalStandaloneSearchShellBody->>MasterSearchHeader: configure phoneMotion as overlay
  MasterSearchHeader->>PhoneFooterLayerPortal: portal composer when overlay and bottom dock are active
  PhoneFooterLayerPortal-->>MasterSearchHeader: render composer outside transformed overlay layer
Loading

Possibly related PRs

  • BigSimmo/Database#1234: Modifies the same phone header, search-shell, safe-area, and scroll-hide contract paths.
  • BigSimmo/Database#1259: Changes the phone header hide/reveal and geometry contract in the same implementation and tests.
  • BigSimmo/Database#1270: Updates the shared phone composer portal and scroll/chrome placement flow.

Suggested labels: codex

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: switching phone header hiding to overlay motion to avoid content movement.
Description check ✅ Passed The PR description follows the template and includes summary, verification, risk, governance, and notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@supabase

supabase Bot commented Jul 30, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

…gaps

#112 (P2): verify:phone-chrome exited 0 while its own output ended
"13 failed". All 13 failed at browser launch, so zero assertions ran and the
gate still returned success -- the green-when-broken case AGENTS.md warns
about, in the gate that is meant to be the proof.

#113 (P3): the container's Playwright browsers are build 1194 while the
repo's client resolves 1234, so browser gates cannot run in a remote session
without hand-patching. Worked around in-session with symlinks under
/opt/pw-browsers; nothing committed, and it vanishes with the session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
@BigSimmo
BigSimmo marked this pull request as ready for review July 30, 2026 03:12
@BigSimmo

Copy link
Copy Markdown
Owner Author

@cursoragent Inspect the PR and repository state, identify the root cause of every failing CI check, unresolved review comment, merge conflict, and related defect. Apply the smallest robust fix using existing project patterns and best practices, without unrelated changes. Run Bugbot and all relevant lint, type-check, test, build, and CI-equivalent commands, fix any issues found, then resolve only the review comments that are fully addressed. Summarise the root causes, changes made, validation results, and any remaining blockers.

@cursor

cursor Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

PR #1396 is MERGEABLE again (9c922c34). The blockers were real docs/outstanding-issues.md ID collisions with main, not product chrome bugs. Hosted CI is still running on the tip.

Root causes

  1. Merge conflicts (real)main repeatedly claimed issue IDs this PR used for phone-chrome verification gaps (#112#114, then #115, plus table-width/#109 updates from #1394/#1402/#1398). GitHub DIRTY was content conflict, not stale-only.
  2. Codex P1s (already fixed on tip) — pre-hydration reserve/0px fallback and resting translateY(0) containing-block for the dock. Claude landed 8e003c84; both threads are resolved.
  3. CI cancellations — tip churn cancelled mid-flight Production UI / PR required on older SHAs (#095-style), not product failures.
  4. Bugbot — no cursor[bot] findings on tip; offline chrome scan found nothing actionable.

Changes made

  • Merged origin/main three times; kept main’s open table and retained this PR’s gaps as #116 / #117 (next-id=118).
  • Pushed merge + ledger records; no product code changes from this pass (Claude’s pre-paint fix already on branch).

Validation

  • verify:cheap: 432 files / 4460 tests passed (pre-final sync tip)
  • header-scroll-hide-contract: 28/28
  • typecheck, lint, prettier: clean
  • merge-tree vs origin/main: clean
  • Review threads: 0 unresolved / 3 total
  • Hosted CI on 9c922c34: still pending (Static / Unit / Build / Production UI / Advisory)

Remaining blockers

  • Wait for PR required green on exact tip 9c922c34 (do not treat cancelled older runs as product red).
  • Residual tracked debt: #116 (verify:phone-chrome green-when-broken) and #117 (Playwright browser build lag); physical-device acceptance still outstanding per PR notes.
Open in Web Open in Cursor 

Copy link
Copy Markdown
Owner Author

Two environment traps on this branch, from having just hit both. Flagging them because they will mislead a verification sweep rather than merely slow it down.

1. verify:phone-chrome returns exit 0 while its tests fail. On this branch it finished with exit code 0 and output ending 13 failed. Every one of the 13 failed at browser launch, so zero assertions ran — and the gate still reported success. Do not trust its exit status; grep the output for a real pass count. Filed as #112.

2. The container's Playwright browsers do not match the pinned client. The repo's client resolves headless-shell build 1234; this image provides 1194 under /opt/pw-browsers, and PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 means it cannot self-heal. Every browser test fails with:

browserType.launch: Executable doesn't exist at
/opt/pw-browsers/chromium_headless_shell-1234/chrome-headless-shell-linux64/chrome-headless-shell

Do not run npx playwright install (the environment forbids it). The workaround is to build the expected path as symlinks onto the 1194 binary and its sibling resources:

SRC=/opt/pw-browsers/chromium_headless_shell-1194/chrome-linux
DST=/opt/pw-browsers/chromium_headless_shell-1234/chrome-headless-shell-linux64
mkdir -p "$DST"
for f in "$SRC"/*; do ln -sfn "$f" "$DST/$(basename "$f")"; done
ln -sfn "$SRC/headless_shell" "$DST/chrome-headless-shell"
touch /opt/pw-browsers/chromium_headless_shell-1234/{INSTALLATION_COMPLETE,DEPENDENCIES_VALIDATED}

That is container-local, commits nothing, and does not survive the session. Filed as #113.

Verification already completed on 581dd31e, so it need not be repeated:

  • verify:cheapTest Files 432 passed (432), Tests 4452 passed | 4 skipped (4456)
  • Focused Chromium phone-chrome journeys — 13 passed (34.0s), the exact set verify:phone-chrome selects for these files, including both document detail header overlay and footer follow tests and the dock-geometry test
  • typecheck, lint, prettier --check clean
  • Both new contract guards checked against the broken shapes, so neither is vacuous

What is genuinely outstanding is the full verify:ui sweep and the physical-device acceptance in docs/phone-chrome-physical-acceptance.md. That second one is not a formality here: this change alters shared safe-area and ownership behaviour, and invariant 23 is explicit that local Chromium cannot certify Safari chrome minimisation or cold-launch PWA paint. No amount of headless work substitutes for it.


Generated by Claude Code

@BigSimmo

Copy link
Copy Markdown
Owner Author

@cursoragent Inspect the PR and repository state, identify the root cause of every failing CI check, unresolved review comment, merge conflict, and related defect. Apply the smallest robust fix using existing project patterns and best practices, without unrelated changes. Run Bugbot and all relevant lint, type-check, test, build, and CI-equivalent commands, fix any issues found, then resolve only the review comments that are fully addressed. Summarise the root causes, changes made, validation results, and any remaining blockers.

@cursor

cursor Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

PR #1396 tip 08d5be16 is merge-tree clean vs main, with 0 unresolved review threads. Hosted CI is re-queuing on that tip.

Root causes

  1. Static PR redmerge=union duplicated two exact #1394/#1399 ledger rows; check:branch-review-ledger failed.
  2. Merge conflictsdocs/search-chrome-behaviour.md (invariant 6: our overlay carve-out vs main #1393 surface paint) plus repeated outstanding-issues ID churn earlier.
  3. Codex P1s — pre-paint reserve/dock (already fixed); phone-scroll collapse asserts under unconditional overlay (Claude narrowed overlay via isCollapseMotionPhoneRoute; Services still asserted zero collapse height).
  4. CodeRabbit — invariant 6 wording; major asking to zero overlay reserve on hide (would reintroduce the bug).
  5. Bugbot — no cursor[bot] findings.

Changes made

  • Removed exact post-merge ledger duplicates (allowed by ledger contract).
  • Classified use-phone-overlay-chrome-reserve as shared phone-chrome foundation + test.
  • Reconciled invariant 6 / Scroll hide/reveal with overlay default + collapse exceptions + #1393 surface paint.
  • Gated Services “chrome releases” assert on data-phone-motion.
  • Synced origin/main; replied + resolved CodeRabbit/Codex threads that were fully dispositioned.

Validation

  • header-scroll-hide-contract + verify-phone-chrome: 37/37
  • check:branch-review-ledger: PASS
  • typecheck / lint: clean (earlier this pass)
  • merge-tree vs origin/main: clean
  • Review threads: 0 unresolved / 8 total
  • Hosted CI on 08d5be16: just started (no failures yet)

Remaining blockers

  • Wait for PR required / Production UI on exact tip 08d5be16.
  • Claude still flagged other overlay-route phone-scroll migrations (calculator near-bottom, Answer “complete top edge”, document-search focus). Services is fixed; those may still fail Production UI.
  • #116/#117 verification-infra traps and physical-device acceptance remain outstanding.
Open in Web Open in Cursor 

@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex review PR

Resolve docs/outstanding-issues.md by keeping main's #112#114 and
renumbering this branch's phone-chrome verification gaps to #115/#116
(next-id=117).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 581dd31eb4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/clinical-dashboard/master-search-header.tsx
Comment thread src/components/clinical-dashboard/use-phone-overlay-chrome-reserve.ts Outdated
@BigSimmo

Copy link
Copy Markdown
Owner Author

@cursoragent please resolve the comments and apply fixes from the comments and fix merge conflicts also

@cursor

cursor Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Resolved the open review work and the Production UI / merge blockers on #1396. Tip is 5d9bb64e, MERGEABLE, 0/8 unresolved threads.

Root causes

  1. Codex P1s (pre-hydration reserve + resting transform / dock portal) were already on tip — no product rework needed.
  2. Production UI red came from phone-scroll asserts still assuming in-flow collapse:
    • Answer mode has no collapse track (strategy: "overlay"), so usesCollapse was wrongly true.
    • Calculator near-bottom budget still charged overlay header height.
    • Focus test pre-scrolled to 40px, which hides overlay chrome (8px activation).
  3. GitHub DIRTY was main staleness (merge-tree clean); synced origin/main.
  4. Static PR riskmerge=union reintroduced an exact ledger duplicate; removed the later twin.

Changes

  • tests/ui-phone-scroll.spec.ts — overlay/Answer-aware asserts, reserve-only calculator budget, focus pre-scroll at 0, footer-host wait.
  • docs/branch-review-ledger.md — dedupe + closeout row.
  • Merge commit from main.

Validation

  • Focused Chromium phone-scroll: 9 passed (the previously failing set).
  • check:branch-review-ledger PASS; merge-tree clean vs main.
  • Hosted CI on tip is still in progress (BLOCKED on that only).
Open in Web Open in Cursor 

@BigSimmo

Copy link
Copy Markdown
Owner Author

@CodeRabbit review PR

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@BigSimmo: I’ll review PR #1396.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 03:28
@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

claude added 2 commits July 30, 2026 03:35
Fixes both Codex P1 findings. They share one root cause: the transform and
the reserve were applied at render time while their compensations only
arrived after hydration, so a cold load painted wrong and then corrected
itself -- a layout jump introduced by a change whose purpose is removing
layout jumps.

P1 (reserve): --phone-overlay-chrome-h did not exist until a passive
useEffect ran, and the utility fell back to 0px, so first paint put content
underneath the out-of-flow header and hydration pushed it down by the
measured stack height. Now seeded in globals.css as
calc(var(--safe-area-top) + var(--shell-header-h)) so it is never absent,
refined in useLayoutEffect so the measurement commits before paint, and the
0px fallback is gone. SSR cannot measure, so the seed is exact only for
routes without a header-collapse-addon row; addon routes refine by that
row's height, which is far smaller than the previous full-header jump but
not zero.

P1 (dock): PhoneFooterLayerPortal starts with isPhone=false, so on SSR and
first client render the composer rendered inline -- inside the stack that
carried max-sm:translate-y-0. The containing block existed from first paint
but the portal escaping it did not, leaving the dock header-anchored until
hydration. Fixed at the source by dropping the resting transform: the
revealed state is now transform-free, so no containing block exists at rest
and the dock is viewport-anchored in the server markup. The hidden state
keeps -translate-y-full, and a transition from none interpolates from the
identity transform, so the hide still animates. The portal stays as defence
for the during-hide window.

Also records why the earlier browser proof missed this: the 13 focused
journeys all assert after hydration, so a pre-paint shift is invisible to
them. Two new guards close that gap statically -- the CSS seed plus
useLayoutEffect, and no resting transform.

Verified: 13 focused Chromium phone-chrome journeys still pass (the hide
animation survives losing the resting transform); verify:cheap Test Files
432 passed, Tests 4461 passed | 4 skipped; typecheck, lint, prettier clean;
contract suite 28 passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
The contract still described PhoneFooterLayerPortal as the fix for the
containing-block trap. After 8e003c8 that is no longer the primary fix and
the doc would have taught the wrong thing: the portal starts with
isPhone === false, so it does nothing until hydration and cannot protect
first paint on its own. Resting-state-clean is the actual rule; the portal is
defence in depth for the during-hide window.

Also records the third load-bearing property of the reserve, which was
missing entirely: it must be correct before the first paint, hence the CSS
seed plus useLayoutEffect and no `,0px` fallback. Notes that SSR cannot
measure, so the seed is exact only for routes without an addon row.

Caught while reviewing my own change rather than by a reviewer, which is the
sweep I should have run after the previous three retractions in this branch's
history.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
@BigSimmo

Copy link
Copy Markdown
Owner Author

@Cursorsgent fix merge conflict

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4febc11bb7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/clinical-dashboard/global-search-shell.tsx Outdated
cursoragent and others added 7 commits July 30, 2026 04:36
Overlay/reserve-only hide activates after 8px, so the old 40px pre-scroll
hid the portaled dock before the click and timed out as outside-viewport.
Keep GitHub mergeability honest after main advanced; merge-tree was already clean.
Exact duplicate of the white-element-positioning pr-babysit record reappeared
via merge=union when syncing main; remove the later twin only.
The overlay-aware asserts in f2e7d3e/45f9aeb9 guarded with
`Boolean(collapse) && collapse.getAttribute(...)`. That reads as a null guard
but TypeScript does not narrow through a `Boolean()` call, so all seven
snapshot sites went red under TS 6.0.3:

  tests/ui-phone-scroll.spec.ts(997,42): error TS18047: 'collapse' is possibly 'null'.
  ... same at 1493, 1531, 1556, 1816, 1845, 1874

`collapse !== null && ...` narrows and is runtime-identical for
`HTMLElement | null`, so the overlay/collapse semantics those commits
established are unchanged: a missing collapse track (Answer mode's
strategy:"overlay") still reports usesCollapse false.

typecheck: exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
…01v' into claude/latency-findings-impl-s8g01v
…able

Every open PR sampled carries the same ci/circleci: verify failure, including
#1400 which is a docs-only AGENTS.md change, so it is not branch-specific. The
job's whole contents were mirrored locally on #1396's tip and all of it is
green, including the PyMuPDF-gated PDF tests under a venv built exactly as
.circleci/config.yml builds it. That puts the fault in the job environment.

Recorded with the quota hypothesis marked explicitly unverified: the CircleCI
project is private, no session has a CircleCI token, and the unauthenticated
API returns "Build not found". Reading the failing step needs an operator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF

Copy link
Copy Markdown
Owner Author

ci/circleci: verify is red repo-wide, not from this branch — and its log needs operator access

Saying this once rather than on each red. Filed durably as #118 in docs/outstanding-issues.md.

It is not branch-specific. ci/circleci: verify was failure on every open PR sampled — #1396, #1407, #1405, and #1400, which is a docs-only AGENTS.md change — plus #1403's head.

It is sharply bounded in time. #1393's head passed at build 638 (03:57). Builds 645 (04:09) onward all fail.

Everything the job runs is green locally on this PR's exact tip. .circleci/config.yml's verify job is format:checklinttypechecknpm run test:

  • format:checkAll matched files use Prettier code style!
  • lint — exit 0; typecheck — exit 0
  • npm run testTest Files 432 passed (432) / Tests 4473 passed | 4 skipped (4477)
  • the 4 skipped are tests/pdf-extractor.test.ts, the repo's only process.env.CI-gated tests and the one thing CircleCI runs that a local suite doesn't. I built the venv exactly as the config does (PyMuPDF==1.28.0) and ran them with CI=true and PYTHON_BIN pointed at it: Tests 6 passed (6).

So the fault is in the job's environment, not repo code. Around 40 builds fired in ~40 minutes across 8 open PRs in the regression window, so credit/quota exhaustion is my leading hypothesis — but I have not verified it, and I'm not claiming it. The CircleCI project is private, no agent session here has a CircleCI token, and api/v1.1/project/gh/BigSimmo/Database/<n> returns Build not found unauthenticated. Someone with CircleCI access needs to open one failing build and read the failing step; if it is quota, either raise it or drop the status so it stops masking real reds.

Separately, on this PR — a real failure that was ours, now fixed

Static PR checks went red on 5d9bb64e for a new reason, not the earlier ledger duplicate. The overlay-aware asserts in f2e7d3e0/45f9aeb9 guarded with Boolean(collapse) && collapse.getAttribute(...), which reads as a null guard but does not narrow in TypeScript — seven TS18047: 'collapse' is possibly 'null' errors at lines 997, 1493, 1531, 1556, 1816, 1845, 1874. Fixed in d73a7326 with collapse !== null && …, which is runtime-identical for HTMLElement | null, so the overlay/collapse semantics those commits established are unchanged.

Verified on the merged tip: typecheck exit 0, lint exit 0, format:check clean, check:branch-review-ledger passed (1292 records, no duplicates), and header-scroll-hide-contract + verify-phone-chrome 37 passed (37).

Production UI remains the outstanding check — it was 4 failed / 329 passed on 74ee177a, and the fixes for those four have not yet had a green run on a tip that also typechecks. That is what to watch next.


Generated by Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f79c91856c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/app/globals.css Outdated
claude and others added 6 commits July 30, 2026 04:58
Codex P1 (second round). My seed was calc(var(--safe-area-top) +
var(--shell-header-h)), but the overlay header pads its own top with
pt-[max(0.5rem,var(--safe-area-top))] while --shell-header-h (4rem) covers only
the inner min-h-14 bar plus its pb-2. The two classes sit on different
elements, so the padding genuinely adds.

Verified arithmetic rather than taking the report's figure: rendered height is
max(0.5rem, inset) + 3.5rem + 0.5rem, so the seed under-reserved by exactly
max(0, 0.5rem - inset). That is nothing on a notched iPhone, where the inset
already exceeds 0.5rem, and a full 8px on any phone reporting no top inset --
Android, and Playwright's default emulation. The layout effect then corrected
it after paint, which is the same cold-load shift this change exists to remove,
just smaller than the one the first round fixed.

Guards now pin both halves so they cannot drift apart: the CSS seed's max()
form, and the header's pt-[max(0.5rem,...)] it has to mirror.

verify:cheap: exit 0, Test Files 432 passed (432), Tests 4473 passed | 4 skipped.
Contract suite: 37 passed (37).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
Keep main's closed #115 and open #116. Remap this branch's ledger
additions to #120#122 to avoid colliding with PR #1404's #117#119.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
…01v' into claude/latency-findings-impl-s8g01v
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
…01v' into claude/latency-findings-impl-s8g01v
@BigSimmo
BigSimmo enabled auto-merge July 30, 2026 05:55
claude and others added 3 commits July 30, 2026 06:24
The 9df21db main sync re-duplicated the claude/white-element-positioning-t607pk
pr-babysit row (lines 1329/1335, byte-for-byte identical), failing
check:branch-review-ledger and with it Static PR checks and the PR required
aggregate. This is ledger #88 recurring on every main sync: merge=union keeps
both sides of a row that both branches appended.

Removing an exact duplicate is the one mutation the append-only contract
permits. Verified identical with diff before deleting the later copy.

check:branch-review-ledger: 1296 table records, no duplicates.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
@BigSimmo
BigSimmo merged commit 90b3e34 into main Jul 30, 2026
18 checks passed
@BigSimmo
BigSimmo deleted the claude/latency-findings-impl-s8g01v branch July 30, 2026 06:49
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Follow-up to the #1396 review. The overlay branch of this test was moved until
it passed, and nothing checked that its scroll position still exercised a
refusal, so it could have stopped guarding anything silently.

Derives both target offsets from computeScrollHideUpdate's own clauses instead
of chosen numbers, because the two motions refuse for different reasons:

  in-flow       runwayAfterCollapse <= revealIntentDistance + collapseRunwaySlack
  reserve-only  offset > postCollapseMaxOffset + bottomClampTolerance

Adds non-vacuity assertions ahead of the behavioural check. "Chrome stayed
visible" only evidences a refusal if the offset sat inside the refusal band and
the other clauses were satisfied. The load-bearing one is
postCollapseMaxOffset >= topRevealOffset + hideIntentDistance: without it, a
short post-collapse range refuses the hide on its own and the near-bottom clause
is never reached, so the test passes while proving nothing.

Renames the test. "96px of near-bottom runway" named collapseRunwaySlack, which
exists only on the in-flow branch; reserve-only has no slack term. One test
covers both owners, so the title now names the behaviour. Nothing outside the
definition referenced the old name, so no flake-ledger identity is broken.

No production hide policy changed — only what the test asserts about it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
PR #1396 repeatedly declared physical-device Safari/PWA acceptance
(docs/phone-chrome-physical-acceptance.md) as required before merge
because headless Chromium cannot certify Safari chrome minimisation
or cold-launch PWA paint, then merged with the checklist still blank.
Also notes a related missing pre-paint/cold-load hydration test the
same PR's review flagged but never filed.
BigSimmo added a commit that referenced this pull request Jul 30, 2026
… PR babysitting (#1421)

* issues: capture two CI/merge operational findings from PR babysitting

#117: this repo's CI (on: pull_request with default types) doesn't
retrigger on the draft-to-ready transition, only on
opened/synchronize/reopened — a marked-ready PR can sit with a
minimal check set until an actual new commit lands. #118: GitHub's
update-branch API doesn't honor the merge=union .gitattributes driver
on docs/branch-review-ledger.md, so it can 422 with a false conflict
that a local git merge resolves cleanly. Both observed today on PR
#1406.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Re9ERtQwJ82ErbAnahAhsa

* Address Codex review: clarify ledger rows #125/#126 wording

#125: spell out that ready_for_review must be added alongside the
existing pull_request.types defaults, not replace them.
#126: qualify the update-branch fallback push with the same
explicit user confirmation the provider boundary already requires.

* docs(issues): capture #1396's unaddressed physical-device chrome gate

PR #1396 repeatedly declared physical-device Safari/PWA acceptance
(docs/phone-chrome-physical-acceptance.md) as required before merge
because headless Chromium cannot certify Safari chrome minimisation
or cold-launch PWA paint, then merged with the checklist still blank.
Also notes a related missing pre-paint/cold-load hydration test the
same PR's review flagged but never filed.

* style: fix table padding drift from the main merge

npx prettier --write after merging main (9e2fe44) — a table cell
width shifted during the merge and format:check would have caught it.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Main's side carried #128-#130, archived #116 and reordered #117-#119, so it
is taken whole; only the #127 row is grafted from this branch, since main
still holds the withdrawn "sharedChromePinned is stuck" text. Marker stays
at main's 131. The file now reports `union merge active`, so this class of
collision should stop.

Also cross-links #130 into #127. PR #1396 ("overlay the phone header so
hiding it never moves content") merged at 06:49:55, about twenty minutes
before the first failure, and rewrote the exact overlay path this defect
sits in — phoneOverlayMotion, the overlay stack transition, and
readChromeCollapseMetrics charging zero released top geometry. Its merge
commit 90b3e34 is the single main run that passed, which fits the
passed-once-then-failed-twice-escalating shape better than the focus-latch
reading. #130 also records that #1396's own declared physical-device
prerequisite was never run, and that headless Chromium cannot certify what
it covers.

Verified after the merge: check:outstanding-issues 128 rows / unique ids /
next-id=131 / union merge active; check:branch-review-ledger 97 live + 1206
archived; prettier clean on all three changed files. Not re-run after the
merge: verify:cheap and the phone-scroll spec, which both passed on this
branch's own commit before it (434 test files / 4562 tests, and 56 passed).
The merge adds only main's already-verified tree plus one docs cell, so the
earlier evidence still covers this diff — but it is the earlier commit's
evidence, not this one's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XrPbbfU9yWuEjEVypCr4ZQ
BigSimmo added a commit that referenced this pull request Jul 30, 2026
…ottom refusal guard non-vacuous (#1423)

* docs(operator): correct the mislabelled ordering-safe documents index

My error, live in a merged runbook. The 2026-07-29 correction identified the
unordered LIMIT 12 in rag-candidate-sources.ts:482 as the RAG hazard, then
attributed it only to the trigram index and listed documents_status_id_idx as
ordering-safe. Re-reading the statement it describes:

  query = query.or(filters).eq("status", "indexed").limit(12);

One statement carries both the status equality and the unordered LIMIT 12, and
(status, id) is exactly the index serving that equality. So the mechanism the
doc already documents applies to it verbatim: a new plan can return a different
twelve title-alias rows into candidate assembly. It is canary-gated.

The generalisation that produced the error is worth naming, because it is the
trap: (status, id) has two consumers. search-scope.ts:271-277 pages with an
explicit .order("id") and is genuinely safe; rag-candidate-sources.ts:482 is
unordered and is not. Safety of one consumer is not transitive to the other.

Also marks the SQL block itself, which is what an operator actually copies. The
prose gated the indexes while the block still listed all three together with no
distinction, so a copy-paste run would apply the canary-gated ones regardless.

Gates: prettier clean; docs:check-links 1381 references resolve;
docs:check-scripts 395 npm-run references resolve. No code or SQL applied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF

* test(chrome): make the calculator near-bottom refusal non-vacuous

Follow-up to the #1396 review. The overlay branch of this test was moved until
it passed, and nothing checked that its scroll position still exercised a
refusal, so it could have stopped guarding anything silently.

Derives both target offsets from computeScrollHideUpdate's own clauses instead
of chosen numbers, because the two motions refuse for different reasons:

  in-flow       runwayAfterCollapse <= revealIntentDistance + collapseRunwaySlack
  reserve-only  offset > postCollapseMaxOffset + bottomClampTolerance

Adds non-vacuity assertions ahead of the behavioural check. "Chrome stayed
visible" only evidences a refusal if the offset sat inside the refusal band and
the other clauses were satisfied. The load-bearing one is
postCollapseMaxOffset >= topRevealOffset + hideIntentDistance: without it, a
short post-collapse range refuses the hide on its own and the near-bottom clause
is never reached, so the test passes while proving nothing.

Renames the test. "96px of near-bottom runway" named collapseRunwaySlack, which
exists only on the in-flow branch; reserve-only has no slack term. One test
covers both owners, so the title now names the behaviour. Nothing outside the
definition referenced the old name, so no flake-ledger identity is broken.

No production hide policy changed — only what the test asserts about it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01361jh3eYVjJCzXWjAhdZiF

* docs(issues): correct #102's stale ordering-safe claim for (status,id)

Codex review on this PR caught that docs/outstanding-issues.md #102
still called documents_status_id_idx ordering-safe after this PR's
own runbook correction reclassified it as canary-gated (its
rag-candidate-sources.ts consumer shares the RAG-hazard mechanism
with the trigram index; only the search-scope.ts ordered consumer
stays safe). Mirrors the runbook's exact corrected wording so an
operator following the ledger entry alone doesn't retain an
unguarded index.

* docs: record PR 1423 review

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants