Skip to content
Closed
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 @@ -713,6 +713,7 @@ This file is append-only. Never rewrite or delete an existing review record; app
| 2026-07-21 | claude/clinical-kb-pwa-review-asi3wb (Option A wave verdict — no code change; #1040 merged as cde6c5c) | canary run 29827012719 (#61, main cde6c5c) vs banked #60 (29800029819) | OPTION A WAVE ADOPTED — FIRST FULLY-GREEN 44-CASE CANARY IN PROGRAM HISTORY (Blocking failures: None). (1) Option A payoff EXCEEDED: citation_failure_rate 0.0227→0; the neuroleptic-side-effect-escalation case flipped from wrong-doc→failed-generation→1-citation-fallback to **strong route, successful gpt-5.6-sol generation, passed in 15.4s with no fallback marker** — the rescued S3 retrieval fixed generation itself, not just the citation count; expected_source_hit 0.6364→0.6591. (2) Golden held exactly as the blast-radius analysis promised: 36/36 PASS, content_recall 1.0, mrr@10 0.8921 BYTE-IDENTICAL to the pre-wave baseline (zero ordering movement — no golden case fires the predicate), irrelevant@10 0.1083→0.0917 (slightly better). (3) Parity payoff PARTIAL: monitoring targeting 1/5→2/5 (olanzapine-lai flipped — previously called a retrieval-depth residual; quetiapine-dose also flipped on the dose side); lithium-range (232ch) + metabolic (73ch, byte-identical answer to #60) did NOT flip despite offline-proven fixes — their live chunk sets evidently contain no admissible schedule sentence even under the widened gate → reclassified as retrieval-depth/live-content residuals joining adhd; below the ≥3/5 target but strictly improved, no regression anywhere. Dose 2/5 vs 2/4: same passing count, applicable set grew (new quality-metformin-renal-dosing miss = eval-set churn, not regression). (4) No-worse EXCEEDED: relevance 0.5333→0.6 (the two-step watch-item slide FULLY REVERSED to the #58 level), targeting_rate 0.6667→0.6957, fail_closed 0.9 held, readability/artifact_leaks 1.0, route ceilings 0, grounded 1.0, unsupported_correct 1.0, numeric 0, p95 22.8s, red_result 3/3. Adoption per the measured-gain rule: primary goal achieved, three case flips, relevance recovered, zero regressions. Residual queue: monitoring retrieval-depth trio (lithium-range/metabolic/adhd), E-3d H2 discards, weekly ANSWER_CASE_LIMIT 8→44 raise now unblocked (gate would be green), comparison-class coverage. Wave spend +~$2-4 → Phase E + Option A total ~$12-20 of ≤$20. | Evidence: run #61 job log read (Threshold Status: None; Answer Metrics; neuroleptic diagnostics row; targeting metric_rates + 6-miss list; golden 36 PASS lines + summary). Revert drill NOT triggered. |
| 2026-07-21 | claude/clinical-kb-pwa-review-asi3wb (PR: I9 weekly coverage raise) | see PR head | ADDENDUM 5 post-green item I9 (plan-authorized "after reds fixed"): weekly scheduled canary ANSWER_CASE_LIMIT default 8→44 — the Sunday 18:00 UTC cron now guards the FULL answer-quality case set instead of the first 8 (both #57 blocking reds historically lived OUTSIDE the first 8, leaving the weekly gate blind to them). Unblocked by run #61 proving the citation gate green on the full 44. Cost: est +$1-2/week (user-authorized in the plan). Contract test pin updated in lockstep (eval-canary-workflow.test.ts). Dispatch shapes unchanged (input override still wins); operational-risk diff, plain-revert rollback. | check:github-actions PASS; check:ci-scope PASS; check:gate-manifest PASS (20/20); eval-canary-workflow contract 4/4; prettier clean; no provider calls |
| 2026-07-21 | claude/database-governance-audit-10b6ed (PR #1051: source-governance audit — safe subset) | cee396730 | Governance-metadata observability + UI display + provenance flow test; no ranking/retrieval/generation surface touched. | IMPLEMENTED + handed off (not a review of prior work). Resolved audit #1 (logger.warn on unrecognized enum values; return value unchanged), #2 (review_due_source added to frontendVisibleWarningCodes → answer-level badge; warning-severity, no refusal impact), #9 (source_metadata retained on safety-finding citations + governance pill in SafetyFindingsListContent), #13 (new tests/provenance-flow.test.ts: DB-normalize→governance→client payload sources+safety citations→render policy). Deferred #4/5/6/8/10 (RAG-protected ranking/selection/LLM-context/cache — need live eval-canary+approval), #11/#5 flag debt (D5/D4), #3 (is_public schema/RLS), #7 (conflict-detection scope), #12 (canary automation). Rebased onto origin/main (was 18 behind; conflict-free — none of the 18 commits touched the 8 files). PR-policy CI green (confirmed no ragRankingPatterns match). | verify:pr-local exit 0 (351 files/3129 tests, production build, client-bundle secret scan, offline RAG fixtures 36/36); typecheck + lint + prettier green. verify:ui NOT run locally: pre-existing globals.css Tailwind/Turbopack dev-compile error (git-clean, unrelated; prod build passed) — CI Production UI job covers it. check:production-readiness deferred (offline env/config validator; PR changes no env/secret/config inputs; secretless worktree). No provider calls. |
| 2026-07-24 | PR #1132 / `codex/review-code-for-bugs-and-issues` (latest commit review: Next security patch + merge-readiness stabilizers) | 444972627e829775510638295665db09422f2812 | Scoped local review requested by user for remaining ASAP issues after latest PR commit. | No high-confidence code defect found in the current latest-commit diff. Recommended remaining ASAP work is process/environmental rather than another code patch: run the merge-readiness gate on Node 24.x, fetch/provide `main` or a remote so a true checkout-against-main check can run, and keep provider-backed/live gates approval-gated. Evidence: Next packages are updated to 16.2.11 in package.json/package-lock; `src/lib/search-scope.ts` adds batched label loading and abort propagation; sheet teardown guard prevents `document` access after DOM teardown; PDF deadline test now avoids scheduler-start race and zombie false-positive. | Local inspection: git status/HEAD/branch/remotes, latest commit diff, docs/codex-review-protocol.md. Prior checks from the commit: focused search/private-access tests passed, PDF/sheet focused tests passed, typecheck passed, npm audit high found 0 vulnerabilities. `npm run verify:cheap` remains blocked in this container by Node v20.20.2 vs repo Node 24.x engine / `node:module.registerHooks`; no hosted CI, GitHub, Supabase, OpenAI, or live provider calls. |
| 2026-07-24 | codex/reindex-agent-enrichment-guard (PR #1143) | f82cf9cfa | Run PR sweep: CI fix + threads + drift | Before: PR required green, 1 unresolved reindex/agent-claim serialization thread, branch behind main. After: remote branch already had atomic RPC fix 2bb0470d plus merge-main d2d57d7c; validated pushed head, resolved thread via GraphQL; reply mutation 403 noted in commit f82cf9cf. | node scripts/run-vitest.mjs run --reporter=dot tests/reindex-enrichment-lease.test.ts tests/private-access-routes.test.ts tests/supabase-schema.test.ts tests/drift-detection.test.ts PASS (218/218); npm run check:migration-role PASS; npm run typecheck PASS; npm run check:production-readiness PASS with non-blocking warnings; no live eval gates run. |

## 2026-07-24 — work search chrome behaviour review
Expand Down
84 changes: 12 additions & 72 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
"devDependencies": {
"@axe-core/playwright": "^4.12.1",
"@babel/parser": "^8.0.4",
"@next/bundle-analyzer": "^16.2.10",
"@next/bundle-analyzer": "^16.2.11",
"@tailwindcss/postcss": "^4.3.3",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^7.0.0",
Expand All @@ -226,7 +226,7 @@
"@vitest/coverage-v8": "^4.1.10",
"esbuild": "0.28.1",
"eslint": "^9.39.5",
"eslint-config-next": "16.2.10",
"eslint-config-next": "16.2.11",
"fast-check": "^4.8.0",
"jsdom": "^29.1.1",
"knip": "^6.27.0",
Expand Down
6 changes: 4 additions & 2 deletions src/app/api/search/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,9 @@ export async function POST(request: Request) {
const failurePayload = {
results: [],
telemetry: {
query_class: classifyRagQuery(error.message).queryClass,
query_class: fallbackBody
? classifyRagQuery(fallbackBody.query).queryClass
: classifyRagQuery(error.message).queryClass,
retrieval_strategy: null,
failure_code: code,
},
Expand All @@ -1031,7 +1033,7 @@ export async function POST(request: Request) {
logSearchObservation({
supabase,
ownerId,
query: "unknown",
query: fallbackBody?.query ?? "unknown",
results: [],
payload: failurePayload,
failure: {
Expand Down
1 change: 1 addition & 0 deletions src/components/ui/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ export function Sheet({
window.setTimeout(() => {
if (
restoreTarget.isConnected &&
typeof document !== "undefined" &&
document.activeElement !== restoreTarget &&
document.activeElement === document.body
) {
Expand Down
45 changes: 38 additions & 7 deletions src/lib/search-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const labelTypes = [
const sourceStatusValues = ["current", "review_due", "outdated", "unknown"] as const;
const validationStatusValues = ["unverified", "locally_reviewed", "approved"] as const;
const documentScopeQueryPageSize = 1000;
const labelScopeDocumentBatchSize = 200;
const labelScopeQueryPageSize = 1000;

export const searchScopeFiltersSchema = z
.object({
Expand Down Expand Up @@ -78,6 +80,7 @@ type ScopeDocumentRow = {
};

type ScopeLabelRow = {
id?: string;
document_id: string;
label: string;
label_type: DocumentLabelType;
Expand Down Expand Up @@ -163,6 +166,39 @@ function labelMatches(labels: ScopeLabelRow[], type: DocumentLabelType, requeste
return labels.some((label) => label.label_type === type && wanted.has(normalizeFilterText(label.label)));
}

async function loadScopeLabels(args: {
supabase: SupabaseClient;
candidateIds: string[];
signal?: AbortSignal;
}): Promise<ScopeLabelRow[]> {
const rows: ScopeLabelRow[] = [];

for (let start = 0; start < args.candidateIds.length; start += labelScopeDocumentBatchSize) {
const documentIdBatch = args.candidateIds.slice(start, start + labelScopeDocumentBatchSize);
for (let offset = 0; ; offset += labelScopeQueryPageSize) {
let labelQuery = args.supabase
.from("document_labels")
.select("id,document_id,label,label_type")
.in("document_id", documentIdBatch)
.in("label_type", [...labelTypes])
.order("document_id", { ascending: true })
.order("label_type", { ascending: true })
.order("label", { ascending: true })
.order("id", { ascending: true })
.range(offset, offset + labelScopeQueryPageSize - 1);
if (args.signal) labelQuery = labelQuery.abortSignal(args.signal);

const { data, error } = await labelQuery;
if (error) throw new Error(error.message);
const page = (data ?? []) as ScopeLabelRow[];
rows.push(...page);
if (page.length < labelScopeQueryPageSize) break;
}
}

return rows;
}

function isLocalSource(metadata: ClinicalSourceMetadata) {
const jurisdiction = `${metadata.jurisdiction ?? ""} ${metadata.publisher ?? ""}`.toLowerCase();
return /\b(?:wa|western australia|north metropolitan|east metropolitan|south metropolitan|perth|health service)\b/.test(
Expand Down Expand Up @@ -326,14 +362,9 @@ export async function resolveSearchScope(args: {
hasValues(filters.labelTypesAny);
let labelsByDocument = new Map<string, ScopeLabelRow[]>();
if (needsLabels) {
const { data: labelRows, error: labelError } = await args.supabase
.from("document_labels")
.select("document_id,label,label_type")
.in("document_id", candidateIds)
.in("label_type", [...labelTypes]);
if (labelError) throw new Error(labelError.message);
const labelRows = await loadScopeLabels({ supabase: args.supabase, candidateIds, signal: args.signal });
labelsByDocument = new Map();
for (const label of (labelRows ?? []) as ScopeLabelRow[]) {
for (const label of labelRows) {
labelsByDocument.set(label.document_id, [...(labelsByDocument.get(label.document_id) ?? []), label]);
}
}
Expand Down
Loading
Loading