Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
986ffd2
fix: land residual P2 audit remediations on current main
cursoragent Jul 28, 2026
4265b3e
docs: record clean rebuild HEAD for PR #1298 secret-scanner history
cursoragent Jul 28, 2026
43795bc
ci: remove PR_POLICY_BODY.md after successful description sync
cursoragent Jul 28, 2026
c60953b
docs: record PR #1298 closeout tip after clean rebuild
cursoragent Jul 28, 2026
6f06b84
fix(ci): unblock Build on low-RAM runners and restore escalation class
cursoragent Jul 28, 2026
c89756f
fix: scope medication alias matching per named subject
cursoragent Jul 28, 2026
648a629
docs: record PR #1298 CI babysit tip after Build/Unit fixes
cursoragent Jul 28, 2026
7f75c39
style: prettier clinical-search and fix ledger tip marker
cursoragent Jul 28, 2026
f8d4d17
docs: record exact PR #1298 tip after prettier
cursoragent Jul 28, 2026
dc47256
docs: record exact PR #1298 HEAD after thread resolution
cursoragent Jul 28, 2026
738643d
docs: record PR #1298 tip after Bugbot review request
cursoragent Jul 28, 2026
7156310
fix(ci): forward CI=true into Docker app image builds
cursoragent Jul 28, 2026
111aee5
merge origin/main into codex/fix-p2-audit-20260719
cursoragent Jul 28, 2026
4de7ec8
docs: record PR #1298 main-merge tip after RAM-guard conflict resolution
cursoragent Jul 28, 2026
b503f3b
docs: record PR #1298 CI-green closeout tip
cursoragent Jul 28, 2026
065f76c
merge origin/main into codex/fix-p2-audit-20260719
cursoragent Jul 28, 2026
bdca7dd
fix(ci): dedupe branch ledger and harden differentials results locator
cursoragent Jul 28, 2026
8ec6bee
merge origin/main into codex/fix-p2-audit-20260719
cursoragent Jul 28, 2026
439dbeb
Merge branch 'main' into codex/fix-p2-audit-20260719
BigSimmo Jul 28, 2026
270fb5d
Merge branch 'main' into codex/fix-p2-audit-20260719
BigSimmo Jul 28, 2026
de14ee2
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
29e30d9
docs: record PR 1298 review
BigSimmo Jul 28, 2026
f829b5a
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
56536a4
fix: remove unvalidated retrieval behavior
BigSimmo Jul 28, 2026
1b8b57a
docs: record final PR 1298 review
BigSimmo Jul 28, 2026
ab43974
fix: skip untabbable sheet controls
BigSimmo Jul 28, 2026
506dce0
test: await settled search results owner
BigSimmo Jul 28, 2026
feabb35
test: scope safety-plan privacy assertions
BigSimmo Jul 28, 2026
bcc70ce
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
319acc8
test: scope safety-plan notices correctly
BigSimmo Jul 28, 2026
ecc3493
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
d3f52f1
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
67d6ce8
test: always restore sheet focus spies
BigSimmo Jul 28, 2026
3d5ed37
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
dcf3348
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
730adb1
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 2026
856e22e
Merge remote-tracking branch 'origin/main' into codex/pr1298-review-sync
BigSimmo Jul 28, 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
14 changes: 14 additions & 0 deletions docs/branch-review-ledger.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion playwright.config.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -55,7 +55,8 @@ export default defineConfig({
// claims the page, and serves every subsequent navigation — bypassing route
// interception for navigations outright, and wedging Playwright-Firefox's
// reload path under an active route (the two ui-smoke reload hangs in matrix
// run 4012). Only ui-pwa.spec.ts is meant to exercise the worker; it opts
// run 4012). Page routes also cannot intercept requests made by a controlling
// service worker. Only ui-pwa.spec.ts is meant to exercise the worker; it opts
// back in with test.use({ serviceWorkers: "allow" }).
serviceWorkers: "block",
},
Expand Down
1 change: 0 additions & 1 deletion src/components/ClinicalDashboard.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -2249,7 +2249,6 @@ export function ClinicalDashboard({
"",
documentsSearchHref({
query: trimmedQuery,
focus: true,
run: true,
...navigationContext,
}),
Expand Down
37 changes: 24 additions & 13 deletions src/components/ui/sheet.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -215,21 +215,32 @@ export function Sheet({
// options) do not dump every inactive item into the Tab cycle.
'a[href], button:not([disabled]):not([tabindex="-1"]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), summary, [tabindex]:not([tabindex="-1"])',
) ?? [],
).filter((element) => !element.hasAttribute("disabled") && element.getAttribute("aria-hidden") !== "true");
).filter(
(element) =>
!element.hasAttribute("disabled") &&
element.getAttribute("aria-hidden") !== "true" &&
element.tabIndex >= 0 &&
!element.closest('[aria-hidden="true"], [inert]') &&
element.getClientRects().length > 0,
);
Comment thread
cursor[bot] marked this conversation as resolved.
if (focusable.length === 0) return;

const first = focusable[0];
const last = focusable[focusable.length - 1];
if (panelRef.current && !panelRef.current.contains(document.activeElement)) {
event.preventDefault();
(event.shiftKey ? last : first).focus();
} else if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : null;
const currentIndex = activeElement ? focusable.indexOf(activeElement) : -1;
const nextIndex =
currentIndex === -1
? event.shiftKey
? focusable.length - 1
: 0
: event.shiftKey
? (currentIndex - 1 + focusable.length) % focusable.length
: (currentIndex + 1) % focusable.length;

// Move focus explicitly instead of relying on platform Tab preferences.
// Firefox can otherwise leave programmatically focused buttons out of the
// native sequence, which makes the modal trap inconsistent by browser.
event.preventDefault();
focusable[nextIndex].focus();
Comment thread
BigSimmo marked this conversation as resolved.
}

window.addEventListener("keydown", onKeyDown);
Expand Down
50 changes: 50 additions & 0 deletions tests/eval-retrieval.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -462,6 +462,56 @@ describe("golden retrieval eval helpers", () => {
expect(evaluated.failures).toEqual([]);
});

it("recognizes current safety-plan and alcohol-withdrawal titles", () => {
const safetyPlan = evaluateGoldenRetrievalCase({
testCase: {
id: "safety-plan-title",
query: "What should a patient safety plan include?",
expectedQueryClass: "document_lookup",
expectedDocumentSubstrings: ["PtSafetyPlan"],
expectedContentTerms: ["safety", "plan"],
topK: 8,
expectTableEvidence: false,
},
results: [
result({
// Strict golden-eval aliases only accept "Patient Safety Plan" for PtSafetyPlan
// (see scripts/lib/clinical-aliases.ts tiering note).
title: "Patient Safety Plan Policy and Procedure (RKPG)",
file_name: "Patient Safety Plan Policy and Procedure (RKPG).pdf",
content: "A safety plan records agreed actions.",
}),
],
telemetry: { query_class: "document_lookup", retrieval_strategy: "text_fast_path" },
latencyMs: 10,
});
const alcoholWithdrawal = evaluateGoldenRetrievalCase({
testCase: {
id: "ciwa-title",
query: "What CIWA-Ar score threshold requires drug treatment in alcohol withdrawal?",
expectedQueryClass: "table_threshold",
expectedDocumentSubstrings: ["Alcohol withdrawal"],
expectedContentTerms: ["alcohol", "withdrawal", ["ciwa", "score", "threshold"]],
topK: 12,
expectTableEvidence: false,
},
results: [
result({
// Document substring matching uses title/file/section path only (not body
// content), so the fixture title must carry the pinned phrase.
title: "Alcohol Withdrawal - Addiction, Toxicity and Withdrawal",
file_name: "Alcohol Withdrawal - Addiction, Toxicity and Withdrawal.pdf",
content: "Use the CIWA-Ar treatment table for alcohol withdrawal.",
}),
],
telemetry: { query_class: "table_threshold", retrieval_strategy: "text_fast_path" },
latencyMs: 10,
});

expect(safetyPlan.failures).toEqual([]);
expect(alcoholWithdrawal.failures).toEqual([]);
});

it("reports failed cases with top result summaries", () => {
const evaluated = evaluateGoldenRetrievalCase({
testCase: {
Expand Down
24 changes: 24 additions & 0 deletions tests/eval-utils.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,6 +54,30 @@ describe("RAG eval source identity matching", () => {
expect(coverage.missingFiles).toEqual(["MHSP.Discharge.pdf"]);
});

it("maps legacy community-admission expectations to current combined policies", () => {
const coverage = expectedFileCoverage(
["MHSP.AdmissionCommunityPts.pdf"],
[
{
title: "Admission to Discharge for Community Mental Health",
file_name: "Admission to Discharge for Community Mental Health (NMHS).pdf",
},
{
title: "Referral, Admission and Discharge - Mental Health Hospital in the Home",
file_name:
"Referral, Admission and Discharge - Mental Health Hospital in the Home (MHHITH) Policy and Procedure (RKPG).pdf",
},
],
5,
);

expect(coverage).toMatchObject({
matchedFiles: ["MHSP.AdmissionCommunityPts.pdf"],
missingFiles: [],
allHit: true,
});
});

it("fails supported clinical eval cases when numeric faithfulness warnings are present", () => {
const testCase: RagEvalCase = {
id: "dose-warning",
Expand Down
8 changes: 8 additions & 0 deletions tests/playwright-project-isolation.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,4 +14,12 @@ describe("Playwright production-project isolation", () => {

expect(source).toMatch(/name: ["']chromium-mockups["'],\s+testMatch: mockupSpecPattern,\s+grep: mockupTag,/m);
});

it("blocks service workers for mocked journeys but allows the dedicated PWA suite", () => {
const config = readFileSync(resolve(process.cwd(), "playwright.config.ts"), "utf8");
const pwaSpec = readFileSync(resolve(process.cwd(), "tests/ui-pwa.spec.ts"), "utf8");

expect(config).toContain('serviceWorkers: "block"');
expect(pwaSpec).toContain('test.use({ serviceWorkers: "allow" })');
});
});
2 changes: 2 additions & 0 deletions tests/rag-route-budget.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,8 +31,10 @@ describe("RAG route deadlines", () => {
const deadline = createAnswerRouteDeadline({ routeMode: "fast", startedAt });

expect(deadline.requestTimeoutMs(30_000)).toBe(15_000);
expect(deadline.generationRequestTimeoutMs(30_000)).toBe(13_000);
await vi.advanceTimersByTimeAsync(10_000);
expect(deadline.requestTimeoutMs(30_000)).toBe(5_000);
expect(deadline.generationRequestTimeoutMs(30_000)).toBe(3_000);

const pending = deadline.race(new Promise<never>(() => undefined));
const rejection = expect(pending).rejects.toBeInstanceOf(AnswerRouteDeadlineExceededError);
Expand Down
41 changes: 40 additions & 1 deletion tests/sheet-focus.dom.test.tsx
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
import { act, render, waitFor } from "@testing-library/react";
import { useEffect, useState } from "react";
import { afterEach, describe, expect, it } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";

import { Sheet } from "@/components/ui/sheet";
import {
Expand All@@ -11,6 +11,7 @@ import {
} from "@/components/ui/sheet-focus";

afterEach(() => {
vi.restoreAllMocks();
if (typeof document !== "undefined" && document.body) {
document.body.style.overflow = "";
}
Expand DownExpand Up@@ -255,3 +256,41 @@ describe("Sheet open focus", () => {
background.remove();
});
});

describe("Sheet Tab cycle", () => {
it("skips visible controls explicitly removed from the tab order", async () => {
vi.spyOn(HTMLElement.prototype, "getClientRects").mockReturnValue({
length: 1,
item: () => null,
[Symbol.iterator]: function* () {
yield {} as DOMRect;
},
} as DOMRectList);

render(
<Sheet open onClose={() => {}} title="Tab order" portal>
<a href="#first">First</a>
<input aria-label="Programmatic only" tabIndex={-1} />
<button type="button">Last</button>
</Sheet>,
);

const panel = panelOf("Tab order");
const first = panel.querySelector<HTMLAnchorElement>('a[href="#first"]');
const excluded = panel.querySelector<HTMLInputElement>('input[tabindex="-1"]');
const last = Array.from(panel.querySelectorAll<HTMLButtonElement>("button")).find(
(button) => button.textContent === "Last",
);
expect(first).not.toBeNull();
expect(excluded).not.toBeNull();
expect(last).toBeDefined();

act(() => {
first?.focus();
window.dispatchEvent(new KeyboardEvent("keydown", { key: "Tab", bubbles: true, cancelable: true }));
});

expect(document.activeElement).toBe(last);
expect(document.activeElement).not.toBe(excluded);
});
});
4 changes: 3 additions & 1 deletion tests/ui-formulation.spec.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,7 +111,9 @@ test("keeps mobile search, domain filtering, record actions, and universal chrom
await expectNoHorizontalOverflow(page);

await page.getByRole("link", { name: "Open Worry" }).click();
await expect(page).toHaveURL(/\/formulation\/worry$/, { timeout: 30_000 });
await expect(async () => {
await expect(page).toHaveURL(/\/formulation\/worry$/);
}).toPass({ timeout: 30_000 });
Comment thread
cursor[bot] marked this conversation as resolved.
await expect(page.getByRole("heading", { name: "Worry", exact: true })).toBeVisible({ timeout: 30_000 });
await expect(page.getByRole("link", { name: "Compare", exact: true }).last()).toBeVisible();
await expect(page.getByRole("link", { name: "Use in formulation", exact: true }).first()).toBeVisible();
Expand Down
4 changes: 3 additions & 1 deletion tests/ui-tools.spec.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2376,7 +2376,9 @@ test.describe("Responsive layout guards", () => {

await page.goto("/safety-plan");
await expect(page.getByLabel(/Patient \(name or initials\)/i)).toHaveCount(0);
await expect(page.getByText(/kept only in this browser tab/i)).toBeVisible();
const privacyRegion = page.getByRole("region", { name: "Safety plan privacy" });
await expect(privacyRegion).toHaveCount(1);
await expect(privacyRegion.getByText(/kept only in this browser tab/i)).toBeVisible();
await expect(
page.getByText(/Copying, printing, or saving a PDF moves the plan outside Clinical KB/i),
).toBeVisible();
Expand Down
Loading