Skip to content

test(phone-scroll): split the 2100-line spec, and fix two coverage holes it exposed - #1466

Merged
BigSimmo merged 28 commits into
mainfrom
claude/ci-testing-review-2l8klp
Jul 31, 2026
Merged

test(phone-scroll): split the 2100-line spec, and fix two coverage holes it exposed#1466
BigSimmo merged 28 commits into
mainfrom
claude/ci-testing-review-2l8klp

Conversation

@BigSimmo

@BigSimmoBigSimmo commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Split tests/ui-phone-scroll.spec.ts (2104 lines, 56 tests) into three files over a shared tests/helpers/phone-scroll.ts. Test bodies moved byte-identical; the seam is the page-owner model docs/search-chrome-behaviour.md already defines.
  • Fixed a pre-existing coverage hole: nothing under tests/helpers/ was in uiPatterns, so editing a shared Playwright fixture skipped Production UI entirely.
  • Fixed scripts/phone-chrome-plan.mjs, whose ownership stage would have selected zero tests after the split.
  • Recorded that this split's stated justification is refuted — it does not rebalance the shards, and the measurement says why.
  • Separately: made the run-coordinator's JSON writes atomic (fecd190). Unrelated to the split, but it failed this PR's first Unit coverage run and is a real defect, not a re-roll candidate. Its own commit, independently revertible.

