Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions docs/branch-review-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,4 @@ Use this ledger to prevent repeated branch and PR reviews when the reviewed HEAD
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (restarted; PR: ci.yml concurrency) | 79aaacf04e64f753c480dd957a81ac9be6acbb43 | CI workflow concurrency: stop main churn cancelling dispatch/schedule runs | One-line group expression: workflow_dispatch/schedule events now get a per-run concurrency group (github.run_id) while push/PR keep the shared ref group with cancel-in-progress — fixes the release-browser-matrix livelock (cancelled twice on 2026-07-19/20 by main merges mid-run; the weekly Sunday 18:00 UTC scheduled run was subject to the same cancellation). release-browser-matrix is not a required branch-protection check; pin/scope checkers do not constrain the concurrency block. Accepted side effect: deliberate runs can overlap push runs. Rollback: plain revert. | check:github-actions PASS; check:ci-scope PASS; format:check PASS (repo files; local-only .claude/settings.local.json warning is gitignored) |
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (restarted; PR: #901 rerank regression closeout) | fd5dcd1582e1c7aa8bf92ff097575e0c68aa930d | #901 rerank regression: baseline re-eval + offline guard net + saturated-tie fix | Baseline eval-canary dispatch on remediated main b3ae061 (run 29731533081) PASSED — golden retrieval 36/36 + answer-quality green, confirming #913-#926 closed the live 4/36 regression (July 19 failing run tested the raw #901 state; fixes landed 1-8h after it, never re-evaled until now). Residual defect found by new offline repro and fixed: with byte-identical imputed fast-path primaries, selection's clamped keys tie exactly and the chunk-id fallback decides, which secondStageScore's position adjustment launders into releaseRankScore (buried the CIWA answer doc in repro); fix = contentRankScore carried on RetrievalCandidate as tie-break between clamped rerankScore and chunk id, never added to scores. Amended #901's own never-live-validated saturated-tie pin to content-rank-then-id. Guards: tests/rag-fast-path-ordering.test.ts (4 end-to-end eval-shape repros) + ranking-tuning gates (4 golden-mapped hard negatives at production weights + full-snapshot high-risk). Fixture aliases NOT changed (Step C not triggered — identity cases pass live). | Targeted 4-suite vitest 37/37; npm run test 2981 passed (sole fail = container-only pdf-extraction-budget artifact); verify:cheap green through all 18 pre-test checks incl. lint+typecheck; check:production-readiness PASS on substantive checks (2 FAILs = documented missing-secret class in this container); build + client-bundle scan + check:rag:fixtures PASS |
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (restarted; PR: coverage tie-break follow-up) | 57ec880b306a8e2b31c5f20dacc47256fc93b4e2 | Post-merge live-eval finding on #982 + corrective fix: saturated-tie key rankScore → query-term coverage | Post-#982 golden dispatch (eval-canary run #50, 29735004222, main b9057f0 + deps) came back 35/36: the three verifiable July-19 failures (lithium-therapy-monitoring, clozapine-anc-threshold, patient-safety-plan-include) all PASS live, but alcohol-ciwa-threshold flipped pass→FAIL vs the same-morning pre-#982 run #49 (29731533081, 36/36) — failing top-3 ordered by descending rankScore (1.85/1.75/1.53, all finalScore-saturated, releaseRankScore 1.09/1.086/1.07), i.e. #982's tie-break let generic clinicalSignalBoost stacking outvote the ciwa/score/threshold-bearing chunk; #982 is the only retrieval-path delta in the window. Fix: contentRankScore → contentCoverageScore sourced from lexicalCoverageScore (query-term coverage, immune to boost stacking; ties still fall to chunk id); saturated-tie contract test re-pinned so coverage beats a HIGHER rankScore (discriminating — old key fails it); fast-path CIWA guard gains the run-#50 screening-chunk shape + content-term assertion. Live validation: tonight's 18:00 UTC scheduled canary (dispatch cap 2/2 spent ≈$2-4). Separately: ci.yml dispatch 4012 survived 30+ min of main churn under #979's per-run concurrency group (fix working); duplicate dispatch 4017 cancelled. | Targeted vitest 38/38; npm run test 3012 passed / 1 known container-only pdf-budget artifact; verify:cheap green to the same artifact; build + client-bundle scan + check:rag:fixtures PASS; check:production-readiness expected missing-secret FAILs only (no secrets in container) |
| 2026-07-20 | claude/clinical-kb-pwa-review-asi3wb (restarted; PR: WebKit matrix diagnosis) | caa298972846ef52d472bfbff98c90fc26481ed8 | First completed release-browser-matrix in weeks (run 4012, main b9057f0, 38 min uncancelled under #979) — full triage of 28 failures + fix for the dominant cluster | Run 4012: 716 passed / 28 failed (25 webkit, 3 firefox) / 4 skipped. Dominant cluster (root-caused, FIXED here): all 8 ui-universal-search webkit failures share one signature — typeahead content never enters the DOM — because commandDropdownCanDisplay (added 42a3e3c 2026-07-17, AFTER the last completed matrix; never ran on WebKit until 4012) requires fine-pointer OR zero-touch; headless browsers fail the (hover:hover)+(pointer:fine) query (proven by the zero-touch escape existing for CI at all), Chromium/Firefox pass via maxTouchPoints===0, and Playwright's Linux WebKit build advertises phantom touch points — flunking both branches and disabling useUniversalSearch entirely. Fix: beforeEach addInitScript in ui-universal-search/ui-smoke/ui-tools specs stubbing Navigator.prototype.maxTouchPoints to the runner's true 0 (inert on Chromium/Firefox; product gate + tests/search-command-surface.test.ts pins untouched). Local chromium runs of ui-universal-search fail 16/20 IDENTICALLY on unmodified main (container artifact — hosted CI chromium green in 4012 is authoritative; verified by stash/run/pop baseline). Expected delta next matrix: ≥8 webkit failures clear; candidates ui-tools:1244 + several ui-smoke answer-flow cases (same surface). NOT yet root-caused (triaged remainder, hosted-matrix-only reproduction): webkit ui-stress overflow 330/409 (360px overflow at mobile), webkit ui-accessibility 195/252 (focus dismissal; forced-colors labels), webkit ui-formulation 132, webkit ui-smoke copy-table/retry/recovery/recent-searches/source-only/differential-context/viewer-hydration/document-questions, webkit ui-tools 2087 (goto interrupted by ?q= navigation), webkit ui-universal-search 183 strict-mode duplicate options (fallback-surface rendering; likely clears with the gate fix), firefox ui-smoke 946/2206/2932 (@critical document search fails on BOTH firefox and webkit — cross-browser, highest-priority remainder). | prettier PASS; eslint PASS; typecheck PASS; chromium stash-baseline no-delta (16 fail pre AND post — container artifact); webkit validation lands via tonight's 18:00 UTC scheduled matrix |
10 changes: 10 additions & 0 deletions tests/ui-accessibility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@ async function expectNoBlockingAxeViolations(page: Page, testInfo: TestInfo, opt
expect(summary, "axe found critical/serious WCAG A/AA violations").toEqual([]);
}

// Playwright's Linux WebKit build advertises phantom touch points on the touch-free CI
// runner, tripping the fine-pointer/zero-touch gate on the search command surface
// (commandDropdownCanDisplay) that Chromium and Firefox pass via the zero-touch fallback.
// Report the runner's real capability so WebKit exercises the same desktop surfaces.
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(Navigator.prototype, "maxTouchPoints", { configurable: true, get: () => 0 });
});
});

