Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d1043f0
Fix React hydration mismatches and add Playwright safeguards
BigSimmo Jul 24, 2026
a1437b8
Merge branch 'main' into codex/hydration-fixes
BigSimmo Jul 24, 2026
d52eb2d
Merge branch 'main' into codex/hydration-fixes
BigSimmo Jul 24, 2026
bbd4705
Fix typescript and knip CI failures
BigSimmo Jul 24, 2026
62d9fbc
Merge remote-tracking branch 'origin/main' into HEAD
cursoragent Jul 24, 2026
56a2447
fix: harden hydration guard
cursoragent Jul 24, 2026
dc62e9e
fix: format hydration support files
cursoragent Jul 24, 2026
43770fc
Merge remote-tracking branch 'origin/main' into HEAD
cursoragent Jul 24, 2026
58c26ba
Merge remote-tracking branch 'origin/main' into HEAD
cursoragent Jul 24, 2026
979a91b
Merge branch 'main' into codex/hydration-fixes
BigSimmo Jul 24, 2026
177aee8
Merge remote-tracking branch 'origin/main' into HEAD
cursoragent Jul 24, 2026
0ae33c5
fix: harden hydration warning guard
cursoragent Jul 24, 2026
8633723
Merge remote-tracking branch 'origin/main' into HEAD
cursoragent Jul 24, 2026
a145041
Merge remote-tracking branch 'origin/main' into HEAD
cursoragent Jul 24, 2026
e9d7093
Merge branch 'main' into codex/hydration-fixes
BigSimmo Jul 24, 2026
6c093e9
Merge branch 'main' into codex/hydration-fixes
BigSimmo Jul 24, 2026
43449d7
docs: record Run PR behind-main sweep for #1131
BigSimmo Jul 24, 2026
f545110
fix: sync theme cookie with bootstrap and useTheme
BigSimmo Jul 24, 2026
b8ebfbd
docs: ledger Run PR babysit for #1131
BigSimmo Jul 24, 2026
9351833
merge: sync origin/main into hydration-fixes
BigSimmo Jul 24, 2026
b4b5f21
docs: ledger post-main sync for #1131
BigSimmo Jul 24, 2026
af78e22
Merge remote-tracking branch 'origin/main' into codex/hydration-fixes
BigSimmo Jul 24, 2026
a29b0d7
fix(hydration): drop suppressHydrationWarning from skip link
BigSimmo Jul 24, 2026
5fbda07
docs: ledger re-sync sweep for PR #1131
BigSimmo Jul 24, 2026
8a6a4e1
Merge branch 'main' into codex/hydration-fixes
cursoragent Jul 24, 2026
21bdde7
fix(ledger): remove duplicate PR #1149 row after main merge
cursoragent Jul 24, 2026
d6b5d23
Merge remote-tracking branch 'origin/main' into HEAD
BigSimmo Jul 24, 2026
8315b03
fix(ci): remove duplicate hydration ledger row
BigSimmo Jul 24, 2026
9fef7aa
Merge remote-tracking branch 'origin/codex/hydration-fixes' into HEAD
BigSimmo Jul 24, 2026
7d7f751
Merge branch 'main' into codex/hydration-fixes
cursoragent Jul 24, 2026
90da1b8
fix(ui): drop unused LoadingPanel import after lazy-module merge
cursoragent Jul 24, 2026
0e0537b
Merge branch 'main' into codex/hydration-fixes
cursoragent Jul 24, 2026
e9e19a0
Merge branch 'main' into codex/hydration-fixes
cursoragent Jul 24, 2026
ec281a7
Merge remote-tracking branch 'origin/main' into codex/hydration-fixes
cursoragent Jul 24, 2026
555213f
test(ui): cover persisted hydration state
BigSimmo Jul 24, 2026
235bcdf
docs: record PR 1131 hydration coverage
BigSimmo Jul 24, 2026
3aa50e3
Merge branch 'main' into codex/hydration-fixes
BigSimmo Jul 24, 2026
9af5424
Merge remote-tracking branch 'origin/main' into codex/hydration-fixes
cursoragent Jul 24, 2026
146e94b
Merge remote-tracking branch 'origin/main' into codex/hydration-fixes
cursoragent Jul 24, 2026
b403cbf
Merge cursor/pr-queue-hygiene-72ec for postcss audit + PR branch sync
cursoragent Jul 24, 2026
b11e4de
Merge remote-tracking branch 'origin/main' into codex/hydration-fixes
cursoragent Jul 24, 2026
66289fd
Merge remote-tracking branch 'origin/main' into codex/hydration-fixes
cursoragent Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/branch-review-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,9 @@ This file is append-only. Never rewrite or delete an existing review record; app
| 2026-07-24 | cursor/search-performance-review-4ee9 (PR #1134) | 9311d01212fe42bd41ffb22a83bfa51f1a4d19f2 | Run PR re-sync sweep | Re-check: CONFLICTING on use-differential-catalog.ts (+ related). Not cheap; merge aborted, no push. | merge origin/main and/or conflict re-check only; no provider-backed checks run |
| 2026-07-24 | cursor/comprehensive-repo-review-ledger-d9a1 (PR #1150) | 60a3c3a83a31e65ec2759540629687e7113e2489 | Run PR sweep: CI fix + threads + drift | Before: CONFLICTING, CI green, 0 threads. After: merged origin/main cleanly (ledger auto-merge); pushed 60a3c3a83. Threads: none. Residual: CI re-running. | merge origin/main only; no provider-backed checks run |
| 2026-07-24 | cursor/search-interactive-perf-af54 (PR #1138) | ff4b293d95f922e70ebf5ee9b0c156c41a8bff3b | Run PR sweep: CI fix + threads + drift | Before: CONFLICTING, CI green, 0 threads. RAG impact: no retrieval behaviour change — PR is client deferred-search/UI only (no src/lib/rag/**). After: merged origin/main; conflict resolved in src/components/ui/sheet.tsx by keeping main restoreTimersRef/unmountingRef focus-restore fix; pushed ff4b293d9. Threads: none. | merge origin/main only; no provider-backed checks run |
| 2026-07-24 | codex/hydration-fixes (PR #1131) | 6c093e927d7b4f7261fb78160d85bdc407853001 | Run PR sweep: CI fix + threads + drift | Before: already contained origin/main. After: ledger-only record. Threads: non-P0/P1 left open. CI not waited. | merge origin/main only; thread scan read-only; no provider-backed checks run |
| 2026-07-24 | codex/hydration-fixes (PR #1131) | f5451102cc0f157d0f63a3679e532d02ae85918c | Run PR babysit: CI/threads/drift | Run PR babysit: Codex P2 theme cookie validated+fixed + thread resolved. Before: CI mostly green, 1 unresolved Codex P2 (3644928239; prior Codex claim not on this branch). After: cookie fallback in THEME_BOOTSTRAP_SCRIPT + useTheme write/clear + shared keys; reply+resolve PRRT_kwDOSh5Fis6TiAhF. Not behind main. | npx vitest run tests/theme.test.ts PASS (9/9). No provider-backed checks run. |
| 2026-07-24 | codex/hydration-fixes (PR #1131) | 93518331fd1839e773a0cb08d0e8425e502f876d | Run PR babysit: CI/threads/drift | Theme cookie P2 fixed+resolved; merged origin/main resolving layout.tsx (kept cookie html class + THEME_COOKIE_NAME atop localFont/skip-link from main). | merge origin/main; vitest theme 9/9; no provider-backed checks run. |
| 2026-07-24 | codex/apply-phone-layout-to-all-home-pages (PR #1124) | 2cb98b40e2fd36650e293b27a97996c069971db3 | Run PR sweep: CI fix + threads + drift | Before: behind main by 35. After: merged origin/main cleanly (no conflicts). Threads: non-P0/P1 left open. CI not waited. | merge origin/main only; thread scan read-only; no provider-backed checks run |
| 2026-07-24 | codex/apply-phone-layout-to-all-home-pages (PR #1124) | e061ce29300cd80df5c8cd95d2ea8ecfeef1e2b0 | Run PR babysit: CI/threads/drift | Run PR babysit: Codex P2 prescribing typed-draft dock path fixed + thread resolved. Before: CI mostly green, 1 unresolved Codex P2 (3644919028). After: showDesktopHomeComposer for prescribing requires !query.trim(); documents half dispositioned as not holding (home slot stays pre-submit); reply+resolve PRRT_kwDOSh5Fis6Th-6B. Not behind main. | npx vitest run tests/mobile-composer-reserve.test.ts PASS (9/9). No provider-backed checks run. |
| 2026-07-24 | codex/fix-next.js-startup-failure-and-verify-pages (PR #1149) | 8ddddbab2a29a94b3f993cbd114889f72c95f4f1 | Run PR sweep: CI fix + threads + drift | Before: behind main. After: merged origin/main cleanly (no conflicts). Unresolved review threads left as non-P0/P1. CI not waited. | merge origin/main only; thread scan read-only; no provider-backed checks run |
Expand All @@ -760,11 +763,13 @@ This file is append-only. Never rewrite or delete an existing review record; app
| 2026-07-24 | codex/query-ribbon-search-headings (PR #1166) | 37cfa5553ccb784ee5e9f47ded1ad69914c053ed | Run PR babysit: CI/threads/drift | Final HEAD after merge origin/main + ledger bookkeeping. 0 unresolved threads; no Bugbot actionable findings; required CI re-running on this SHA. | merge origin/main; no provider-backed checks run. |
| 2026-07-24 | codex/query-ribbon-search-headings (PR #1166) | 9eac2e252bcc5c548aa919b69faeb79b9ff7d2cf | Run PR babysit: CI/threads/drift | Merged origin/main; Codex ledger-SHA P2 dispositioned+resolved (append-only supersede already in 9eac2e252). 0 unresolved threads. | merge origin/main; thread resolve only; no provider-backed checks run. |
| 2026-07-24 | remediate-audit-system-issues (PR #1160) | bdf530fc8c6faaa4491c510396b47872fc39bf25 | Run PR sweep: CI fix + threads + drift | second re-merge after main moved to 2e68888f3 during first push; clean ort merge (ledger + layout.tsx); taskkill /T retained; sitemap prettier retained | merge only; no provider-backed checks run |
| 2026-07-24 | codex/hydration-fixes (PR #1131) | a29b0d778b542932972aa6035ee115b91e49025a | Run PR re-sync sweep | Before: CONFLICTING + Static PR FAIL (suppressHydrationWarning on skip link). After: merged origin/main; removed illegal suppressHydrationWarning from skip-to-content anchor; theme fix already on PR head b4b5f21b9. CI re-running. | merge origin/main and/or conflict re-check only; no provider-backed checks run |
| 2026-07-24 | codex/apply-phone-layout-to-all-home-pages (PR #1124) | d0a96caa01b90dffa40e60770b7700f36e8ba43f | Run PR re-sync sweep | Before: CONFLICTING @8adaaf229. After: merged origin/main clean (ort). CI re-running. Threads: not re-triaged. | merge origin/main and/or conflict re-check only; no provider-backed checks run |
| 2026-07-24 | cursor/repo-auditor-ledger-4132 (PR #1147) | 2f47746ad7e13e8cb848da71fb2647644388da8f | Run PR re-sync sweep | Before: CONFLICTING. After: merged origin/main clean. | merge origin/main and/or conflict re-check only; no provider-backed checks run |
| 2026-07-24 | cursor/frontend-ui-review-docs-e8d9 (PR #1146) | 2b17f5fcbe06307e7ff50ad0373789daa8f07a01 | Run PR re-sync sweep | Before: CONFLICTING. After: merged origin/main clean. | merge origin/main and/or conflict re-check only; no provider-backed checks run |
| 2026-07-24 | codex/query-ribbon-search-headings (PR #1166) | c94e89f392f578c4b2c749195dd485b74959074c | Run PR re-sync sweep | Before: CONFLICTING. After: merged origin/main clean. CI re-running. | merge origin/main and/or conflict re-check only; no provider-backed checks run |
| 2026-07-24 | cursor/comprehensive-repo-review-ledger-d9a1 (PR #1150) | 345c02cdbaefb13aeb951a14674aedfe4648a50e | Run PR re-sync sweep | Before: CONFLICTING. After: merged origin/main clean. | merge origin/main and/or conflict re-check only; no provider-backed checks run |
| 2026-07-25 | codex/hydration-fixes (PR #1131) | d6b5d23f7e97f99310a249db8e9f006833e697c6 | Open-PR maintenance: CI fix + threads + drift | Before: 24 commits behind, Static PR checks/PR required failed, 2 unresolved Codex threads. After: merged current main cleanly and removed the branch-introduced byte-identical PR #1149 ledger duplicate; hydration suppression fix was already present. | branch-review-ledger guard pass (717 records); targeted lint blocked by active repository heavyweight lock in worktree 6314; `git diff --check` pass; no provider-backed checks run. |
| 2026-07-24 | codex/apply-phone-layout-to-all-home-pages (PR #1124) | c59ae820db3034ef3cf74ae6d0030a0472a3a264 | Run PR babysit: merge/CI/threads | Before: CONFLICTING + Static PR checks FAIL (duplicate #1149 ledger row) + 2 unresolved Codex P2s. After: merged origin/main; removed duplicate ledger row; Differentials hero slot gated on !(query.trim() && documentMatches.length); threads resolved. | vitest mobile-composer-reserve 9/9; check:branch-review-ledger pass; maintainability 4132/4140. No provider-backed checks run. |
| 2026-07-25 | codex/document-clinical-summary-20260725 (PR #1169) | 6bbce2b97477cb4497624abe2a37c74864e872c8 | Open-PR maintenance: review-thread verification | Before: 2 unresolved Codex threads; branch current with main and required CI running. After: both persisted-profile/placeholder-summary fixes confirmed on the exact head and ready for reply-then-resolve; no further code change required. | `node scripts/run-vitest.mjs run tests/document-clinical-summary.test.ts tests/document-clinical-summary.dom.test.tsx --reporter=dot` pass (5/5); `git diff --check` pass; no provider-backed checks run. |
| 2026-07-25 | cursor/pr-babysit-bugbot-agents-6c52 (PR #1167) | ee44812aae9dad1973d8302eba5bfca5000dffb6 | Open-PR maintenance: review-thread fixes | Before: 8 unresolved Codex/CodeRabbit threads; branch current with main. After: target-head pinning, fresh-main verification, exact `cursor[bot]` identity checks, explicit mutation/provider authorization, direct reply-then-resolve semantics, and no-op ledger bookkeeping are documented. | Prettier check on both agent files pass; `git diff --check` pass; GitHub author probe confirmed `cursor[bot]` account type `Bot`; no provider-backed checks run. |
Expand All @@ -781,6 +786,7 @@ This file is append-only. Never rewrite or delete an existing review record; app
| 2026-07-24 | execute-audit-code-remediation (PR #1162) | 3cb7c977 | Conflict fix + Bugbot + local review | Before: CONFLICTING (21 files). After: mergeable. Restored atomic upload RPC; aligned private-access tests (133/133). Bugbot 2 medium left open. | private-access-routes 133/133; no provider-backed checks |
| 2026-07-25 | codex/document-clinical-summary-20260725 (PR #1169) | 605a47b551a03774fab41416bf980dfbc9610221 | Open-PR maintenance: malformed persisted profile guard | Before: one actionable thread showed non-array or malformed persisted summary groups could throw during render. After: every priority group is normalized through an array/item guard and malformed values are ignored while valid items still render. | Focused Vitest 7/7 pass; Prettier and diff checks pass; no provider-backed checks run. |
| 2026-07-25 | cursor/search-performance-review-4ee9 (PR #1134) | 692834a86e612cc8b311dc6895e007f182f5c5b8 | Open-PR maintenance: superseded docs-link thread and clean main sync | Before: branch was behind current main with one outdated docs-link thread; its product tree already matched main. After: merged current main cleanly and verified the route-group-aware docs-link fix now covers legacy route references. RAG impact: no retrieval behaviour change — history sync and docs tooling verification only. | `node scripts/check-docs-links.mjs` pass (1154 references); clean merge-tree; no live RAG canary or provider-backed check run. |
| 2026-07-25 | codex/hydration-fixes (PR #1131) | 555213fcf4dec82c6dbb445630e59e0d5465149a | Open-PR maintenance: persisted-state hydration coverage | Before: the browser guard covered only an empty-storage dashboard load. After: it seeds theme localStorage plus cookie, sidebar state, and document-viewer PDF mode before navigation, while retaining the default case. | Repository Playwright runner built the isolated production app and passed 3/3 Chromium hydration scenarios; Prettier and diff checks pass; no provider-backed checks run. |
| 2026-07-24 | open-PR conflict sync (20 PRs) | multi-head | Conflict resolution pass | Before: 8 PRs behind/dirty (#1124 #1131 #1162 #1169 #1174-1177). After: merged origin/main into all; all 20 open PRs MERGEABLE behind=0 (BLOCKED only by CI/reviews). | merge origin/main per branch; no provider-backed checks run |
| 2026-07-24 | open-PR conflict sync (22 PRs) | multi-head | Conflict resolution pass | Before: all 22 open PRs behind/dirty vs main (several CONFLICTING/DIRTY). After: merged origin/main into every open head; all pushes OK; merge-tree classified 22/22 clean. | merge origin/main per branch; check:branch-review-ledger on #1172; no provider-backed checks run |
| 2026-07-24 | cursor/pr-queue-hygiene-72ec | pending-push | PR queue hygiene | Add pr-branch-sync workflow + sync:pr-branches helper; bump postcss to clear npm audit high; document anti-churn guidance in AGENTS/process-hardening/pr-babysit/run-pr. | check:github-actions PASS; docs:check-scripts/index PASS; vitest sync-open-pr-branches 3/3; npm audit high clean; no provider-backed checks run |
Expand Down
35 changes: 35 additions & 0 deletions eslint-rules/restrict-suppress-hydration-warning.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @type {import('eslint').Rule.RuleModule}
*/
export default {
meta: {
type: "problem",
docs: {
description: "Restrict suppressHydrationWarning to <html> and <body> tags only",
category: "Possible Errors",
recommended: true,
},
schema: [],
},
create(context) {
return {
JSXAttribute(node) {
if (node.name.name === "suppressHydrationWarning") {
const parentElement = node.parent; // JSXOpeningElement
if (parentElement && parentElement.name) {
const tagName = parentElement.name.name;
// The audit explicitly requested banning it on elements other than html and body.
// We also allow script since it's required for nonce mismatch bypass in layout.tsx.
if (tagName !== "html" && tagName !== "body" && tagName !== "script") {
context.report({
node,
message:
"suppressHydrationWarning is only allowed on <html>, <body>, and <script> elements. Fix the underlying mismatch instead of hiding it.",
});
}
}
}
},
};
},
};
9 changes: 9 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import nextTs from "eslint-config-next/typescript";

import requireLucideIconAria from "./eslint-rules/require-lucide-icon-aria.mjs";
import requireButtonWiring from "./eslint-rules/require-button-wiring.mjs";
import restrictSuppressHydrationWarning from "./eslint-rules/restrict-suppress-hydration-warning.mjs";

// Shared `local` plugin object. ESLint flat config requires every config block
// that references a plugin namespace to point at the *same* object, so the two
Expand All @@ -12,6 +13,7 @@ const localRulesPlugin = {
rules: {
"require-lucide-icon-aria": requireLucideIconAria,
"require-button-wiring": requireButtonWiring,
"restrict-suppress-hydration-warning": restrictSuppressHydrationWarning,
},
};

Expand Down Expand Up @@ -66,6 +68,13 @@ const eslintConfig = defineConfig([
"local/require-button-wiring": "error",
},
},
{
files: ["src/**/*.{js,jsx,ts,tsx}"],
plugins: { local: localRulesPlugin },
rules: {
"local/restrict-suppress-hydration-warning": "error",
Comment thread
BigSimmo marked this conversation as resolved.
},
},
// Import boundary: production source must not import design-scratch mockup
// modules. Every legitimate mockup import lives under `src/app/mockups/**` (all
// 404 in production) or inside the `*-mockups` component sources themselves;
Expand Down
4 changes: 2 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ const chromiumExecutablePath = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH;
// they share a spec file. Every required browser project uses the same
// production matcher and tag exclusion.
const productionSpecPattern =
/.*(?:answer-progress-ui-smoke|ui-(smoke|stress|accessibility|tools|overlap|universal-search|specifiers|formulation|phone-scroll|pwa|route-coverage|visual-artifacts))\.spec\.ts/;
/.*(?:answer-progress-ui-smoke|ui-(smoke|stress|accessibility|tools|overlap|universal-search|specifiers|formulation|phone-scroll|pwa|route-coverage|visual-artifacts|hydration))\.spec\.ts/;
const mockupSpecPattern = /.*ui-(tools|tools-collapse|tools-task-directory)\.spec\.ts/;
const mockupTag = /@mockup/;

export default defineConfig({
testDir: "./tests",
testMatch:
/.*(?:answer-progress-ui-smoke|ui-(smoke|stress|accessibility|tools|tools-collapse|tools-task-directory|overlap|universal-search|specifiers|formulation|phone-scroll|pwa|route-coverage|visual-artifacts))\.spec\.ts/,
/.*(?:answer-progress-ui-smoke|ui-(smoke|stress|accessibility|tools|tools-collapse|tools-task-directory|overlap|universal-search|specifiers|formulation|phone-scroll|pwa|route-coverage|visual-artifacts|hydration))\.spec\.ts/,
timeout: 60_000,
retries: 0,
// Fail the run if a stray `test.only` is committed: otherwise it silently
Expand Down
12 changes: 8 additions & 4 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { Metadata, Viewport } from "next";
import localFont from "next/font/local";
import { headers } from "next/headers";
import { cookies, headers } from "next/headers";
import { AuthProvider } from "@/lib/supabase/client";
import { AccountDataProvider } from "@/components/account-data-provider";
import { PwaLifecycle } from "@/components/pwa-lifecycle";
import { WebVitalsReporter } from "@/components/web-vitals-reporter";
import { resolveMetadataBase } from "@/lib/metadata-base";
import { APP_THEME_COLORS, THEME_BOOTSTRAP_SCRIPT } from "@/lib/theme";
import { APP_THEME_COLORS, THEME_BOOTSTRAP_SCRIPT, THEME_COOKIE_NAME } from "@/lib/theme";
import "./globals.css";

const geistSans = localFont({
Expand Down Expand Up @@ -78,10 +78,15 @@ export default async function RootLayout({
// silent runtime failure: theme flash returns). Reading headers() opts the app
// into dynamic rendering — inherent to nonce-based CSP.
const nonce = (await headers()).get("x-nonce") ?? undefined;
const cookieStore = await cookies();
const clinicalTheme = cookieStore.get(THEME_COOKIE_NAME)?.value;
const isDark = clinicalTheme === "dark";
const themeClass = isDark ? "dark" : "";

return (
<html
lang="en-AU"
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased ${themeClass}`}
suppressHydrationWarning
>
<body className="min-h-full flex flex-col" suppressHydrationWarning>
Expand All @@ -102,7 +107,6 @@ export default async function RootLayout({
/>
<a
href="#main-content"
suppressHydrationWarning
className="sr-only focus:not-sr-only focus:fixed focus:left-[max(0.75rem,env(safe-area-inset-left))] focus:top-[max(0.75rem,env(safe-area-inset-top))] focus:z-[100] focus:rounded-lg focus:border focus:border-[color:var(--border-lux)] focus:bg-[color:var(--surface-raised)] focus:px-4 focus:py-2 focus:text-sm focus:font-semibold focus:text-[color:var(--text)] focus:shadow-[var(--shadow-elevated)]"
>
Skip to main content
Expand Down
Loading