RAG impact: no retrieval behaviour change — nothing under src/lib/rag/**, clinical-search, retrieval-selection, ranking-config, answer-ranking, the eval harness, or the golden fixture is touched.

FileTestsCovers
ui-phone-scroll.spec.ts21shared shell header hide/reveal, per-mode top-edge release, universal collapse owner
ui-phone-scroll-routes.spec.ts19per-route breadth sweep (mode homes, dashboard scrollers, long pages)
ui-phone-scroll-page-owned.spec.ts16document-viewer composer, standalone frame-owned footers, calculators dock, Services canvas

The reason for this split is refuted, and that is the useful result

It was justified — in docs/process-hardening.md and in PR #1453 — as "the only lever that rebalances the shards, because --shard cannot divide a single file." Measured against a live server, it rebalances nothing:

BeforeAfter
Project total342 tests, 18 files342 tests, 20 files
Shard 1121 (56 phone-scroll)121 (56 phone-scroll)
Shard 2111 (0)111 (0)
Shard 3110 (0)110 (0)

--shard does not distribute files. It walks them in alphabetical collection order and cuts at test-count boundaries, so three siblings named ui-phone-scroll* sort adjacently and land in the same shard. The shards were already count-balanced — the imbalance is duration:

shard 1 121 tests / 10 files — phone-scroll(56), chrome-scroll(17), accessibility(15), overlap(14), …
shard 2 111 tests / 4 files — ui-smoke(92), route-coverage(12), specifiers(5), pwa(2)
shard 3 110 tests / 6 files — ui-tools(87), universal-search(16), stress(3), …

Shard 1 is slow because it holds ten slow-per-test files, while shards 2 and 3 are each dominated by one fast-per-test file. The only lever that would actually rebalance is explicit per-shard spec groups in ci.yml instead of --shard=i/N. docs/process-hardening.md now carries that trade rather than the change: perfect balance is ~7m37 against a measured 9m36 largest shard — about 2 min of a 13m39 critical path — bought with a hand-maintained file list in the required UI job whose miss mode is a spec silently running nowhere. It also carries a stop rule against the tempting hack of renaming specs to game the sort order.

Two coverage holes, both the "second hand-maintained list" shape

1. tests/helpers/** was invisible to ui_changed — pre-existing, and the more serious of the two. Three of the four files in that directory back ui-*.spec.ts journeys, and zero-touch.ts alone backs six of them including ui-smoke. Editing any of them reported ui_changed=false, so Production UI skipped and the change reached no browser at all, on a green pull request. Matched at directory level rather than by filename — a hand-list is exactly what failed here — and the one current non-UI file (supabase-round-trip-counter.ts) costs one extra UI run when it changes, against a miss that is silent.

2. scripts/phone-chrome-plan.mjs would have selected zero tests. Its ownership stage greps four journey titles out of ui-phone-scroll.spec.ts; all four moved to the page-owned file. Redirected, and phoneChromeBrowserSpecPattern widened so a changed sibling is recognised as a phone-chrome browser spec at all. playwrightHelper now includes the new shared fixture so editing it selects the phone-chrome plan.

Config regexes.playwright.config.ts's productionSpecPattern and testMatch both carried an exact phone-scroll alternative that matches neither sibling — they would have been collected by nothing. Both arms are now open (phone-scroll(?:-[a-z0-9-]+)?) so a future sibling runs rather than quietly not running, and tests/playwright-project-isolation.test.ts asserts every ui-phone-scroll*.spec.ts on disk is matched by both. It reads the regex literals out of the config source (the config cannot be imported — it resolves a base URL at module scope) and fails closed if either constant is renamed.

The coordinator write race (fecd190)

This PR's first CI run failed Unit coverage with SyntaxError: Unexpected end of JSON input at tests/test-runner-safety.test.ts:321, in "gives a queued heavyweight process priority over later focused work" — 4581 passed, 1 failed, and nothing in the split's diff goes near the run lock.

writeJson in scripts/test-run-lock.mjs published every coordinator record with a plain writeFileSync, and every reader of those records is concurrent by construction. The crash was the mild symptom: the coordinator's own reader has always swallowed the parse error (readJson returns null, queueRecords filters it out), so a torn read does not surface at all — the queued ticket simply disappears for that poll and hasTickets reports false while a queued exclusive waiter is sitting right there. That is the priority inversion the queue exists to prevent, and the tolerant reader was hiding it.

Now written to a sibling temp file and renamed over the target. renameSync is atomic within a filesystem; the temp name deliberately does not end in .json so listJsonFiles cannot pick it up mid-flight; a failed write removes the temp rather than leaving residue. The test's poll is also made tolerant, matching the coordinator's own reader — it was the only reader treating an unparseable file as fatal.

Verification

  • npm run test:e2e -- tests/ui-phone-scroll.spec.ts tests/ui-phone-scroll-routes.spec.ts tests/ui-phone-scroll-page-owned.spec.ts --project=chromium56 passed (4.3m), 0 failed, 16/19/21 per file
  • Collection parity against a live server: 342 tests in 18 files / 56 phone-scroll before, 342 tests in 20 files / 56 after
  • npm run verify:cheapTest Files 436 passed (436), Tests 4578 passed | 4 skipped (4582), exit 0
  • tests/test-runner-safety.test.ts run 5× consecutively — 27 passed each time
  • npm run check:ci-scope — self-test passes including the new playwright-shared-fixtures case
  • npx prettier --check .All matched files use Prettier code style!
  • node scripts/check-outstanding-issues.mjs144 rows (70 open, 74 archived), unique ids, next-id=147 above the highest

Two local failures were diagnosed and are not defects in this branch:

  • The first browser run failed 56/56 at browserType.launch in 3ms — that is #121 (container Chromium 1194 vs pinned 1234). The green result above is the re-run with PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/opt/pw-browsers/chromium.
  • A local verify:cheap failed installed-lock-parity with expected 10000000 to be less than or equal to 40000 — stale node_modules (brace-expansion 1.1.16) against the lockfile this branch merged from main's build(deps): patch brace-expansion denial of service #1456. npm ci --include=dev brought it to 1.1.18 and the gate passed. That guard did exactly its job.

verify:phone-chrome not run as a whole: its browser stage is the same three specs already run directly above, and its contract stage is inside the verify:cheap unit run.

Not run, deliberately: verify:release, eval:*, check:supabase-project are provider-backed and not authorised here.

Risk and rollout

  • Risk: low for behaviour, moderate for wiring — the split itself is a byte-identical move proven by a green 56/56 run and identical collection counts, but it moves files that four other places name. All four are updated in this diff and two of them now have guards. The tests/helpers/** widening can only cause Production UI to run more often, never less. The atomic write can only narrow a race.
  • Rollback: git revert any of the three commits independently. The uiPatterns widening and the coordinator fix are both independently valuable and address defects that predate this branch.
  • Provider or production effects: None. Test and CI-scoping code only; no application source, no schema, no provider calls.

Notes

#127 and #146 both cite the old file; their rows now name the new one, with the reminder that the exact test title is the durable identity because declaration lines drift.

The pattern across the last three changes on this branch is the same defect wearing different clothes: a list of spec or component names maintained in two places, where the copy that goes stale fails by running nothing rather than by going red. Three instances found in one day (mockup components, phone-chrome ownership journeys, shared Playwright fixtures). Each is now guarded individually; a general rule — that any list naming test files must be derived from or asserted against the filesystem — is probably the real fix, and is not attempted here.

Summary by CodeRabbit

  • Bug Fixes

    • Improved phone scrolling and browser chrome behavior across routes, standalone mode, and page-owned layouts.
    • Prevented focus loss, layout shifts, footer misplacement, and near-bottom hide/reveal oscillation.
    • Made CI queue records safer during concurrent reads and writes.
  • Tests

    • Expanded Playwright coverage for phone scrolling, pinned chrome, footer geometry, focus behavior, and route handling.
    • Ensured all phone-scroll test suites are collected and correctly included in affected test runs.
  • Documentation

    • Clarified Playwright shard assignment behavior and updated phone-scroll coverage guidance.

claude added 2 commits July 30, 2026 14:48
…les it exposed
`ui-phone-scroll.spec.ts` was 2104 lines and 56 tests — 267s, 65% of shard 1,
at the worst per-test rate of any large spec in it, and the file behind both
`#127` and `#146`. It is now three files over a shared
`tests/helpers/phone-scroll.ts`:
ui-phone-scroll.spec.ts 21 shared shell header hide/reveal,
per-mode top edge, collapse owner
ui-phone-scroll-routes.spec.ts 19 per-route breadth sweep
ui-phone-scroll-page-owned.spec.ts 16 document-viewer composer, standalone
frame-owned footers, calculators dock
The seam is the page-owner model docs/search-chrome-behaviour.md already
defines, not an arbitrary cut. Test bodies are moved byte-identical, and the
split is proven behaviour-neutral: 56 passed (4.3m) in Chromium, 16/19/21,
against 342 tests/56 phone-scroll collected both before and after.
THE STATED REASON FOR THIS SPLIT IS REFUTED, and that is recorded rather than
quietly dropped. It was justified — here and in PR #1453 — as the only lever
that rebalances the shards. Measured against a live server, it rebalances
nothing: shard 1/2/3 stay at 121/111/110 with all 56 still in shard 1.
`--shard` does not distribute files; it walks them in alphabetical collection
order and cuts at test-count boundaries, so three siblings named
ui-phone-scroll* land together. The shards were already count-balanced — the
imbalance is duration. docs/process-hardening.md now carries the measurement,
the real lever (explicit per-shard spec groups, ~2 min of a 13m39 critical path
against a hand-maintained list in the required UI job), and a stop rule against
renaming specs to game the sort order.
What the split does buy is a 2100-line file broken along ownership lines, and
the two coverage holes that fell out of doing it:
1. scripts/phone-chrome-plan.mjs greps four ownership journeys out of
ui-phone-scroll.spec.ts. All four moved to the page-owned file, so the
ownership stage would have selected zero tests. Redirected, and
phoneChromeBrowserSpecPattern widened so a changed sibling is recognised.
2. Pre-existing and worse: nothing under tests/helpers/ was in uiPatterns.
Editing zero-touch.ts — imported by SIX required browser specs including
ui-smoke — reported ui_changed=false, so Production UI skipped and the
change reached no browser at all, on a green pull request. Three of the four
files in that directory back ui-*.spec.ts journeys. Matched at directory
level: a hand-list is what failed, and the one non-UI file costs an extra UI
run against a miss that is silent.
playwright.config.ts's two spec regexes carried an exact `phone-scroll`
alternative that would not have matched either sibling. Both arms are now open
(`phone-scroll(?:-[a-z0-9-]+)?`) so a future sibling runs rather than quietly
not running, and playwright-project-isolation.test.ts asserts every
ui-phone-scroll*.spec.ts on disk is matched by both — reading the literals out
of the config and failing CLOSED if either constant is renamed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
…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
@coderabbitai

coderabbitaiBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

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

Next review available in:30 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: 2f886285-514e-4552-a8ea-7fa1e1395f8f

📥 Commits

Reviewing files that changed from the base of the PR and between 1878588 and 93cc68a.

📒 Files selected for processing (9)
  • docs/branch-review-ledger.md
  • docs/process-hardening.md
  • scripts/ci-change-scope.mjs
  • scripts/ensure-codex-cloud-git-remote.mjs
  • scripts/phone-chrome-plan.mjs
  • tests/codex-cloud-setup.test.ts
  • tests/test-runner-safety.test.ts
  • tests/ui-phone-scroll-page-owned.spec.ts
  • tests/verify-phone-chrome.test.ts
📝 Walkthrough

Walkthrough

Changes

Phone scroll coverage and execution hardening

Layer / File(s)Summary
Shared phone-scroll fixtures and UI coverage
tests/helpers/phone-scroll.ts, tests/ui-phone-scroll*.spec.ts
Phone-scroll utilities are centralized and used by expanded route, page-owned chrome, focus, footer, geometry, and near-bottom behavior tests.
Playwright collection and shard guidance
playwright.config.ts, tests/playwright-project-isolation.test.ts, docs/process-hardening.md, docs/search-chrome-behaviour.md
Phone-scroll filename matching and collection assertions are expanded, and shard behavior and documented coverage are corrected.
CI scope and phone-chrome routing
scripts/ci-change-scope.mjs, scripts/phone-chrome-plan.mjs, tests/verify-phone-chrome.test.ts
Shared helper changes now select UI and phone-scroll consumer coverage, with synchronization tests for the consumer list.
Atomic test-run record publication
scripts/test-run-lock.mjs, tests/test-runner-safety.test.ts
Coordinator JSON writes use temporary files and renames, while polling ignores temporarily invalid records.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels:codex

Suggested reviewers:cursoragent, claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 46.67% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the main change: splitting the phone-scroll spec and addressing coverage gaps it exposed.
Description check✅ PassedThe description follows the template with Summary, Verification, Risk and rollout, and Notes, and the nonclinical sections are filled out.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

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

@github-actions

github-actionsBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

CI triage

CI failed on this PR. Automated classification of the 2 failed job(s):

  • Production UI (1)needs investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • PR requiredneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.

Compared with main CI run #7314 (cancelled).

Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger.

claude added 2 commits July 30, 2026 15:14
`Unit coverage` failed on this PR's first CI run with
SyntaxError: Unexpected end of JSON input
tests/test-runner-safety.test.ts:321:31
in "gives a queued heavyweight process priority over later focused work" —
4581 passed, 1 failed, and nothing in this branch's diff goes near the run
lock. It is not this branch's flake, but it is a real defect and it was
blocking a required check, so it is fixed here rather than re-rolled.
`writeJson` published every coordinator record with a plain `writeFileSync`.
Every reader of those records is concurrent by construction — the queue exists
so separate processes can watch each other — so a reader can observe a file
half-written.
The crash was the mild symptom. The coordinator's own reader has always
swallowed the parse error (`readJson` returns null, `queueRecords` filters it
out), which means a torn read does not surface at all: the queued ticket simply
*disappears* for that poll and `hasTickets` reports false while a queued
exclusive waiter is sitting right there. That is the priority inversion the
queue exists to prevent, and the tolerant reader was hiding it.
`writeJson` now writes a sibling temp file and renames over the target.
`renameSync` is atomic within a filesystem, so a reader sees the old file or
the complete new one and never a fragment. The temp name deliberately does not
end in `.json`, so `listJsonFiles` cannot pick it up mid-flight, and a failed
write removes the temp file rather than leaving residue.
The test's poll is also made tolerant, matching what the coordinator's reader
already did — it was the only reader that treated an unparseable file as fatal.
It stays tolerant after the atomic-write fix because the test should measure
ordering, not write timing.
Verified: tests/test-runner-safety.test.ts run 5x, 27 passed each time.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
This was a REAL conflict, not staleness, and it is why PR #1466 had no `CI`
workflow run at all — only the four `pull_request_target` checks. GitHub could
not build refs/pull/1466/merge. That is #116's signature: a missing check list
is a conflict signal, not a green pass. `git merge-tree` exited 1 on
tests/ui-phone-scroll.spec.ts while `PR mergeability` still showed success from
before main advanced.
main's #1432 edited a hunk inside the `phoneOwner` loop — precisely the region
this branch moved to ui-phone-scroll-page-owned.spec.ts — so git saw one side
delete the region and the other modify it.
Resolved by taking this branch's shell-only ui-phone-scroll.spec.ts and
re-applying #1432's change at its new home. That change is a genuine flake fix
(sheet focus restoration retries after 50 ms when focus falls through to
<body>, so a bare blur races the retry and can re-pin the header), and dropping
it in a merge would have silently reintroduced the flake — the same
fails-by-running-nothing class this branch exists to close. It went to the
occurrence in the section-sheet round-trip, matched by the hunk's own context,
not the similar-looking line 95 lines earlier.
No content lost, proven rather than asserted: every non-trivial line of main's
ui-phone-scroll.spec.ts is present across the three split files plus the shared
helper. The only 22 differences are declarations that gained an `export `
prefix and the two imports whose path changed depth.
Verified on the merged tree: verify:cheap exit 0, Test Files 437 passed (437),
Tests 4588 passed | 4 skipped (4592); tsc --noEmit clean; prettier --check .
clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
@BigSimmo
BigSimmo marked this pull request as ready for review July 30, 2026 19:05
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 19:06

@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:6320250c6b

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadscripts/phone-chrome-plan.mjs
Second time a real conflict has blocked this PR's CI entirely — GitHub could
not build refs/pull/1466/merge, so no pull_request workflow ran and the thin
check list read as pending rather than blocked (#116).
Only docs/outstanding-issues.md conflicted; scripts/ci-change-scope.mjs and
docs/process-hardening.md auto-merged (main's regions are 150+ lines from this
branch's). Took main's ledger wholesale rather than hand-editing a 140-row
table around conflict markers.
Only ONE of this branch's two ledger edits was re-applied:
- #146 keeps its relocation note. The row is still open, and main's #1481 added
two further data points to it (head c739340, anchorTop expected -138 received
-7; six data points, two failures, shard 1 only) which are left untouched.
- #127's edit is DROPPED as obsolete. Main's #1487 archived that row, and the
archived form no longer cites tests/ui-phone-scroll.spec.ts at all, so there
is nothing left to relocate. Re-applying it would have matched nothing or
corrupted a differently-shaped row.
Marker is main's 149 (not this branch's 147): #149 was allocated, withdrawn and
retired rather than reused.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
@BigSimmo
BigSimmo disabled auto-merge July 30, 2026 19:16
claudeand others added 4 commits July 30, 2026 19:20
Codex P2 on PR #1466, and it is correct — this branch created the hole.
A change confined to tests/helpers/phone-scroll.ts is `playwrightHelper` scope,
which selects the focused ownership journeys: four grepped cases in ONE spec.
Before the split that was adequate, because the helper and every consumer were
the same file. After it, three specs import the helper and the plan named one:
[focused-browser] run-playwright ui-phone-scroll-page-owned.spec.ts
ui-smoke ui-tools --grep "phone browser results use
document scrolling|document detail header overlay…"
So a regression in a shared function — readGeometry, installFlipCounter,
dragScrollBy — passed `verify:phone-chrome`, the gate AGENTS.md names for
phone-chrome work, while two of the helper's three consumers never ran. CI
would still have caught it via ui_changed, but the local gate reported green,
which is the worse failure because it is the one people trust before pushing.
A change to the helper now expands to all three consumers and runs them in
full, as if each had been edited directly:
[changed-browser] run-playwright ui-phone-scroll-page-owned.spec.ts
ui-phone-scroll-routes.spec.ts ui-phone-scroll.spec.ts
--project=chromium
The redundant ownership grep drops out of focused-browser on its own, since
those journeys are now covered by a full run of their own file.
Two guards, because a hand-maintained list of spec names is precisely what
failed here and the miss does not go red — it runs nothing:
- the plan for a helper-only change must contain all three specs and no --grep
- the list must equal the specs that actually import the helper, read from
disk, so a fourth sibling cannot be added without updating it
Both mutation-proven: dropping a consumer from the list fails the parity test,
and reverting the expansion fails the plan test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
…onflict loop
Third consecutive real conflict blocking this PR's CI, always the same file,
and the fix is to stop touching it rather than to resolve it a fourth time.
main's newest commit is `fix(ledger): stop Prettier padding the issues table,
closing #133 (#1479)` — a whole-file reformat of docs/outstanding-issues.md.
Every row changed shape, so any edit to any row conflicts. That file is also
touched by nearly every main PR (row appends, archival moves), and this branch
is competing with a queue that merges several times an hour.
This PR's entire stake in it was ONE cosmetic line: a note on #146 saying the
cited spec moved to ui-phone-scroll-page-owned.spec.ts in the split. Three
CI-blocking conflicts — each one stopping GitHub building refs/pull/1466/merge
so no pull_request workflow ran at all — is a bad trade for that.
So the file is taken from main verbatim and the note is not re-applied. This
PR's diff no longer contains docs/outstanding-issues.md, which removes its only
remaining contact point with the hottest file in the repo.
Cost, stated rather than hidden: #146 keeps citing the old path. That row
already records that the exact test title is the durable identity because
declaration lines drift, so the stale path misleads nobody who reads it. The
note belongs in a docs-only PR when the ledger is not mid-reformat.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 20:08
@BigSimmo
BigSimmo disabled auto-merge July 30, 2026 20:13
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 20:17
@BigSimmo
BigSimmo disabled auto-merge July 30, 2026 20:24
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 20:30
@BigSimmo
BigSimmo disabled auto-merge July 30, 2026 20:32
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 20:40
@BigSimmo
BigSimmo disabled auto-merge July 30, 2026 20:42
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 20:44

CopilotAI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested change, apply t...

Fixed in fecd190-adjacent commit. The doc comment now names tests/playwright-project-isolation.test.ts as the actual guard and describes what it asserts — the references to the non-existent phoneScrollSpecFiles constant and check-phone-scroll-specs.mjs script are gone.

@BigSimmoBigSimmo added the skip-branch-sync Opt out of hosted pr-branch-sync / update-branch on this PR label Jul 30, 2026

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/process-hardening.md`:
- Around line 189-193: Specify the `text` language on the fenced code block
containing the shard listing, changing its opening fence while preserving the
listing contents and closing fence.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 38fb3b60-b31a-45b1-9da9-a536370a81a4

📥 Commits

Reviewing files that changed from the base of the PR and between db50738 and 1878588.

📒 Files selected for processing (13)
  • docs/process-hardening.md
  • docs/search-chrome-behaviour.md
  • playwright.config.ts
  • scripts/ci-change-scope.mjs
  • scripts/phone-chrome-plan.mjs
  • scripts/test-run-lock.mjs
  • tests/helpers/phone-scroll.ts
  • tests/playwright-project-isolation.test.ts
  • tests/test-runner-safety.test.ts
  • tests/ui-phone-scroll-page-owned.spec.ts
  • tests/ui-phone-scroll-routes.spec.ts
  • tests/ui-phone-scroll.spec.ts
  • tests/verify-phone-chrome.test.ts

Comment threaddocs/process-hardening.md Outdated
BigSimmoand others added 3 commits July 31, 2026 05:45
…f sleeping
Root-caused from the failure trace (run 30582678887 artifact 8775836025), not
inferred. Two snapshots either side of the resize:
before anchorTop -138 documentScrollTop 504 headerBottom 0
after anchorTop -7 documentScrollTop 504
`documentScrollTop` is IDENTICAL at 504. The scroll position never moved; the
content shifted down 131 px. And 131 is not arbitrary — the trace records
collapseHeight 72, and gotoPhoneSurface injects --safe-area-top:59px. 72 + 59 =
131. The resize transiently re-shows the shared header, which reclaims its
collapse row AND its safe-area band, and the assertion measured mid-transient.
The cause is the fixed `waitForTimeout(100)` immediately after
`setViewportSize`. That is the same sleep-and-hope pattern PR #1427 removed from
`addPhoneScrollRunway`, and it explains every observation #146 has collected:
- bimodal, never in between: the two states are "settled hidden" (-138) and
"header fully re-shown" (-7), nothing between them
- pixel-identical across runs: -138/-7/131 reproduced on three separate heads
and two different PRs, which timing jitter cannot do
- "under CI load": load pushes the settle past 100 ms, nothing more exotic
- documentScrollTop unchanged: only chrome layout moved
This also retroactively settles the narrowing that #146 WITHDREW. That row once
argued the scroll position held because the sibling documentScrollTop assertion
did not fail — invalid, since Playwright aborts at the first failing expect so
it never ran. The conclusion was right anyway: the trace shows 504 on both
sides. It is now measured rather than inferred.
The fix polls the same geometry the hidden-state assertions already use
(`header#search` bottom <= 1) with a 10 s budget and a message naming the
condition. The tolerance is untouched — #146's stop rule forbids loosening it,
and loosening it would have hidden a real 131 px content jump.
Note what this does NOT claim: if the header ever fails to re-hide rather than
merely settling slowly, the poll times out and the test fails naming that. That
is strictly better than a 100 ms coin flip either way.
Verified: the previously-failing test 3x consecutively (1 passed each), and the
full spec 16 passed (43.0s). Local passes are weak evidence for a load-dependent
race; the mechanism change is the argument.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHLPEV4o1rzipPDqshCSHY
@coderabbitai

coderabbitaiBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • docs/process-hardening.md

Commit:5bcef7d9e10ef385fa17bbc805c1c8727e8f9485

The changes have been pushed to the claude/ci-testing-review-2l8klp branch.

Time taken:2m 24s

Fixed 1 file(s) based on 1 unresolved review comment.
Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

Temporarily paused during the owner-authorized ordered merge sweep so main cannot move between exact-head review and merge. The branch and all commits are preserved; this PR will be reopened at its verified place in the queue.

@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

@cursoragent this PR will be re-opened soon. Please resolve any failing CI, run bugbot and resolve any bugbot comments against current repo and fix any merge conflicts and also fix any errors and address and fix all comments or suggestions that are likely to improve the PR and Codebase. Please implement smallest required fix according to best code practices. Check your work. Leave this PR closed for now but still make all these changes and run the review. I want it ready to go for when I re-open it.

@cursor

cursorBot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

PR #1466 is ready to reopen and remains CLOSED. Branch tip: f6a27bc6 (contains origin/main).

Done

  • Merged origin/main cleanly (was 7 behind).
  • Bugbot: no cursor[bot] findings.
  • Review threads: all 3 resolved (Codex helper consumers, Copilot doc refs, CodeRabbit MD040 — already fixed in tree).
  • Last hosted CI on the pre-close tip was green; closed PR UI still shows frozen head 5bcef7d until reopen.

Fixes landed

  1. phoneContract sibling missui-phone-scroll-routes / -page-owned now select contracts + phoneRelevant like the base file; pinned in verify-phone-chrome.test.ts (ae74f57e).
  2. Codex Cloud origin inspect — use configured remote.origin.url, not git remote get-url (insteadOf token rewrite was breaking verify:cheap here) (fa304a53).

Verification

Test Files 444 passed (444)
Tests 4652 passed | 4 skipped (4656)

prettier --check . pass · check:ci-scope pass · review ledger recorded for fa304a53.

On reopen, GitHub should move the PR head to f6a27bc6 and CI will re-run on that tip.

Open in WebOpen in Cursor

cursoragentand others added 5 commits July 31, 2026 00:13
Bring the closed PR tip current before reopen. merge-tree was clean; no
outstanding-issues.md stake on this branch.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
phoneChromeBrowserSpecPattern already recognised ui-phone-scroll-{routes,
page-owned}.spec.ts, but phoneContract still exact-matched only the base
file. A sibling-only edit therefore ran changed-browser while skipping
contracts and reporting phoneRelevant=false — the incomplete-gate half of
the same silent-miss class this PR closes. Widen the suffix arm and pin
sibling plans in verify-phone-chrome.test.ts.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
git remote get-url applies global url.*.insteadOf rewrites. Cursor Cloud
injects token insteadOf rules, so a credential-free origin appears
credential-bearing and ensureOriginRemote refuses to preserve it after
add — breaking the new origin-repair tests under verify:cheap. Read
remote.origin.url from config (the stored value) and assert the same in
tests.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Append-only review record for the closed-PR readiness pass: main merged,
phoneContract sibling fix, Codex Cloud origin inspect fix, review threads
cleared, Bugbot none. PR left closed.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Behind-but-clean sync for closed PR #1466 reopen prep. merge-tree was
clean; main tip is docs/outstanding-issues only (#1513).
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@BigSimmoBigSimmo reopened this Jul 31, 2026
@supabase

supabaseBot commented Jul 31, 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 ↗︎.

@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

@cursoragent This PR was just reopened. Do not merge, force-push, rebase, or arm auto-merge
unless I explicitly ask.

  1. Confirm GitHub is on the current branch tip (not the old closed head).
    Snapshot head SHA, behind/ahead, mergeable state, required checks, and
    unresolved actionable threads.

  2. Mergeability on this tip only:

    • Real conflict (merge-tree dirty): smallest fix, push.
    • Behind-but-clean: if required CI is in flight, wait and sync once late;
      otherwise sync once now. Prefer human/operator identity for update-branch;
      else git merge origin/main + push. No sync thrash.
    • Clean/current: leave it.
      Missing checks while mergeability is dirty ≠ green.
  3. Fresh required CI on this tip only — ignore pre-close rollup. On failure:
    smallest fix, push, re-check. Don’t rerun unless a fix landed or a check
    is stuck. No provider-backed gates without approval.

  4. New/unresolved actionable Codex/Bugbot/Copilot/human threads: smallest fix
    or short already-fixed/not-actionable reply, then resolve. Ignore
    rate-limit/summary noise.

  5. Stop when: merge-tree clean, no actionable threads, required checks green
    or clearly in progress on this tip. Report tip SHA, sync done/not needed,
    CI status, threads handled, residual risks. Leave the merge decision to me.

@cursor

cursorBot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

1. Snapshot (reopen)

Tip93cc68a9 (after sync; was a76601d5)
GitHub headmatches tip
Was1 behind / 27 ahead · GitHub CONFLICTING/DIRTY
merge-treeclean (false DIRTY — behind-but-clean)
Threads0 unresolved
Checks on old tiponly PR mergeability FAILURE + thin pull_request_target set (merge ref unbuildable)

2. Sync

Synced once: git merge origin/main + push (#1510). No content conflict (docs/branch-review-ledger.md auto-merged).
gh identity unavailable for update-branch; sync:pr-branches skipped this PR (skip-branch-sync label) — merge+push used instead.

3. CI on this tip

Fresh runs queued/in progress on 93cc68a9:

  • CI pending · Gitleaks/Semgrep queued · PR Policy in progress · mergeability re-queued
    Now MERGEABLE / BLOCKED (checks not finished). Pre-close rollup ignored.

4. Threads

None actionable. Prior Codex/Copilot/CodeRabbit threads stay resolved.

5. Stop

  • merge-tree clean vs origin/main (0 behind)
  • 0 unresolved actionable threads
  • required checks in progress on this tip

Tip:93cc68a9 · Sync: done once · CI: running · Threads: none · Merge: left to you

Residual: skip-branch-sync will block automated sync next time main moves; phone-scroll still lives in slow shard 1 (documented).

Open in WebOpen in Cursor

Reopened PR #1466: GitHub reported DIRTY/CONFLICTING while merge-tree was
clean (behind-by 1). Sync once so refs/pull/1466/merge can build and
pull_request CI can run. No content conflict.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@BigSimmo
BigSimmo enabled auto-merge (squash) July 31, 2026 00:56
@BigSimmo
BigSimmo merged commit be8c9ff into mainJul 31, 2026
25 checks passed
@BigSimmo
BigSimmo deleted the claude/ci-testing-review-2l8klp branch July 31, 2026 01:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-branch-syncOpt out of hosted pr-branch-sync / update-branch on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@BigSimmo@claude@cursoragent