test.describe("Clinical KB accessibility coverage", () => {
test.describe.configure({ timeout: 60_000 });

Expand Down
7 changes: 7 additions & 0 deletions tests/ui-formulation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ async function expectNoBlockingAxeViolations(page: Page, testInfo: TestInfo) {

test.beforeEach(async ({ page }) => {
await blockExternalRequests(page);
// Playwright's Linux WebKit build advertises phantom touch points on the touch-free CI
// runner, tripping the fine-pointer/zero-touch gate on the search command surface
// (commandDropdownCanDisplay) that Chromium and Firefox pass via the zero-touch fallback.
// Report the runner's real capability so WebKit exercises the same desktop surfaces.
await page.addInitScript(() => {
Object.defineProperty(Navigator.prototype, "maxTouchPoints", { configurable: true, get: () => 0 });
});
});

test("searches patient language, opens a mechanism guide, and carries it into the builder", async ({
Expand Down
10 changes: 10 additions & 0 deletions tests/ui-smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,16 @@ async function openDailyActions(page: Page, triggerName: string | RegExp = /^Ope
return menu;
}

// Playwright's Linux WebKit build advertises phantom touch points on the touch-free CI
// runner, tripping the fine-pointer/zero-touch gate on the search command surface
// (commandDropdownCanDisplay) that Chromium and Firefox pass via the zero-touch fallback.
// Report the runner's real capability so WebKit exercises the same desktop surfaces.
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(Navigator.prototype, "maxTouchPoints", { configurable: true, get: () => 0 });
});
});

test.describe("Clinical KB UI smoke coverage", () => {
test.describe.configure({ timeout: 60000 });

Expand Down
10 changes: 10 additions & 0 deletions tests/ui-stress.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,16 @@ async function openScopeControl(page: Page) {
}).toPass({ timeout: 20_000 });
}

// Playwright's Linux WebKit build advertises phantom touch points on the touch-free CI
// runner, tripping the fine-pointer/zero-touch gate on the search command surface
// (commandDropdownCanDisplay) that Chromium and Firefox pass via the zero-touch fallback.
// Report the runner's real capability so WebKit exercises the same desktop surfaces.
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(Navigator.prototype, "maxTouchPoints", { configurable: true, get: () => 0 });
});
});

