Skip to content

Land codex RAG_FIX work: ranking-layer de-weighting, frontend governance warnings, label-coverage hardening - #130

Merged
BigSimmo merged 4 commits into
mainfrom
codex/rag-fix-main-merge
Jul 2, 2026
Merged

Land codex RAG_FIX work: ranking-layer de-weighting, frontend governance warnings, label-coverage hardening#130
BigSimmo merged 4 commits into
mainfrom
codex/rag-fix-main-merge

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

Lands the codex session's final RAG_FIX working set (recovered verbatim from its handoff stash), merged with current main and reconciled against the relevance-first retrieval contract:

  • Ranking-layer metadata de-weighting: document_status / clinical_validation_status / extraction_quality now nudge instead of dominate ranking scores (answer-ranking sourceQualityScore, rag secondStageScore, clinical-search sourceQualityRankSignal / extractionQualityScore / statusBoost / routeSignal). Selection ordering itself remains metadata-free per the measured contract from PR RAG optimisation: answer quality (P1-P10), v17 numeric grounding, offline fallback, hybrid RPC hardening + golden-recall regression fix #118.
  • Frontend-visible governance warnings: frontendSourceGovernanceWarnings filters the dashboard warning strip to actionable codes (outdated_source, poor_extraction, weak_evidence); refusal and danger-warning behavior unchanged.
  • Label-coverage hardening: extended document-intent/patient-info/staff/operational/medication label term lists, label coverage checker improvements, new audit:source-governance script, backfill/classify script updates, expanded tests.
  • Build heap bump to 16 GB for next build.

Merge resolutions a reviewer should know

Verification

  • npm run verify:cheap — runtime, lint, typecheck pass; unit tests 821 passed / 2 skipped
  • Focused domain targets — retrieval-selection, source-governance, eval-quality, document-tags, document-organization: 51/51
  • npm run verify:ui — ui-smoke Chromium suite running at merge time; merge is gated on it (result posted as a PR comment)
  • npm run verify:release — not run (not a release)
  • npm run format:check — all files in this PR are Prettier-clean
  • npm run check:production-readiness — READY, 5 PASS
  • npm run check:deployment-readiness — no deployment/startup behavior changed

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use — refusal answer and danger-warning gating untouched
  • No patient-identifiable document workflow introduced or expanded
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy) — confirmed by check:production-readiness
  • Service-role keys and private document access remain server-only — no auth/access changes
  • Demo/synthetic content separation unchanged
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative — outdated/poor-extraction penalties retained in ranking; governance warnings still surfaced (UI strip filtered to actionable codes only); selection stays relevance-first per the measured golden-recall contract
  • Deployment classification/TGA SaMD impact considered: ranking weight changes move ordering toward relevance-first, the direction already validated by the golden retrieval eval in PR RAG optimisation: answer quality (P1-P10), v17 numeric grounding, offline fallback, hybrid RPC hardening + golden-recall regression fix #118; no new clinical claims or advice pathways added

Notes

  • Commits preserve provenance: codex WIP landed verbatim, merge resolutions and the fixture fix are separate commits with full rationale in their messages.

🤖 Generated with Claude Code

