Skip to content

refactor(rag): extract per-request hydration - #1463

Merged
BigSimmo merged 9 commits into
mainfrom
claude/x3-rag-coverage-gate-qx9j7d
Jul 30, 2026
Merged

refactor(rag): extract per-request hydration#1463
BigSimmo merged 9 commits into
mainfrom
claude/x3-rag-coverage-gate-qx9j7d

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

Pure structural extraction (X3 / #101, the next unit after #86's coverage gate): move the per-request hydration cluster out of src/lib/rag/rag.ts into a new src/lib/rag/rag-hydration.ts.

  • What moved, byte-for-byte: DocumentRankingMetadataCache, createDocumentRankingMetadataCache, attachDocumentRankingMetadata, withCachedIndexQuality, attachIndexQualityMetadata, attachPageVisualEvidence — one contiguous block at rag.ts:1478-1716 on d76b0f73. The only edit to any body is the export keyword added to the type and to createDocumentRankingMetadataCache, which now cross the module boundary. withCachedIndexQuality and attachIndexQualityMetadata stay module-private: nothing outside the cluster calls them.
  • Why the responsibility is cohesive: all six exist to hydrate already-retrieved SearchResult[] with data fetched per request — document labels/summaries, index quality, and page visual evidence — behind one bounded DocumentRankingMetadataCache that exists to stop the same document being fetched twice within a request. They share that cache and nothing else does; withCachedIndexQuality and attachIndexQualityMetadata are pure internals of that flow.
  • Cycle-free, verified not assumed: I diffed every free identifier in the cluster against rag.ts's own top-level declarations and the intersection was empty — the cluster referenced no rag.ts-local symbol at all. The new module's 11 dependencies all resolve to stable siblings (@/lib/types, @/lib/supabase/admin, @/lib/document-enrichment, @/lib/image-filtering, @/lib/reindex-pipeline, @/lib/rag/rag-answer-text, @/lib/rag/rag-source-block). No back-edge to rag.ts.
  • Public export strategy: rag.ts re-exports attachDocumentRankingMetadata and attachPageVisualEvidence (export { … } from "@/lib/rag/rag-hydration"), chosen deliberately to preserve the public @/lib/rag/rag API and avoid consumer churn — tests/rag-query-concurrency.test.ts dynamically imports both from @/lib/rag/rag and is unchanged. check:knip is clean with the re-export in place. rag.ts additionally imports createDocumentRankingMetadataCache and the DocumentRankingMetadataCache type, which it still uses in prepareCoverageGateResults and searchChunksWithTelemetry.
  • Seven import bindings orphaned by the move were pruned from rag.ts (ChunkImage, ClinicalImageUseClass, compactContextText, fetchRelatedDocumentMetadata, isCommittedGenerationMetadata, metadataText, normalizeImageBbox), each verified to have no remaining reference.
  • Budget ratcheted 4780 → 4543, preserving the existing "keep the reclaimed budget" intent.

This does NOT unblock prepareCoverageGateResults — and that was predicted

PR #1454 left prepareCoverageGateResults in rag.ts because it needs five rag.ts-only runtime symbols. The Codex review on PR #1461 correctly pointed out that hydration covers only two of those five, and shipping it confirms exactly that. The remaining three are a separate ranking/timing seam and are untouched here:

Symbol Location Why it is not hydration
selectRankedRetrievalResults rag.ts:1825 (pre-move) retrieval selection
applySecondStageRerankIfNeeded rag.ts:679 second-stage ranking
measureSearchPhase rag.ts:1975 (pre-move) shared pipeline timing wrapper — 21 references, only 2 are hydration phases

#086 and the X3 work order are updated to record this rather than repeat the earlier over-claim.

Files changed

File Change
src/lib/rag/rag-hydration.ts New module, six declarations (+252)
src/lib/rag/rag.ts Cluster removed, imports pruned, re-export added (+10 / −247)
scripts/check-maintainability-budgets.mjs rag.ts budget 4780 → 4543
docs/codebase-index.md RAG module-map row for rag-hydration.ts
docs/maturity-backlog-workorders.md X3 progress entry for #101
docs/outstanding-issues.md #086 updated: hydration shipped; ranking/timing seam still open

Line counts and movement evidence

  • src/lib/rag/rag.ts: 4780 → 4543 (−237), measured with sourceLineCount from scripts/check-maintainability-budgets.mjs.
  • Configured budget: 4780 → 4543. The gate reported 4780/4780 before and reports 4543/4543 now.
  • git diff --stat: 6 files changed, 289 insertions(+), 262 deletions(-).
  • git diff --color-moved=zebra: 239 of 262 added lines classified as moved; the 23 plain additions are imports, the header comment, and the two export keywords. The 8 plain removals are the pruned import bindings plus those same two declarations.
  • Total src/lib/rag/** LOC: 18141 → 18156 (+15) — ordinary import/export overhead. Each moved symbol is defined exactly once repo-wide; no pipeline body was duplicated.
  • Byte-identity verified by extracting rag.ts:1478-1716 from origin/main and diffing against the new module: identical modulo the two added export keywords.

Verification

  • npm run verify:pr-local

During development, use npm run verify:cheap as the faster iteration gate before the final PR-local preflight.

  • npm run verify:ui when UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changed
  • npm run verify:release before release or handoff confidence claims

For retrieval, ranking, selection, chunking, source/citation rendering, or answer-contract changes, verify:pr-local runs eval:rag:offline automatically. Run the offline command directly during iteration before spending a live eval.

  • npm run eval:retrieval:quality (must stay 36/36) when retrieval, ranking, selection, chunking, or scoring behavior changed — CI cannot run it (needs live keys), so run it locally and paste the summary. A metadata/governance-weighting change once buried correct docs (recall 1.0→0.76) and only this eval caught it.
  • npm run eval:rag -- --limit 15 + npm run eval:quality -- --rag-only when answer generation, the synthesis prompt, or answer post-processing changed (grounded-supported must not drop; citation-failure 0)
  • npm run check:production-readiness when clinical workflow, privacy, environment, Supabase, source governance, or deployment behavior changed
  • npm run check:deployment-readiness when deployment startup, hosting, or rollout behavior changed

UI verification not run: no UI, routing, styling, browser, reduced-motion, or forced-colors surface is touched — the diff is two src/lib/rag modules, a budget script, and three docs.

Verification not run (provider-backed, deliberately withheld): eval:retrieval:quality, eval:rag, eval:quality --rag-only, check:production-readiness, check:deployment-readiness all call live OpenAI/Supabase and none was run. No live evaluation and no RAG canary was run, because this is a zero-behaviour-change structural extraction: the moved bodies are byte-identical, no comparator, threshold, default, fallback, ordering rule, or await changed, and the byte-range diff against origin/main is the evidence. A reviewer who disputes that classification can refute it cheaply by re-running that byte-range comparison; if it is disputed, require a live canary pair before merge.

Gates run

Command Exit Decisive output
npm run typecheck 0 tsc --noEmit completed with no diagnostics
npm run lint 0 eslint --max-warnings 0 completed with no output
npm run check:knip 0 no unused/unlisted/unresolved/duplicate findings (one pre-existing .css hint)
npm run check:maintainability-budgets 0 [maintainability] src/lib/rag/rag.ts: 4543/4543 lines
npm run test -- tests/rag-query-concurrency.test.ts tests/retrieval-query-variants.test.ts tests/rag-tail-latency.test.ts tests/rag-shared-cache.test.ts tests/rag-variant-early-exit.test.ts 0 Test Files 5 passed (5) / Tests 83 passed (83)
npm run eval:rag:offline 0 Test Files 22 passed (22) / Tests 572 passed (572) / Offline RAG fixture and production-contract checks passed.
npm run check:outstanding-issues 0 144 rows (71 open, 73 archived), unique ids, next-id=147 above the highest
npm run format:check 0 All matched files use Prettier code style!
npm run verify:cheap 0 Test Files 436 passed (436) / Tests 4574 passed | 4 skipped (4578)
npm run verify:pr-local 0 ✓ Compiled successfully in 48s, Client bundle secret surface check passed., Offline RAG fixture and manifest validation passed (36 golden cases, 22 suites)
git diff --check 0 no whitespace errors

Risk and rollout

  • Risk: LOW for behaviour, MEDIUM for surface sensitivity — a protected RAG surface (src/lib/rag/**), so the surface is high-consequence even though the diff is a mechanical move. The residual risk is a mis-transcribed body, refuted directly by the byte-range comparison against origin/main and by 4574 green unit tests including the 36-case offline golden fixture set.
  • Rollback: a single-commit git revert restores rag.ts and the 4780 budget exactly. No data migration, no cache-format change, no persisted state.
  • Provider or production effects: None. No OpenAI, Supabase, Railway, live database, ingestion, answer-generation, deployment, or release operation occurred. GitHub was used only to fetch main, push this branch, and open this PR.

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

RAG impact: no retrieval behaviour change — pure module extraction

Notes

  • Zero intentional behaviour change: no owner or document scope enforcement, admission-before-scope ordering, retrieval ordering, released-result ordering, ranking comparator or comparator-key order, evidence selection, coverage threshold or default, cache semantics, abort semantics, conservative fallback, citation verification, numeric-grounding verification, source governance rule, telemetry name, timing boundary, error propagation, rollback behaviour, clinical behaviour, or provider behaviour was intentionally changed. The per-request cache's identity and lifetime are unchanged — rag.ts still constructs it and threads it through exactly as before.
  • Remaining coupling: rag.ts still owns prepareCoverageGateResults and the ranking/timing seam above. rag-hydration.ts has no back-edge to rag.ts.
  • Handoff: chore(deps-dev): bump prettier from 3.9.0 to 3.9.1 #98, perf: pre-compute query phrases once per rankAnswerEvidence call #99 and docs: record phase 6 re-audit #100 remain separate follow-up tasks and are untouched.

Generated by Claude Code

Move the per-request hydration cluster out of the rag.ts monolith into
src/lib/rag/rag-hydration.ts: DocumentRankingMetadataCache,
createDocumentRankingMetadataCache, attachDocumentRankingMetadata,
withCachedIndexQuality, attachIndexQualityMetadata, attachPageVisualEvidence.

All six move byte-for-byte; the only edit is the export keyword added to the
type and to createDocumentRankingMetadataCache, which now cross the module
boundary. withCachedIndexQuality and attachIndexQualityMetadata stay private —
nothing outside the cluster calls them.

The cluster referenced no rag.ts-local symbol, so the new module imports only
stable siblings and carries no back-edge. rag.ts re-exports
attachDocumentRankingMetadata and attachPageVisualEvidence so the public
@/lib/rag/rag API is unchanged for tests/rag-query-concurrency.test.ts. Seven
import bindings orphaned by the move were pruned from rag.ts.

This does not unblock prepareCoverageGateResults, which stays in rag.ts:
hydration covered only two of its five rag.ts-only dependencies. The remaining
three — selectRankedRetrievalResults, applySecondStageRerankIfNeeded and
measureSearchPhase — are a separate ranking/timing seam, as the Codex review on
PR #1461 predicted.

rag.ts 4780 -> 4543 lines; maintainability budget ratcheted 4780 -> 4543.

RAG impact: no retrieval behaviour change — pure module extraction

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGEBHp4Seoh1jK1vGTNtYS
@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 ↗︎.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

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: 36 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: d1ddf4a4-ec37-4e52-9c36-0e7d138724ca

📥 Commits

Reviewing files that changed from the base of the PR and between ee34b4d and 0e70a6a.

📒 Files selected for processing (5)
  • docs/codebase-index.md
  • docs/maturity-backlog-workorders.md
  • scripts/check-maintainability-budgets.mjs
  • src/lib/rag/rag-hydration.ts
  • src/lib/rag/rag.ts

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

@BigSimmo
BigSimmo marked this pull request as ready for review July 30, 2026 15:05
claude added 4 commits July 30, 2026 16:05
Resolves the docs/outstanding-issues.md conflict against #1441 and #1470. That
file deliberately carries no merge driver (#133), so overlapping edits conflict
loudly rather than being silently concatenated.

Resolved by the prescribed recipe: rebuilt the file from origin/main and
re-applied only this branch's own change (the #86 row's "Hydration SHIPPED
(#101)" edit). Verified the result has an identical row count and an identical
id set to origin/main, so #1470's closures were preserved and nothing was
dropped; the only content delta against main is that one row.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGEBHp4Seoh1jK1vGTNtYS
Second docs/outstanding-issues.md conflict, this time against #1459. That file
carries no merge driver by design (#133), so any overlapping edit conflicts.

Resolved by the same prescribed recipe: rebuilt from origin/main and re-applied
only this branch's own #86 "Hydration SHIPPED (#101)" edit. Verified identical
row count (144) and identical id set to origin/main, so #1459's ranking change,
withdrawn verification and restored row are all preserved; the only content
delta against main is that one row.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGEBHp4Seoh1jK1vGTNtYS
Third docs/outstanding-issues.md conflict, this time against #1462, #1467 and
#1482. That file carries no merge driver by design (#133), so any overlapping
edit conflicts; main is landing issue-ledger commits continuously.

Resolved by the same prescribed recipe: rebuilt from origin/main and re-applied
only this branch's own #86 "Hydration SHIPPED (#101)" edit. Verified identical
row count (146) and identical id set to origin/main, so the archived rows from
all three of those PRs are preserved and nothing was dropped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGEBHp4Seoh1jK1vGTNtYS
Fourth docs/outstanding-issues.md conflict. Same cause and same prescribed
resolution: that file has no merge driver by design (#133), main is landing
issue-ledger commits continuously, so every sync collides on it.

Rebuilt from origin/main and re-applied only this branch's own #86 "Hydration
SHIPPED (#101)" edit. Verified identical row count (146) and identical id set to
origin/main before committing, so no other session's rows were dropped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGEBHp4Seoh1jK1vGTNtYS
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 19:08
@BigSimmo
BigSimmo disabled auto-merge July 30, 2026 19:16
Fifth docs/outstanding-issues.md conflict. Applying the default announced to the
user after the fourth: drop the #86 "Hydration SHIPPED (#101)" row from this PR
rather than keep re-resolving it.

That file has no merge driver by design (#133) and main lands issue-ledger
commits continuously, so every sync collided on it — five conflicts, each
costing a full CI cycle, for one documentation line unrelated to the extraction.
This branch now takes origin/main's copy verbatim and no longer modifies the
file at all, making the PR immune to that churn.

Nothing else changes: rag-hydration.ts, rag.ts at 4543, the budget ratchet, the
codebase-index row and the X3 work-order entry all remain. The #86 row will be
recorded in a separate follow-up PR after this merges — the same pattern used
for #1454 via #1461.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGEBHp4Seoh1jK1vGTNtYS
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 19:41
@BigSimmo
BigSimmo merged commit dba7356 into main Jul 30, 2026
23 checks passed
@BigSimmo
BigSimmo deleted the claude/x3-rag-coverage-gate-qx9j7d branch July 30, 2026 19:48
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Both defects were raised by Codex on PR #1495 and both are real; verified
against the files before accepting.

1. #101 is NOT this extraction. docs/outstanding-issues.md:138 shows #101 is
   "Canary-gated retrieval parallelisation candidates" (P3, rec) — a separate,
   still-open recommendation gated on a live canary pair. Calling the hydration
   extraction "#101" marked that unrelated work as shipped and could have caused
   the live-evaluation work to be skipped. The label came from the original task
   brief and was propagated without checking it against the ledger. Both the
   #86 row and the X3 work-order entry now identify the change as the X3
   hydration unit (PR #1463) instead. #101's own row is untouched and still open.

2. The ledger row did not resolve. `npm run ledger:lookup --
   dba7356` returned NOT REVIEWED, because the
   ref cell held only the slash-form branch token and that branch no longer
   resolves locally, so the throttling record could not prevent a repeat review.
   Appended a superseding record keyed to the landed SHA; the same lookup now
   returns ALREADY REVIEWED. The original row is retained, per the ledger's
   append-only rule.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGEBHp4Seoh1jK1vGTNtYS
BigSimmo added a commit that referenced this pull request Jul 31, 2026
* issues: capture the unreadable-CI token, at-risk worktree work, and the unpushed hook fix

Three findings from the 2026-07-30 organisation session that were recorded
nowhere durable:

- #149 the session GitHub PAT lacks Checks: Read, so no agent can confirm a PR
  is green. The endpoint that does work returns an empty result rather than an
  error, so it reads like an absence of checks rather than an absence of
  permission.
- #150 four worktrees on already-merged branches hold uncommitted work that
  exists in no branch and no PR, the largest being +395/-200 across 19 files
  including CI config.
- #151 the pre-commit fail-open for #143 lives only on a never-pushed local
  branch, which is also 17 behind main and conflicts on the file whose count
  sentence main's new docs:update generator now owns.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(ledger): record the session-followup capture review for PR #1490

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(ledger): record #143/#151/#149 reconciliation for PR #1490

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs(ledger): supersede PR #1490 reconciliation after remote sync

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* issues: record the worktree snapshots and redirect #151 to PR #1494

#150 — the four at-risk worktrees were snapshotted onto their own already-merged
branches (748ef018f, 5dbd9f965, b7eae51a4, d949859c3), so the work survives a
worktree reclaim. All four are clean now. None is pushed or reviewed; the next
action is per-snapshot promote-or-reset.

#151 — the never-pushed branch is superseded rather than salvageable: its script
and hook reached main by other routes, so the fail-open guard was applied to
main's committed hook in PR #1494 instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: remove credential metadata and correct audit dates

* docs: consolidate session follow-up findings

* docs: record consolidated follow-up review

* issues: record that #101 hydration shipped

PR #1463 merged as dba7356, so #86's "Next X3 unit — rag-hydration.ts" is
now stale. The row records the extraction as shipped and keeps the corrected
boundary: hydration re-homed only two of prepareCoverageGateResults's five
rag.ts-only dependencies, so it did not unblock that function — exactly as the
Codex review on PR #1461 predicted.

This row was deliberately dropped from #1463 itself (commit 6290d02) after
docs/outstanding-issues.md conflicted on five consecutive main syncs. Recording
it separately here is the same pattern used for #1454 via #1461.

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

* docs(ledger): record the landed X3 hydration review

Appended with npm run ledger:append (never hand-written), keyed to the squash
commit dba7356 so ledger:lookup can resolve it.

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

* docs: fix the #101 mislabel and key the ledger row to a resolvable ref

Both defects were raised by Codex on PR #1495 and both are real; verified
against the files before accepting.

1. #101 is NOT this extraction. docs/outstanding-issues.md:138 shows #101 is
   "Canary-gated retrieval parallelisation candidates" (P3, rec) — a separate,
   still-open recommendation gated on a live canary pair. Calling the hydration
   extraction "#101" marked that unrelated work as shipped and could have caused
   the live-evaluation work to be skipped. The label came from the original task
   brief and was propagated without checking it against the ledger. Both the
   #86 row and the X3 work-order entry now identify the change as the X3
   hydration unit (PR #1463) instead. #101's own row is untouched and still open.

2. The ledger row did not resolve. `npm run ledger:lookup --
   dba7356` returned NOT REVIEWED, because the
   ref cell held only the slash-form branch token and that branch no longer
   resolves locally, so the throttling record could not prevent a repeat review.
   Appended a superseding record keyed to the landed SHA; the same lookup now
   returns ALREADY REVIEWED. The original row is retained, per the ledger's
   append-only rule.

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

* docs: record consolidated PR reviews

* docs: record ingestion recovery review

* docs(visual): document the platform-scoped baseline layout and how to seed it

`playwright.visual.config.ts` records snapshots under
`__screenshots__/{platform}/`, so a baseline taken on Windows lands in `win32/`
and is never consulted by the `ubuntu-24.04` CI job, which reads `linux/`.
Nothing said so, and committing `win32/` images looks like protection while
providing none.

Records the constraint, names the CI artifact as the supported recorder for
`linux/` baselines, and notes that comparison stays advisory until the jobs come
off `continue-on-error`. Also creates the tracked directory `.gitignore` already
claims exists, which sets `ui_changed=true` (`scripts/ci-change-scope.mjs`) so
the visual job can run and produce that first artifact.

No baselines are added here — they cannot be produced on this platform.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: correct visual baseline adoption steps

* docs: record visual baseline guidance review

* fix(ui): repair mockup accent token references

* docs: record token-reference repair review

* docs: archive advisory UI scoping task

* docs: record advisory UI closure review

* issues: archive #151 after #1494 and mark #143 fully resolved

PR #1494 landed the fail-open guard on main, so close the open salvage
row and update the #143 archive from PARTIAL to resolved across #1442
and #1494. Also carries the merge of origin/main that cleared the
GitHub DIRTY mergeability state.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs(ledger): record PR #1490 main-sync and #151 closeout

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs(ledger): record #1496 id-collision renumber for PR #1490

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* issues: record the withdrawn live-region finding as #151 so it is not re-filed

Archive-only row. There is no defect and no work to do — the row exists purely
as a guard rail against repeating a misreading that already happened once.

search-results-header-band.tsx sets aria-live={faulted ? "off" : "polite"} on
its count/status span, which reads like a silenced failure announcement. It is
not: the band mounts a separate fault panel with role="alert" carrying the
failure title, body and Retry, and the mute is deliberate so the two do not both
speak. The reasoning is in a comment directly above the attribute, and
tests/search-results-header-band.dom.test.tsx pins it with singular role queries
that throw on duplicates.

During session 2026-07-30 (PR #1481) this was filed as a real P2 defect on the
strength of the attribute alone, and the proposed fix — escalating the count span
to role="alert"/aria-live="assertive" — would have produced a duplicate
announcement and a red test, making it worse than no change. Codex caught it.
An earlier withdrawal row was then lost to the squash that merged #1481, which
is the row-deletion shape #148 now guards against.

Also records that the mockup's escalation is correct in the mockup and must not
be ported: search-refine-adaptive-mockups.tsx has no fault panel, so there the
count span is the only announcement channel.

#148 needed no work — the merge-base deletion check landed on main
independently, and its output now reports the base it compared against.

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

* docs(rag): record refuted lexical probe collapse (#98)

* issues: capture the residual id-allocation hazard as #151

#133 is resolved: #1444 removed merge=union and #1479 excluded the ledger from
Prettier, which together fixed conflict frequency. Neither changes id
allocation, which is still read-modify-write against the next-id marker, so
concurrent branches still claim the same number.

Measured on PR #1451: one row was renumbered #135 -> #141 -> #145 -> #147 ->
#149 across four sync cycles. The sharper finding is that GitHub's Update-branch
button resolved one such collision into duplicate #141 rows with the marker left
below main's highest id — git reported success and only
check:outstanding-issues caught it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(issues): attribute the mobile CLS breach — a 128px reserve round trip

#147 asked which elements shift. Driving Chromium against the same
offline production build with a PerformanceObserver on layout-shift
(Lighthouse mobile emulation, reading entry.sources[].node) gives one
dominant cause on all four breaching routes: the entire main content
region moves down 128px and straight back up 128px within 15-60ms. Both
moves score, so it is pure cost with zero net movement — 100% of
/documents/search's 0.220 and about 75% of /dsm's.

The shifting element is the max-sm:pt-[var(--phone-overlay-chrome-h)]
wrapper around <main>. A MutationObserver timeline on the root style
attribute pins the mechanism rather than inferring it: the property goes
CSS seed -> 200px -> 72px, and the 200px is written when the header
stack ALREADY measures 72px (t=1552ms reserve=200px stack=72, corrected
at t=1612ms). usePhoneOverlayChromeReserve reads stack.offsetHeight
while the stack is transiently tall, publishes a value that is stale by
the time it lands, and its ResizeObserver then corrects it.

The CSS seed at globals.css:375 is correct for the settled stack, which
corrects the mechanism recorded on the now-archived #130 — that framed
the defect as the seed under-reserving by 0-8px. Measured, the driver is
a 128px transient over-reserve written by the hook, not the seed. / is
the control: it never writes the property and is the one clean route.

Variance is stated rather than smoothed: /dsm measured 0.363 and 0.219
across two runs, and this harness has no network throttling so /forms
and /therapy-compass run high locally. Only /dsm, /documents/search and
/ reproduced the live dispatch exactly.

Also recorded: attaching a MutationObserver to document.documentElement
inside a Playwright addInitScript throws before the document element
exists, silently killing the CLS observer and reporting a uniform
CLS=0.000 — a false clean bill that voided one run of this harness.

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

* docs(ledger): record the #151 capture review for PR #1506

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(review): clarify snapshot branch state

* docs(ledger): record PR #1490 main sync after snapshot wording

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs: archive rendered style contract task

* docs: record style contract closure review

* docs: record synced style contract review

* docs: record post-121 style closure review

* docs: normalize style review ledger after sync

* docs: record post-1490 style closure review

* docs: record consolidated PR 1490 review

* docs: record replacement consolidation review

* docs: record reconciled consolidation review

* docs: record post-1511 consolidation review

* docs: normalize PR 1510 ledger after main sync

* docs: record PR 1510 post-sync review

* docs: correct false #98 canary evidence and NOTES triage

Remove the incorrect probe-collapse canary attribution from #98 and
point the unread --med-accent-soft note at #157 without breaking the
seven-token TOKENS_MISSING accounting.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs(ledger): record PR #1510 evidence-correction review

Supersede the prior approve-with-no-findings row after correcting the
false #98 canary attribution and NOTES triage drift.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs: keep concurrency note inside issue table

* docs: record post-1513 consolidation review

* docs: address CodeRabbit notes on PR #1510

Fix the computed-value-time wording in design-sync notes, give #33 a
unique recommended-queue order, and drop the duplicated #98 Done block.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs(ledger): record PR #1510 CodeRabbit fix review

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 5 <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.

2 participants