test.describe("Clinical KB long-content stress coverage", () => {
for (const viewport of [
{ name: "mobile", width: 320, height: 740 },
Expand Down
10 changes: 10 additions & 0 deletions tests/ui-tools.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,16 @@ async function expectVerticalSeparation(page: Page, upperSelector: string, lower
expect((metrics?.lowerTop ?? 0) - (metrics?.upperBottom ?? 0)).toBeGreaterThanOrEqual(minimumGap);
}

// Playwright's Linux WebKit build advertises phantom touch points on the touch-free CI
// runner, tripping the fine-pointer/zero-touch gate on the search command surface
// (commandDropdownCanDisplay) that Chromium and Firefox pass via the zero-touch fallback.
// Report the runner's real capability so WebKit exercises the same desktop surfaces.
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(Navigator.prototype, "maxTouchPoints", { configurable: true, get: () => 0 });
});
});

test.describe("Clinical KB tools launcher", () => {
test.describe.configure({ timeout: 60_000 });

Expand Down
12 changes: 12 additions & 0 deletions tests/ui-universal-search.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ async function openComposer(page: Page, href = "/?mode=documents&focus=1") {
return input;
}

// Playwright's Linux WebKit build advertises phantom touch points on the touch-free CI
// runner. That trips the deliberate fine-pointer/zero-touch gate on the search command
// surface (commandDropdownCanDisplay: headless browsers fail the fine-pointer media query
// and rely on the zero-touch fallback), silently hiding the desktop dropdown that Chromium
// and Firefox render — every typeahead assertion then fails with "element not found".
// Report the runner's real capability; the product gate and its unit pins stay unchanged.
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(Navigator.prototype, "maxTouchPoints", { configurable: true, get: () => 0 });
});
});

test.describe("universal search typeahead", () => {
test("shows grouped cross-entity results while typing", async ({ page }) => {
await mockUniversalSearch(page);
Expand Down
Loading