BigSimmoand others added 4 commits July 2, 2026 13:22
…overnance warnings, tags/labels hardening
Recovered verbatim from the main checkout stash 'codex/RAG_FIX uncommitted
work before switch to main (2026-07-02)', base 3eeb9b6.
- Reduce metadata/governance boost magnitudes in retrieval-selection
resultBoost, answer-ranking sourceQualityScore, and rag secondStageScore
so document status/validation/extraction metadata nudges rather than
dominates ordering; drop review_due and unverified penalties.
- Add frontend-visible source-governance warning filtering
(isFrontendVisibleSourceGovernanceWarning / frontendSourceGovernanceWarnings)
and surface it in ClinicalDashboard.
- Harden document tags/organization: expanded tag derivation rules,
organization badge fixes, label coverage checker improvements, and
backfill/classify script updates; extend matching tests.
- Add scripts/audit-source-governance.ts and the audit:source-governance
npm script; update retrieval-quality runbook and metadata debt snapshot.
- Bump next build heap to 16 GB.
Excluded deliberately: mockups/best/ screenshot set (20 MB of PNGs; repo
tracks no images) and its README reference, docs/backup-pr-111.md
(machine-local restore metadata), docs/codex-prompt-playbook.md (unrelated
doc). All remain preserved in the main checkout / stash.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…wins; keep ranking-layer de-weighting
Conflict resolutions (deliberate, per the measured relevance-first contract):
- src/lib/retrieval-selection.ts: took main wholesale. Main removed ALL
source-governance metadata weighting from selection ordering (golden
doc-recall@5 1.0 -> 0.76 when weighted) and replaced the old PR-111
hasRiskFlowchartActionSignal block with the next_step_or_action signal
mechanism hardened in PR #119. Codex's softened weights (0.003/0.004)
in this file were a weaker version of the same fix and were dropped.
- tests/retrieval-selection.test.ts: kept main's no-reordering contract
test and exact relevance-order assertions; kept codex's new
metadata-absent selection test; provisionally kept codex's
risk-flowchart displacement test pending the focused run.
- src/lib/clinical-search.ts: took main's zone-action risk-flowchart
rework (supersedes codex's simpler regex tweak), then reapplied codex's
metadata weight softening in the ranking-layer scores
(sourceQualityRankSignal, extractionQualityScore, statusBoost/
validationBoost, routeSignal) which main had not touched — ranking
penalties are where the contract says governance belongs.
- src/lib/document-organization.ts: kept codex's extended label term
lists (superset of main's in all five hunks) in main's formatting.
- src/components/ClinicalDashboard.tsx: import union (main's glyph
sanitizer helpers + codex's frontendSourceGovernanceWarnings).
Auto-merged but semantically reviewed: answer-ranking sourceQualityScore
and rag secondStageScore kept codex's softened weights (main had not
changed those lines since base).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codex bumped topScore/secondScore to 0.63/0.61 to suit its pre-merge
weights; under the merged (main) confidence-gate thresholds 0.63 is no
longer 'weak', so the gate correctly declines to block and the test
failed. Main's 0.6/0.58 fixture keeps the scenario inside the weak band
the test is about.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

UI smoke gate (ui-smoke.spec.ts, chromium): 29/29 passed locally on the PR head (2.5m). Combined with verify:cheap (821 unit tests), the focused domain targets (51/51), and check:production-readiness (READY), all planned gates are green.

@BigSimmo
BigSimmo merged commit d6af282 into mainJul 2, 2026
2 checks passed

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:763932079d

ℹ️ 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".

return frontendVisibleWarningCodes.has(warning.code);
}

export function frontendSourceGovernanceWarnings(warnings: SourceGovernanceWarning[]) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Filter frontend warnings before applying the warning cap

When /api/answer and /api/search call sourceGovernanceWarnings without a limit, the warning list is already capped at 8 before this frontend filter runs. If the first few sources produce only hidden routine notes such as review-due, unverified, partial extraction, low-index, or non-local warnings, they can consume the cap and any later outdated_source/poor_extraction warning will never reach the dashboard, so the user sees no actionable governance warning even though one exists. Please apply the frontend-visible filter before slicing, or request enough warnings for frontend filtering.

Useful? React with 👍 / 👎.

@BigSimmo
BigSimmo deleted the codex/rag-fix-main-merge branch July 2, 2026 08:12
BigSimmo added a commit that referenced this pull request Jul 2, 2026
…ata debt at 0.6 (#176)
* test(eval): scope danger-warning failures to answered routes; re-accept metadata debt
Two release-quality-eval governance fixes, no app-behavior change.
1. Danger source-governance warnings on unsupported (declined) routes are no
longer counted as failures. The app attaches a weak-evidence danger warning
when relevance verdict is "none", which on a refusal is the correct reader
signal ("no source-backed evidence, do not act"), not a governance failure.
The metric now counts danger warnings only on answered routes (a delivered
answer standing on dangerous sourcing). For genuinely out-of-scope cases the
warning's presence is positively asserted so a silent regression is caught;
for supported questions that were wrongly refused, the routing failure is
reported elsewhere and no misleading missing-warning noise is added.
Verified on the live release eval: source_governance_danger_failure_rate
0.225 -> 0, all 9 affected cases are correctly-declined out-of-scope queries.
2. Re-accept the bounded source-metadata debt at a 0.6 review-required ceiling
(expiry unchanged, 2026-07-31). The rate rose 0.14 -> 0.5398 with no corpus
change: the relevance-first ranking work (PR #118 / PR #130) removed
governance metadata weighting from selection ordering, so review-flagged
sources are no longer buried and the metric now reports true corpus state.
docs/source-review-priority-2026-07-02.md lists the 25 documents occupying
golden top-5 slots, highest-frequency first; reviewing the top 12 returns the
rate to ~0.12, after which the ceiling should be tightened back toward 0.2.
Note: the eval still reports separate blocking failures (grounded_supported,
one prompt-injection false-positive, citation, extractive latency) that are
pre-existing answer-quality regressions unrelated to these two changes and
tracked separately.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(eval): key danger-warning failures on grounded, not route (review fixes)
Addresses two automated review notes on the danger-warning reclassification:
- Exempt non-grounded refusals however they arise. finalizeRagAnswerQualityCore
can convert a fast/strong/extractive answer into an evidence-gap refusal by
setting grounded=false while preserving the original routingMode, so a
route-based check could still fail the gate on a declined answer. Key the
danger-warning failure on grounded === true (an answer was actually
delivered) instead of route !== "unsupported".
- Drop the toothless positive "missing danger warning" assertion. It only
surfaced in failed_cases and never fed a thresholded metric, so it could not
gate; making it gate would introduce new blocking failures on the current
corpus (e.g. close-title-noise), which we explicitly must not do. The
grounded-based check is the clean, robust core.
Behavior unchanged on the current corpus: danger rate stays 0 (all danger
warnings are on grounded=false refusals). Unit tests updated to cover the
finalize-core evidence-gap refusal path. vitest 8/8, typecheck + lint clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Fourth conflict in this file today. main advanced 30 commits and took #126 and
#127 for itself, so my rows renumber again to #128/#129/#130, marker 131.
Resolution is mechanical as always: main's file plus this branch's three
appended rows.
That is now four conflicts and four rounds of ID collision in one session,
which is the evidence #129 (the padding recommendation) rests on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Fifth conflict in docs/outstanding-issues.md today; mechanical again, and this
time with no id collision, so the three rows keep #128/#129/#130.
More importantly, the merge exposed a real defect. docs/branch-review-ledger.md
came out of it with **conflict markers inside an append-only file**, because
`.gitattributes` declares `merge=ledger` while the driver lives in git config
and is installed by postinstall — which this container skipped ("node_modules
matches the lockfile, skipping install"). `git merge` never named the file;
only `npm run check:branch-review-ledger` caught it. Committing that would have
corrupted the file the guard exists to protect.
Fixed by running `npm run hooks:install`, re-merging the ledger with the driver
active (union: my row plus main's three, no duplicates), and running
`npm run ledger:dedupe` as AGENTS.md requires after a driverless main sync.
Recorded as #131 with the concrete next step: have the ledger guard fail when
the attribute is declared but the driver is unset, so the environment is caught
before a merge rather than after.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Sixth conflict today, and the first that auto-merged *wrongly*: git's text
merge concatenated both tables, duplicating all 63 open rows. PR #1421 had
landed on main using #128/#129/#130 — the exact id collision #112 describes —
so both sides had those ids with different content and the merge kept both.
`npm run check:outstanding-issues` caught it and stated the correct resolution
verbatim: renumber the incoming rows above the marker and bump it, rather than
taking one side wholesale and dropping the other's rows. Done exactly that —
main's table is authoritative, this branch's four rows renumber to
#131/#132/#133/#134, marker to 135. Verified both sides' rows survive:
main's #128-#130 and mine are all present and distinct.
Worth noting main's new #129 (`update-branch` API does not honour the
`merge=ledger` driver) is the server-side twin of my #134 (the driver is absent
wherever `npm install` was skipped). Same root cause from two directions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
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 pushed a commit that referenced this pull request Jul 30, 2026
The `merge=union` driver on `docs/outstanding-issues.md` preserves concurrent
appends, but when both sides restructure the same region it concatenates them
wholesale. Merging the latest main did exactly that: every open row appeared
twice and both `issues:next-id` markers survived — 66 duplicate-id errors from
`check:outstanding-issues`, which is precisely the failure that gate exists to
catch (#112).
Resolved by rebuilding on main's canonical file rather than by hand-editing the
duplicated table: reset to `origin/main`, then re-apply this branch's five
captured rows at #131-#135 (main had advanced its allocation to #130 while this
branch was open, so the earlier #128-#132 numbering collided again) and
re-apply the #127 narrowing note. Marker bumped to 136.
Union merge cannot allocate unique ids; only the structural gate can catch when
it has produced an invalid file. It did.
BigSimmo added a commit that referenced this pull request Jul 30, 2026
…indings (#1424)
* docs(ledger): record PR #1400 closeout and capture three unrecorded findings
Documentation only — two ledger files, no code.
**Review closeout for PR #1400** appended with `ledger:append` (never
hand-written), recording the 17 findings fixed, the verification behind each,
and the post-merge check that all 8 commits are ancestors of main with the 4
changed files byte-identical.
**Three findings from that session that nothing else records:**
- `#125` — `@codex fix` produced 11 commits across a branch named `work`,
none fetchable, the same finding rewritten four times. It reads as success
while the branch is unchanged, which is the actual hazard.
- `#126` — both client-side push guards are inert for agent pushes:
`gh` absent makes the auto-merge sentinel fail open, and `core.hooksPath`
is set only by a local install. They protect the environment least likely to
need them.
- `#127` — this ledger's fixed-width padding makes one row's edit re-pad all
59, so it conflicts on nearly every main advance; each conflict silently
stopped all CI on #1400 via `#116`. Records that `merge=union` is the wrong
fix, with the evidence.
CircleCI was deliberately not filed — already captured as `#122`. Checked
before writing rather than after.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
* docs(issues): correct unsafe pull_request_target advice in #129
Review caught a real problem in the guidance I filed, not in code: #129's
next-action suggested moving *both* push guards server-side into a
`pull_request_target` job. That context carries secrets and a write token, and
a format check must execute PR-head code — including the dynamic
`prettier.config.*` this very PR taught the guard to load. That is the classic
privileged-context vector, and `.github/workflows/pr-policy.yml` already avoids
it deliberately by checking out only `github.workflow_sha`.
Corrected, and the row now records why the whole idea was unnecessary:
formatting is already enforced server-side by `Static PR checks` running
`format:check` on ordinary `pull_request` CI, so the guard's only unique value
is failing fast before the push. Only the metadata-only auto-merge sentinel
could safely live in a target job.
Bad advice in a durable ledger is worse than no advice — someone would have
acted on it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
* fix(issues): repair the duplicated table from the sixth main merge
Sixth conflict today, and the first that auto-merged *wrongly*: git's text
merge concatenated both tables, duplicating all 63 open rows. PR #1421 had
landed on main using #128/#129/#130 — the exact id collision #112 describes —
so both sides had those ids with different content and the merge kept both.
`npm run check:outstanding-issues` caught it and stated the correct resolution
verbatim: renumber the incoming rows above the marker and bump it, rather than
taking one side wholesale and dropping the other's rows. Done exactly that —
main's table is authoritative, this branch's four rows renumber to
#131/#132/#133/#134, marker to 135. Verified both sides' rows survive:
main's #128-#130 and mine are all present and distinct.
Worth noting main's new #129 (`update-branch` API does not honour the
`merge=ledger` driver) is the server-side twin of my #134 (the driver is absent
wherever `npm install` was skipped). Same root cause from two directions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
* docs: record PR 1424 review
---------
Co-authored-by: Claude <noreply@anthropic.com>
BigSimmo added a commit that referenced this pull request Jul 30, 2026
…t did (#1427)
* test(phone-scroll): prove the drag delivered before asserting the chrome hid
CI run 30518866604 failed `ui-phone-scroll.spec.ts:423` on
expect(getByTestId('universal-header-collapse'))
.toHaveAttribute('data-scroll-hidden', 'true') // received ""
after the full 10s auto-retry, and the classifier recorded it as "needs
investigation". The assertion was right; the scroll never happened.
`dragScrollBy` moved the scroller with `scrollTop +=`, which clamps silently
at the end of the range, and returned nothing. When a page lays out shorter
than the test assumed — content still settling under full-suite CI load — a
720px request delivers a fraction of that, the chrome correctly stays visible
because document-detail chrome only hides past `scrollTop > 120`, and the
failure surfaces ten seconds later looking like a product regression. The
helper also resolved the scroll owner once up front, so a mid-drag layout
change left it pushing an element that had stopped scrolling.
- `dragScrollBy` now re-resolves the owner each step and returns the distance
actually travelled.
- `dragScrollUntilHidden` waits for the remaining downward runway (a condition
wait, not a settle sleep), drags, and fails naming the shortfall if the drag
could not cross the threshold. Used at the four sites that assert a hide
immediately after a fixed-distance drag.
- `addPhoneScrollRunway` waits for its 1600px filler to reach layout instead of
sleeping 50ms. All 14 call sites already depend on that runway existing.
Every assertion is byte-identical: a genuinely stuck header still fails exactly
as before, once the drag is proven to have happened. No `.first()` was added
(#93's stop rule) and no tolerance was relaxed.
* ci: shard Production UI across three runners
Measured on 2026-07-30 from the Actions API, two full UI-scope PR runs
(30520443076, 30519912667): `Production UI` took 15m26-16m31 of a 16.8-18.6
minute run — 83-89% of wall clock — while every other job finished by minute 4
and then waited. Playwright itself reported `339 passed (13.5m)`; the balance is
the isolated production build.
That single job is also where the churn cost lands: 42% of PR runs in the
sampled window were cancelled (25 of 60 completed), almost all superseded
mid-Production-UI.
Sharding is across runners, not workers. `workers: 1`, `fullyParallel: false`
and `retries: 0` are unchanged inside each shard, so determinism is identical
and per-runner load falls — which matters because #93's duplicate page root is
load-dependent. `run-playwright.mjs` already forwards argv to `playwright test`,
so `--shard` needed no runner change.
The shard count is measured, not chosen. `fullyParallel: false` makes a spec
file indivisible, so shard sizes are lumpy and more shards is not monotonically
faster. Over the 340 required chromium tests:
N=3 -> 121/106/113 largest 121
N=4 -> 121/106/96/17 largest 121 (same critical path, one more runner)
N=6 -> 65/56/106/5/91/17 largest 106
N=5 -> 121/106/0/96/17 and N=8 -> two empty shards
N=4 buys nothing over N=3, and any N with an empty shard would go red because
`test:e2e:pr` deliberately omits `--pass-with-no-tests`. Expected critical path
~15.5 -> ~7 min, assuming per-test cost is roughly uniform.
`fail-fast: false` so a failing shard cannot cancel its siblings and re-create
the cancelled-vs-failed ambiguity #95 removed. Artifact names are shard-scoped
because upload-artifact runs with `overwrite: false`. Branch protection requires
only the `pr-required` aggregate, and `needs` on a matrix job yields the roll-up
of all shards, so the aggregate is unchanged.
Also adds `restore-keys` to both Playwright browser caches: without a prefix
fallback a lockfile bump forced a cold browser download in every UI job at once,
now three times over.
* ci: bound the codex auto-resolve jobs and serialise the visual config
Two inconsistencies found while mapping the pipeline, neither load-bearing but
both silent:
- `codex-autofix-review-comments.yml` was the only workflow in the repo with no
`timeout-minutes` on either job, so both inherited GitHub's 360-minute default
for work that reads PR metadata and posts one comment.
- `playwright.visual.config.ts` set neither `workers` nor `fullyParallel`, so it
inherited Playwright's default `workers = 50% of CPUs`. The production config
pins both to serial deliberately; the visual lane was quietly opting out of
the anti-flake posture the rest of the suite is configured for.
* chore(gates): pin the documented gate count to the real chain
Both numbers were wrong. `CLAUDE.md` said 24 static/consistency gates against an
actual 25 — `check:assets` landed before that line was written, so it was wrong
at authoring — and the `gates` skill said "check 2 of 26" against an actual 28.
A stale count is not cosmetic here. The skill's whole point at that line is that
`verify:cheap` stops at the first failure and everything after it never ran; an
agent that believes the chain is 26 long cannot say how much a mid-chain failure
skipped.
`check:gate-manifest` already derives the real count from
`verify:cheap:internal`, so it now asserts the documented numbers against it.
The assertions fail closed: if the anchor phrasing disappears, the guard reports
a lost anchor rather than passing on a document it no longer checks.
Mutation-proven: reverting the skill to "26" fails with
".claude/skills/gates/SKILL.md says 26 where the chain has 28".
* docs(issues): capture the CI review's deferred findings
Five items from the CI/testing review that should not be changed blind:
- #125 `ui_changed` matches all of `src/app`, so an API-only diff pays the
15-minute UI gate. Narrowing it can hide a real regression, so it needs a
decision plus a compensating check rather than a quieter filter.
- #126 the Playwright build writes to a per-run distDir, so Next's build cache
is cold every run (~2 min, now ~29% of the sharded critical path). Fixing it
means suppressing the runner's documented always-cleanup, which must not ship
without executing the runner.
- #127 the advisory UI lane spends ~3 min per UI PR on 5 mockup tests; there are
currently zero `@quarantine` tests for it to cover.
- #128 CI Triage is complete and self-tested but inert pending a repo variable.
- #129 four `changes` outputs are computed and consumed by nothing, and
`coverage_changed` fires on any non-doc file.
* docs(ledger): record the ci-testing-review pass at this HEAD
* ci: re-measure the shard split on the merged tree and refresh stale gate counts
The merge changed both numbers this branch had recorded.
Shard balance, re-measured against 342 required chromium tests (was 340):
N=3 -> 121/111/110 largest 121
N=4 -> 121/106/98/17 largest 121
N=3 remains correct — one 121-test spec group bounds both, so N=4 spends an
extra runner for the same critical path. The re-measure command is now in the
workflow comment so the next person does not have to rediscover it.
Gate counts: merging main added `check:gitleaks-pinned` and
`check:pr-mergeability` to `verify:cheap:internal`, so the documented counts
went stale the moment the merge landed — 25 -> 27 static, 28 -> 30 total. The
guard added earlier in this branch caught it immediately rather than letting the
docs drift again, which is the whole reason it exists.
Also records the `ui-critical-fast` interaction: the UI critical path is now that
15-test fail-fast job plus the slowest shard, not the full 13.5-minute suite, so
neither of this branch's pre-merge timings can be read on its own.
* docs(issues): rebuild the ledger after a union-merge duplication
The `merge=union` driver on `docs/outstanding-issues.md` preserves concurrent
appends, but when both sides restructure the same region it concatenates them
wholesale. Merging the latest main did exactly that: every open row appeared
twice and both `issues:next-id` markers survived — 66 duplicate-id errors from
`check:outstanding-issues`, which is precisely the failure that gate exists to
catch (#112).
Resolved by rebuilding on main's canonical file rather than by hand-editing the
duplicated table: reset to `origin/main`, then re-apply this branch's five
captured rows at #131-#135 (main had advanced its allocation to #130 while this
branch was open, so the earlier #128-#132 numbering collided again) and
re-apply the #127 narrowing note. Marker bumped to 136.
Union merge cannot allocate unique ids; only the structural gate can catch when
it has produced an invalid file. It did.
* ci: record the measured shard result, correcting the predicted one
First real run of the sharded shape (CI 30530618838, all green, whole run
13m39 against a 16.8-18.6 min unsharded baseline):
ui-critical-fast 15 tests 3m14
Production UI (1) 121 tests 9m36
Production UI (2) 111 tests 6m54
Production UI (3) 110 tests 6m20
The prediction was wrong by ~40%. ~6.8 min was expected for the largest shard
from 121/342 tests x 13.5 min; 9m36 happened. Per-test cost is not uniform —
111 tests took 6m54 while 121 took 9m36 — so a count-balanced split understates
the slowest shard whenever the slow specs land in one group. `--shard` can only
balance by count; balancing by duration would mean splitting the slow spec files
themselves.
The win is real but smaller than claimed, and the workflow comment and
process-hardening now carry the measured numbers plus the reason the arithmetic
misleads, so the next person re-measures instead of re-deriving.
Also merges origin/main. The ledger conflict was GitHub-visible only: that file
carries merge=union locally, which GitHub does not honour (#129). Resolved by
keeping the one genuinely new record and dropping three that main already had
elsewhere in the file — append-only forbids dropping a record that exists once,
not keeping a second copy. Superseding record appended for this HEAD, since the
prior one asserted a root cause that #127's trace evidence refutes.
* docs(issues): renumber this branch's rows above main's concurrent allocation
CI caught what I did not: `static-pr` failed on `check:outstanding-issues` with
#131-#134 duplicated and two `issues:next-id` markers.
Cause: main's PR #1424 allocated #131-#134 for its own findings at the same time
this branch held #131-#135, and `merge=union` did what union does — kept both
sides under the same ids. That is #112's documented limit: union preserves
concurrent appends but cannot allocate unique ids, so the structural gate is the
only thing that catches it.
My error was pushing without re-running that gate. The previous push resolved a
`docs/branch-review-ledger.md` conflict, and I validated only that file before
pushing to win the race against main — but the same merge also touched
`docs/outstanding-issues.md`. `verify:cheap` would have caught it locally.
Main's rows keep #131-#134 (already merged and referenced elsewhere); this
branch's five renumber to #136-#140, one marker at 141, and the cold-cache
cross-reference in process-hardening follows its row.
Two of main's new rows also make a planned addition here redundant: #134 is the
absent ledger merge driver and #133 is the outstanding-issues merge churn — both
hit during this branch's work, both already captured upstream, so nothing new is
filed for them.
* docs(issues): rebuild against main's current id allocation
The union merge duplicated the whole open and archive tables again (two header
rows, every id twice) because main restructured the file while this branch held
rows in it. Same resolution as before and for the same reason: rebuild on main's
canonical file rather than hand-editing a doubled table, then re-apply this
branch's five rows.
Main is now at next-id=135, so they land as #135-#139 with the marker at 140.
None of the five is duplicated upstream — checked by summary before re-applying.
This is the third renumber of the same five rows in one PR. That is not a
mistake being repeated, it is #133 ("outstanding-issues conflicts on nearly
every main advance") happening: any branch that holds rows in this file
re-collides every time main lands one. Worth weighing whether captures should
land in their own PR ahead of the work rather than riding along with it.
* docs: record PR 1427 review
---------
Co-authored-by: Claude <noreply@anthropic.com>
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Sync main, then update two rows against evidence rather than adding new ones.
#98: PR #1450 landed the counting proxy and answer-path budgets while this
branch was open. Verified rather than assumed — the helper counts on execution
not construction, tests/rag-round-trip-budget.test.ts pins two answer-path
scenarios plus three counter self-tests, and it is registered in the offline
contract fixture so it runs there. Ran it: Test Files 1 passed (1), Tests 5
passed (5). The row stays open with its Next narrowed to the two real gaps:
/api/search has no budget, and eval-rag-offline/test-rag-offline were not wired.
Also records the helper's own blind spot — it sees only traffic through the
wrapped client.
#130: already owns the unfiled pre-paint/cold-load guard, so its design goes
there instead of a new row. Records what the guard must test (the pre-paint
reserve seed, sampled before and after hydration rather than once after), why a
zero-inset profile is required for it to be able to fail at all, and that it
must be proven against the broken shape first. Also records the environment
blocker: browser gates cannot launch here per #121, and the symlink bridge
writes under /opt, which the sandbox refuses.
No new ids allocated; both are updates to rows that already own the work.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018K7sEKH35KZkWxvCnQcNN2
BigSimmo added a commit that referenced this pull request Jul 30, 2026
…gn (#1455)
* issues: close#122, capture the container Playwright pin mismatch
Three related ledger items, each independently revertible.
Close#122 (`ci/circleci: verify` fails on every branch). Its outcome allowed
either "trustworthy signal again, or it stops reporting"; the second happened.
`.circleci/config.yml` was deleted by 9779828 (PR #1412), and PR #1452's head
reported 21 check runs with none named `ci/circleci: verify`, so the status no
longer reports on new PRs. No operator log read is needed and the quota
hypothesis is retired unproven.
Capture #145: the remote container ships Chromium 1194 while the repo's
Playwright pin wants 1234, so every browser test dies at launch and zero
assertions run while the output reads like product breakage. This has cost time
twice — the 2026-07-30 handoff records 13 launch failures read as a code defect,
and #120 was filed on a gate reading taken under the same condition. The row
gives the start-of-session check and keeps the existing "never run
npx playwright install" stop rule.
Fix a stale rule found while verifying #122: AGENTS.md cited
`ci/circleci: verify` as a check that fails on unformatted files. It cannot
report again, so the rule now names `Static PR checks` and records the CircleCI
failures as history.
The outstanding-issues diff is 4 insertions / 3 deletions ignoring whitespace;
the rest is Prettier re-padding the archive table, because #122's original
summary is wider than that column and was kept verbatim.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018K7sEKH35KZkWxvCnQcNN2
* issues: fold the Playwright pin evidence into #121, drop duplicate #145
Codex review was right: #121 ("Container Playwright browser build lags the
pinned client") already tracks this exact condition — client 1234 versus
container 1194, every browser test failing at launch — so #145 created a second
canonical action for one problem. The row was allocated without first searching
the open table, which is the dedupe step the issues skill requires.
#145 is removed and its distinct content folded into #121: the reproduction on
main at c5c1a86, the fact that the condition has now been misread twice (the
handoff's 13 launch failures, and #120 filed as a gate defect under it), the
detection command to run before trusting a browser gate, and the stop rule
against filing a gate defect from a run whose tests never launched. #121's own
workaround, PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD note and open Next decision are
unchanged.
The id marker rolls back 146 -> 145 because #145 was never used by a live row.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018K7sEKH35KZkWxvCnQcNN2
* issues: record #98 delivery and #130 pre-paint guard design
Sync main, then update two rows against evidence rather than adding new ones.
#98: PR #1450 landed the counting proxy and answer-path budgets while this
branch was open. Verified rather than assumed — the helper counts on execution
not construction, tests/rag-round-trip-budget.test.ts pins two answer-path
scenarios plus three counter self-tests, and it is registered in the offline
contract fixture so it runs there. Ran it: Test Files 1 passed (1), Tests 5
passed (5). The row stays open with its Next narrowed to the two real gaps:
/api/search has no budget, and eval-rag-offline/test-rag-offline were not wired.
Also records the helper's own blind spot — it sees only traffic through the
wrapped client.
#130: already owns the unfiled pre-paint/cold-load guard, so its design goes
there instead of a new row. Records what the guard must test (the pre-paint
reserve seed, sampled before and after hydration rather than once after), why a
zero-inset profile is required for it to be able to fail at all, and that it
must be proven against the broken shape first. Also records the environment
blocker: browser gates cannot launch here per #121, and the symlink bridge
writes under /opt, which the sandbox refuses.
No new ids allocated; both are updates to rows that already own the work.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018K7sEKH35KZkWxvCnQcNN2
---------
Co-authored-by: Claude <noreply@anthropic.com>
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
…and #146
Conflict was docs/outstanding-issues.md only. Took main's copy wholesale (it
carries #122's closure and the #98/#130 records from #1455) and re-applied the
two one-line relocation notes, rather than hand-editing the conflict region.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Earlier today I recorded on #121 that a sandboxed remote session has only two
options for the Chromium 1194-vs-1234 mismatch: get the /opt write permission,
or decline to claim browser evidence. That was an over-generalisation from a
single blocked mkdir, and it is wrong.
PR #1432 landed a preflight whose own failure message names the route I had
missed: PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH, read by playwright.config.ts:11 and
honoured by scripts/playwright-browser-preflight.mjs:101. It needs no filesystem
write. Verified by launching rather than by reading the flag — the container's
existing 1194 headless_shell drives fine under the repo's Playwright 1.62 client
(version 141.0.7390.37, page rendered, boundingBox measured).
#121 keeps the wrong sentence with the retraction beside it, because which claim
was wrong and why is the part worth carrying forward. #130's recorded blocker for
the pre-paint guard is marked LIFTED: that guard is buildable in a remote session
after all. Also records #1432 itself, which no row referenced.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018K7sEKH35KZkWxvCnQcNN2
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
Both findings verified against the code before accepting, and both were right.
1. scripts/rag-offline-contract.mjs still described the suite as "the same guard
for /api/search". That is the same overstatement Codex caught in the test and
the ledger, and I had missed this third copy of it. The comment now says
retrieval core and names what the suite does not observe: the route's auth,
rate limiting, scope resolution, enrichment and telemetry write.
2. vi.doMock registrations survive vi.restoreAllMocks (which targets spies) and
vi.resetModules (which clears the module cache, not the mock registry), so the
Supabase/OpenAI fakes could outlive this file if isolation were relaxed.
afterEach now calls vi.doUnmock for both. This is the established pattern here
rather than a generic suggestion: five sibling suites already do it, and the
comment cites tests/rag-variant-early-exit.test.ts:110.
Also resolves the fourth docs/outstanding-issues.md conflict from main advancing,
by rebuilding the #98/#121/#130 edits on main's table and diffing row-id sets
against main to prove nothing was lost.
Focused suites after the change, including the neighbouring mock-sensitive ones:
Test Files 3 passed (3), Tests 9 passed (9).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018K7sEKH35KZkWxvCnQcNN2
BigSimmo added a commit that referenced this pull request Jul 30, 2026
… retract a wrong #121 claim (#1464)
Budget the search retrieval core: tests/search-round-trip-budget.test.ts pins
Supabase round-trip counts for searchChunksWithTelemetry, registered in the
offline contract. Scoped explicitly as retrieval-core, not an /api/search
endpoint budget — the route's auth, rate limiting, scope resolution, enrichment
and telemetry write are outside what it observes. One retrieval measures 11
round trips, with match_document_chunks_text_v2 and
match_document_table_facts_text_v2 each firing three times; whether that is
intended is left open on #98 rather than guessed at.
Retract a wrong claim on #121: a sandboxed remote session can produce browser
evidence via PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH, verified by launching. The
earlier "only two options" sentence is kept with the retraction beside it.
#130's blocker is marked LIFTED as a result, so the pre-paint guard is buildable.
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
The conflict was TWO lines — my side removed the open #130 row because it
moved to the archive table, main kept it. Taking my side; #130 remains a
single 5-cell archived row, #149 and #150 remain 7-cell open rows, and
main had claimed neither id (its marker was 149).
Worth recording the size: this same conflict before PR #1479 would have
been the whole 148-row table, because one row edit re-padded every row.
Un-padded it is 2 lines. That is the first conflict since #1479 landed and
it behaved exactly as the change predicted.
Verified: check:outstanding-issues 148 rows (57 open, 91 archived), unique
ids, next-id=151, no merge driver, no ids deleted from base; prettier clean;
no conflict markers remain.
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
…ge gaps (#1496)
* issues: close#130 by decision; capture the stale-install and reviewer gaps
#130 is archived because the owner decided not to pursue it, NOT because
the acceptance was run. The row says so in its first sentence, because a
"CLOSED" line is exactly the thing a future reader could mistake for
evidence: docs/phone-chrome-physical-acceptance.md on main is still the
blank template, and nothing in CI covers what it covers — headless Chromium
was explicitly stated as unable to certify Safari chrome-minimisation or
cold-launch PWA paint. Residual risk is unchanged and unmeasured, and the
row says to open a fresh one if phone-chrome misbehaves on a real device.
Two risks that surfaced during today's work were never written down, and
neither had an existing row (checked before adding, after creating a
duplicate earlier today by not checking):
#149 — the SessionStart hook reported "node_modules matches the lockfile"
while brace-expansion was installed at 1.1.16 against a lockfile pinning
1.1.18, the CVE-2026-14257 patch. Every local gate run in that window was
weaker than reported, including verify:cheap runs called green during
#1430/#1444. It surfaced only because installed-lock-parity asserts the
patched behaviour directly, and its failure was first misread as a
pre-existing repo defect because it also failed on clean main in the same
stale container. Notes that check:installed-lock-parity is only in
verify:ui, so the broad local gate cannot catch its own stale foundation.
#150 — CodeRabbit reviewed none of #1404, #1430, #1444, #1445 or #1479;
every comment was a spending-cap rate-limit notice that renders as ordinary
bot activity. Codex was the sole substantive reviewer and found three real
defects that survived local gates and self-review.
Fast checks run against this tree: check:runtime, check:installed-lock-parity
(now passing, confirming the drift is resolved), check:outstanding-issues,
check:branch-review-ledger and check:migration-role all PASS.
check:supabase-project and check:production-readiness fail only on absent
provider credentials, which AGENTS.md states is expected in demo mode.
Verified: check:outstanding-issues 148 rows (57 open, 91 archived), unique
ids, next-id=151, no merge driver, no ids deleted from base; docs:check-links
clean; whole-tree prettier clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XrPbbfU9yWuEjEVypCr4ZQ
* issues: correct #149 — parity check scope, not its placement
Codex review is right on both counts and this rewrites the row rather than
patching around it. The earlier text said check:installed-lock-parity lives
only in verify:ui and proposed adding it to verify:cheap; verify:cheap:internal
already runs it, so that follow-up was a no-op — and it ran green throughout
the stale window.
The real gap is scope. criticalInstalledPackages lists seven top-level names
(next, react, react-dom, eslint, playwright, typescript, vitest), so a stale
transitive dependency is invisible. Proved by faking node_modules/brace-expansion
back to 1.1.16 against the 1.1.18 lockfile pin: check:installed-lock-parity
exits 0. That also explains why both the hook and the gate reported parity
while the tree was stale — neither was looking at the package that drifted.
Next step is now to broaden the check (full tree, or a lockfile-hash install
stamp) rather than move it, and the row warns against reading a green parity
run as proof the install is current.
Verified: check:outstanding-issues 148 rows, unique ids, next-id=151, no ids
deleted from base; docs:check-links 1413 references; prettier clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XrPbbfU9yWuEjEVypCr4ZQ
---------
Co-authored-by: Claude <noreply@anthropic.com>
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>
BigSimmo pushed a commit that referenced this pull request Aug 24, 2026
…ping fix
The filter-sheet footer repair in 81178b8 was confirmed only against a
simulated safe-area inset in headless Chromium. #71NT23 records that no
container can supply real-device evidence here, and closed row #130 asked for
exactly this row to be reopened when phone chrome is reported wrong on a
device. Queues the acceptance as a request; the canonical ledger is untouched
and reconciliation happens on its own branch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AK4Z6hZFdLwy1mGuEEhk4f
Sign up for freeto 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.

1 participant

@BigSimmo