Skip to content

fix: remediate 2026-07 repo audit findings (clinical answer path, data integrity, privacy) - #123

Merged
BigSimmo merged 3 commits into
mainfrom
claude/cool-wiles-12aade
Jul 2, 2026
Merged

fix: remediate 2026-07 repo audit findings (clinical answer path, data integrity, privacy)#123
BigSimmo merged 3 commits into
mainfrom
claude/cool-wiles-12aade

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

  • Remediates all 42 findings from the full multi-agent repo audit (report: docs/audit/repo-audit-2026-07-01.md), hardened by an adversarial review of the fix diff itself (R1–R13, all resolved).
  • Clinical answer path: numeric-verification corpus now covers everything shown to the model (synopsis, image table text, table-fact metadata snippets); sanitizer no longer deletes threshold sentences; copied ward-note tables share the on-screen conservative normalization + low-confidence caveat (incl. AccessibleTable parity); confidence scoped to cited chunks.
  • Data integrity: DELETE blocks pending reindex jobs; deep-memory computes embeddings before deleting old memory and fails closed on generation-lookup errors; perceptual hash ph1 (16-bit) → ph2 (192-bit); new migration 20260702000000_commit_generation_preserve_legacy_artifacts.sql (not yet applied to the live DB — apply via normal flow, then reindex:health + check:indexing), mirrored in the worker fallback; chunking forward-progress guard + whole-line page-noise anchoring.
  • Privacy/security: optional HMAC-keyed query hashing via new RAG_QUERY_HASH_SECRET (recommend setting wherever real queries are logged); non-string log fields serialized before redaction; timing-safe edge-function secret compare; fail-fast on non-retryable OpenAI 4xx.
  • Retrieval: retrieval-selection.ts + its governance contract test are aligned verbatim with PR RAG optimisation: answer quality (P1-P10), v17 numeric grounding, offline fallback, hybrid RPC hardening + golden-recall regression fix #118's relevance-first design (audit H3/L4 superseded by the measured golden-eval contract; no metadata weighting reintroduced).
  • Also: word-boundary intent signals with digit-attached dose support, classification fixes (site-in-title, BMJ false attribution, flowchart-vs-table), stale-search request guard incl. progress updates, strict CLI arg validation, dead-code removal, CSP host dedup, ~13 new regression tests.
  • Merged origin/main (through PR Merge codex/RAG_FIX modes (Differentials/Services/Forms/Favourites) restyled to Clinical White theme #120) into the branch; conflicts in search/route.ts and ClinicalDashboard.tsx resolved onto main's source-library/differentials refactor.

Verification

  • npm run verify:cheap — pass on the merged tree after clean npm ci (lint ✅, typecheck ✅, vitest 785 passed / 2 skipped across 98 files)
  • npm run verify:ui — not run locally; CI's chromium e2e gate covers the UI changes (ClinicalDashboard request guard, AccessibleTable header-source parity)
  • npm run verify:release — not run (no release claim)
  • npm run format:check — pass (drifted files on both branch and main formatted)
  • npm run check:production-readiness — not run locally (no .env in this worktree); check:production-readiness:ci runs in CI. Post-merge: apply the new migration, then run check:production-readiness + reindex:health + check:indexing
  • npm run check:deployment-readiness — covered by CI

Also run locally: npm run check:edge:functions (Deno) — pass.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use — strengthened: verification corpus now matches the model-visible corpus; quote/number gates fail closed
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval — none introduced; query-hash redaction strengthened (optional HMAC pseudonymization)
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only — RAG_QUERY_HASH_SECRET is server-only (not NEXT_PUBLIC_*); reviewer-verified no client-bundle leak
  • Demo/synthetic content remains clearly separated from real clinical sources — untouched
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative — governance enforcement stays in ranking penalties + answer/source-governance layer per the PR RAG optimisation: answer quality (P1-P10), v17 numeric grounding, offline fallback, hybrid RPC hardening + golden-recall regression fix #118 measured contract; deep-memory generation filter now fails closed
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed — behavior changes are conservative-direction (more caveats surfaced, fewer silent drops); the outstanding classification/TGA sign-offs tracked in docs/clinical-governance.md are unchanged by this PR

Notes

  • The audit report with per-finding outcomes, dispositions (L5/L9/L11/L18/L19), and the diff-review round is in docs/audit/repo-audit-2026-07-01.md.
  • Golden retrieval eval not re-run: retrieval-selection.ts matches origin/main byte-for-byte, so the 23/23 contract is unchanged.

🤖 Generated with Claude Code

BigSimmoand others added 3 commits July 2, 2026 11:28
…trieval, and ingestion paths
Full multi-agent audit (docs/audit/repo-audit-2026-07-01.md): 42 verified
findings fixed or explicitly dispositioned, then hardened by an adversarial
review of the fix diff itself (R1-R13).
Highlights:
- Answer path: numeric-verification corpus now covers retrieval synopses,
image table text, and table-fact metadata snippets (H1); sanitizer no longer
deletes clinical threshold sentences (H2); copied ward-note tables share the
on-screen conservative normalization + low-confidence caveat, with no
duplicated markdown header or ragged-row misalignment (H4/M8/M16, and
AccessibleTable parity).
- Retrieval: deriveConfidence scoped to cited chunks (M1); word-boundary
intent signals with digit-attached dose support (M2/M3); retrieval-selection
aligned verbatim with PR #118 relevance-first contract (H3/L4 superseded).
- Data integrity: DELETE blocks pending reindex jobs (M9); deep-memory builds
embeddings before deleting old memory and fails closed on generation-lookup
errors (M11/L8); perceptual hash 16-bit -> 192-bit ph2 (M12); new migration
20260702000000 preserves legacy NULL-generation artifacts unless replaced,
mirrored in the worker fallback (M13); chunking forward-progress guard and
whole-line page-noise anchoring (M14/M17).
- Privacy/security: optional HMAC-keyed query hashing via RAG_QUERY_HASH_SECRET
(M15); non-string log fields serialized before redaction (L12); timing-safe
edge-function secret compare and fail-fast 4xx (L20/L7); stale-search guard
incl. progress updates in ClinicalDashboard (M10/R9).
- Scripts/config: strict CLI arg validation (L1/L2/R13), classification fixes
(M4-M7/R10), dead-code removal (L15-L17), CSP host dedup (L13).
Verification: tsc clean; vitest 701 passed / 2 skipped (incl. ~13 new
regression tests); Deno edge-function typecheck clean. Lint not run locally
(eslint missing from worktree node_modules; pre-existing lockfile drift).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	src/app/api/search/route.ts
#	src/components/ClinicalDashboard.tsx
format:check now passes repo-wide (CI does not gate on it, so drift had
accumulated on main as well; includes the audit report and merge-touched
sources).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings July 2, 2026 04:09
@BigSimmo
BigSimmo merged commit 491e8e8 into mainJul 2, 2026
3 checks passed

CopilotAI 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.

Pull request overview

Remediates a broad set of clinical-safety, data-integrity, and privacy/security findings across the RAG answer path, ingestion/indexing pipeline, Supabase schema/RPCs, and supporting UI/scripts, with regression tests and a new migration to preserve legacy artifacts safely during reindex commits.

Changes:

  • Expands numeric/quote verification and table-handling so the verification corpus and clipboard/table outputs match the model-visible/cited corpus (synopsis, image table text, table-fact metadata), and preserves low-confidence caveats.
  • Hardens indexing/data-integrity paths (generation commit preservation rules, deep-memory rebuild ordering, delete guards, chunking forward-progress, perceptual hash upgrade).
  • Improves privacy/security/ops robustness (optional HMAC query hashing, safer log redaction for non-strings, timing-safe edge secret compare, fail-fast on non-retryable OpenAI 4xx, stricter CLI arg parsing).

Reviewed changes

Copilot reviewed 51 out of 51 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
worker/main.tsMirrors the new “preserve legacy artifacts unless replaced” rule in the worker fallback deletion logic; documents image I/O trade-off.
tests/ward-output.test.tsAdds regression coverage for clipboard/ward-note table normalization and caveat parity.
tests/supabase-schema.test.tsReformats assertions for schema/migration hybrid function ordering checks.
tests/source-text-sanitizer.test.tsAdds regression coverage for keeping threshold sentences while still dropping title-noise fragments.
tests/retrieval-selection.test.tsAdds coverage for clamping annotated hybrid_score and documents audit disposition context.
tests/rag-provider.test.tsMinor formatting update around rate-limit classification test.
tests/rag-content-accuracy.test.tsMinor formatting update for unbolding verified figures test.
tests/private-access-routes.test.tsExtends DELETE guard test to cover both pending and processing ingestion jobs.
tests/openai-error-mapping.test.tsMinor formatting update for quota-message classification test.
tests/image-filtering.test.tsUpdates tests to assert the new ph2 perceptual-hash format.
tests/document-organization.test.tsAdds regression tests for title-only site detection and BMJ false-attribution avoidance.
tests/deep-memory.test.tsUpdates behavior expectation to fail-closed when committed-generation lookup fails.
tests/clinical-search.test.tsAdds regression coverage for word-boundary intent signals and dose/visual focus detection.
tests/chunking.test.tsAdds regression tests for overlap>=chunkSize termination and inline page-reference preservation.
tests/answer-verification.test.tsAdds regression tests covering synopsis-only and image-table-text-only numeric verification.
tests/answer-prose-runons.test.tsMinor formatting update for run-on sentence polishing test.
supabase/schema.sqlUpdates commit_document_index_generation semantics in the schema snapshot to preserve legacy artifacts unless replaced.
supabase/migrations/20260702000000_commit_generation_preserve_legacy_artifacts.sqlIntroduces migration redefining commit_document_index_generation to avoid destroying legacy NULL-generation artifacts unless replacements exist.
supabase/functions/indexing-v3-agent/index.tsAdds timing-safe secret compare and fail-fast behavior for non-retryable OpenAI 4xx in embedding fetches; updates auth call site to await.
src/lib/ward-output.tsNormalizes copied tables via normalizeAccessibleTable, preserves low-confidence caveat, avoids header duplication and column shifts; avoids dangling headings.
src/lib/visual-intelligence.tsDerives medications from clinical vocabulary category matches instead of a hardcoded allowlist.
src/lib/validation/form-data.tsClarifies preprocess behavior so non-string multipart values are rejected (not silently coerced).
src/lib/source-text-sanitizer.tsAdds threshold-signal detection to prevent dropping threshold-bearing fragments; adjusts provenance scoring to avoid gating regressions.
src/lib/rag.tsScopes confidence derivation to cited chunks; expands table-fact quote corpus to include prompt-visible metadata snippet fields.
src/lib/rag-provider.tsType formatting cleanup for ProviderFailureKind union.
src/lib/query-privacy.tsAdds optional HMAC-SHA256 query hashing keyed by RAG_QUERY_HASH_SECRET (falls back to legacy SHA-256 when unset).
src/lib/privacy.tsSerializes non-string log fields before redaction to avoid leaking URLs/emails/secrets in structured fields.
src/lib/ingestion.tsSimplifies retryable-ingestion error logic and documents duplicate-key/manual-recovery path.
src/lib/image-filtering.tsUpgrades lightweight perceptual hash from ph1 (16-bit) to ph2 (192-bit) to reduce collisions.
src/lib/evidence.tsAllows callers to pass precomputed relevance/visualEvidence into buildSmartPanel to avoid recomputation.
src/lib/evidence-relevance.tsFixes unreachable “none” verdict; uses matched terms and score to avoid overstating evidence.
src/lib/env.tsAdds optional RAG_QUERY_HASH_SECRET env var with minimum length constraint.
src/lib/document-tags.tsRemoves misleading dead branches and clarifies label-noise behavior.
src/lib/document-organization.tsFixes BMJ attribution rule, expands evidence text to include title/filename with bracket stripping, and corrects fallback gating on confirmed candidates.
src/lib/document-index-units.tsPrevents “yes/no” from classifying table-like images as flowcharts unless structurally non-table.
src/lib/deep-memory.tsComputes embeddings before deleting existing rows; fails closed on committed-generation lookup errors.
src/lib/cross-document-synthesis.tsRemoves dead ternary and simplifies maxPerDocument assignment.
src/lib/clinical-search.tsMakes intent-signal matching word-boundary aware (with digit-adjacent doses) and preserves explicit dose signals despite escalation terms.
src/lib/chunking.tsAnchors page-noise stripping to whole lines and enforces forward progress when overlap>=chunkSize.
src/lib/answer-verification.tsExtends verification corpus to include retrieval_synopsis, image table text, and table-fact metadata snippet fields.
src/lib/answer-ranking.tsFixes bold-segment capping to count per-occurrence “free passes” rather than Set-based bypass.
src/components/ClinicalDashboard.tsxAdds request sequencing guard so only the latest in-flight search updates UI state and progress.
src/components/AccessibleTable.tsxEnsures markdown-parsed tables don’t incorrectly re-emit headers as data rows; keeps parity with clipboard normalization.
src/app/api/search/route.tsAvoids recomputing relevance/visual evidence by caching and passing precomputed values through to smart panel and payload.
src/app/api/documents/[id]/route.tsBlocks permanent delete when ingestion_jobs are pending or processing; improves the conflict message.
scripts/recover-ingestion-queue.tsReplaces permissive arg parsing with strict validation (unknown flags/missing values/invalid ints fail).
scripts/purge-query-logs.tsMakes CLI parsing fail loudly on unknown flags.
next.config.tsDeduplicates CSP connect-src Supabase host entry (keeps wildcard).
docs/rag-hybrid-findings-and-todo.mdMarkdown formatting tweaks (indentation/italics changes); note: current diff introduces broken indentation in one section.
docs/audit/repo-audit-2026-07-01.mdAdds the audit report documenting findings, fixes, verification, and dispositions.
.env.exampleDocuments the new optional RAG_QUERY_HASH_SECRET env var and its implications.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 78 to +79
fires for document_lookup/broad_summary (`shouldUseSecondStageRerank` needs `topScoresClose &&
hasVisualEvidence`, `rag.ts:548`). Widening it (RC10) could restore discrimination among the
hasVisualEvidence`, `rag.ts:548`). Widening it (RC10) could restore discrimination among the
Comment on lines +83 to +84
hnsw.ef_search='100'` on the three sql functions; **hosted Supabase denies it (`42501 permission
denied to set parameter`)** — the RC11 blocker. The only method hosted allows is the plpgsql-wrapper
@BigSimmo
BigSimmo deleted the claude/cool-wiles-12aade branch July 2, 2026 08:12
BigSimmo added a commit that referenced this pull request Jul 30, 2026
The open-items table was restored by hand after a #1415 conflict merge wiped it,
which left it off Prettier's formatting. verify:pr-local's format:changed gate
caught it. Table integrity re-verified: 59 open rows, my two rows intact as #123
and #124, no duplicate IDs, ledger guard passing at 1287 records.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@BigSimmo