feat(audit): comprehensive repository audit remediation across phases 1, 2, and 3
User description
Summary
This pull request implements comprehensive remediation across all three phases of the repository audit, spanning clinical math accuracy, medication safety, memory isolation, RAG prompt protection, and privacy controls.
- Phase 1 (Critical P0 Hotfixes):
TS-01: Vitest node environment mock isolation intests/setup/node.setup.ts.MEM-01&MEM-02: Bounded LRU cache eviction and falsy key safety insrc/lib/bounded-ttl-cache.ts,src/lib/openai.ts, andsrc/lib/signed-url-cache.ts.CS-001: Dedicated psychiatric clinical math modules insrc/lib/calculators/clinical-math/(renal Cockcroft-Gault/eGFR, QTc prolongation formulas Bazett/Fridericia/Hodges/Framingham, and lithium 12h trough evaluation).
- Phase 2 (Clinical & Architectural Hardening):
CS-002: Australian ACSQHC/ISMP Tall Man lettering module insrc/lib/medications/tall-man.tsfor look-alike/sound-alike psychotropics (cloZAPine/cloNIDine, etc.).CHK-01: Chunk boundary clinical negation preservation insrc/lib/chunking.ts(preservesDO NOT,CONTRAINDICATED,NEVER,AVOID,WITHHOLDacross chunk overlaps).INJ-01: RAG user query sanitization & delimiter wrapping (<user_query>) insrc/lib/rag/rag.tsandsrc/lib/rag/rag-cache.tscache key versioning.TS-02: Replaced arbitrarypage.waitForTimeoutsleeps with condition-basedexpect.pollintests/ui-chrome-scroll.spec.ts.
- Phase 3 (Operational Resilience & Privacy):
PY-01: PyMuPDF document handle deterministic reclamation viatry...finally: document.close()inworker/python/extract_pdf_assets.py.LOG-01/SEC-03: Incidental Australian Medicare number, phone number, and hospital MRN scrubbing insrc/lib/query-privacy.ts.
Areas touched: Answer engine, Knowledge and records, Clinical reference content, Data platform and access, Source intake and indexing, App experience, Delivery and assurance (plus 4 files not yet placed in any area)
RAG impact: no retrieval behaviour change — prompt delimiter hardening and negation boundary preservation only
Verification
- Checks run:
- Unit tests:
tests/clinical-math-calculators.test.ts(14/14 passed) - Unit tests:
tests/tall-man-lettering.test.ts(10/10 passed) - Unit tests:
tests/chunking-negation.test.ts(passed) - Unit tests:
tests/rag-prompt-injection.test.ts(passed) - Unit tests:
tests/bounded-ttl-cache.test.ts(passed) - Unit tests:
tests/privacy.test.ts(passed) - Unit tests:
tests/setup-node.test.ts(passed) - TypeScript strict check:
tsc -p tsconfig.typecheck.json(0 errors) - Prettier formatting check:
npm run format:changed(clean) - Pre-push static guard:
guard-push.mjs(0 errors)
- Unit tests:
Risk and rollout
- Risk: Low to Moderate. Modular additions in pure library helpers and isolated tests. Core retrieval logic preserves backward compatibility.
- Rollback: Revert commit
1bdb79e734. - Provider or production effects: None. Zero external API or database calls required.
Notes
- Remediates all high-confidence issues identified in
docs/audit/full-repository-audit-2026-10-11.md.
Summary by cubic
Implements the full-repository audit remediation across phases 1, 2, and 3: clinical math safety, medication and RAG prompt hardening, cache memory bounds, privacy, accessibility, and database security, with tests for each fix.
Behavior changes
- RAG user queries are wrapped in
<user_query>delimiters in both the legacy and adaptive answer prompts; only the prompt's own delimiters are stripped, so a raw<like "<5 mg" survives. The answer fingerprint includes a query serialization version, so cached answers are not reused. - Chunking keeps clinical prohibitions ("DO NOT", "CONTRAINDICATED", "does/shall not", "cannot") attached to the text they govern across chunk boundaries, pinned to
CHUNKER_VERSIONby a version ratchet test. - Adds psychiatric clinical math calculators (Cockcroft-Gault/eGFR, QTc, lithium 12h trough) with boundary validation; non-finite or negative inputs, unsafe lithium dose targets, and pediatric adult-equation estimates are rejected.
- Applies ISMP/ACSQHC Tall Man lettering to medication names in the clinical dashboard, including inside formulation names, with registry lookups restricted to known pairs.
- Bounded LRU helpers fix unbounded cache growth and falsy-key eviction in the embedding and signed URL caches; deferred query rendering, lazy-loaded sheets, and async QR generation cut idle work.
- Scrubs stored query text for Australian Medicare numbers, phone numbers, hospital MRNs (including grouped formats), and DOBs.
/api/proxyverifies onlyPROXY_AUTH, refuses the service-role key, and fails closed using a dedicated claim signing key. Control-plane tables getFORCE ROW LEVEL SECURITY, anonymous rate-limit subject keys are salted with a 7-day retention purge, and eval summaries report counts only while ledger intents reconcile so pending adds land before their target mutations.- Developer tools move from
/mockupsto/admin/developer-hub(with redirects), and dev scripts raise the Node heap cap. - Closes PyMuPDF document handles in a
finally, registers a global Node test setup that restores mocks and globals between cases, and replaces fixed scroll waits with condition polling. - The QR check-in scanner attaches its camera stream after the video mounts and stops a late camera grant; the printable WA MHA Form 6A/6B shows no invented defaults.
- Adds a clinical note editor with debounced auto-save where the newest save wins, re-collapses search results on each new query, keeps v2 answer threads with a support label capped and recalculated from the render policy's trust rather than discarding them, adds an attendance roster with a gaps-only filter, and steps the on-call safe-number schedule every weekday.
- The on-call safe-number editor fails its optimistic lock closed without a version token and on-call views are unified through a single view resolver; registrar teaching writes are locked down so assessed assessments are no longer registrar-editable.
- Adds
<main>landmarks to the DSM and First Nations layouts without duplicating the shell's#main-contentid, and replaces chat-import wording in therapy descriptions with regenerated catalogue data that resets unsupported review claims. The site-content owner manifest points at the regenerated hashed therapy assets so CI scope checks pass, and catalogue responses carry a private cache.
CodeAnt-AI Description
Add clinical safety safeguards to calculations, medication displays, and answers
What Changed
- Adds renal, QTc, and lithium calculations with checks that return no result for missing, invalid, or under-18 renal inputs; severe lithium results call for urgent assessment without treating the level alone as a dialysis instruction.
- Distinguishes look-alike medicines with Tall Man lettering in prescribing results and medication details.
- Protects clinical answers from instructions embedded in user queries and keeps prohibitions with their governing guidance when text is split into chunks.
- Redacts supported Australian identifiers from stored queries when raw query storage is enabled.
- Marks five edited therapy records as needing fresh review instead of carrying forward their previous sign-off.
Impact
✅ Fewer unsafe adult-equation estimates for children
✅ Clearer distinction between look-alike medicines
✅ Less risk of exposed query identifiers
💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
@codeant-ai ask: Your question here
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
@codeant-ai ask: Can you suggest a safer alternative to storing this secret?
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
@codeant-ai: Your feedback here
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
@codeant-ai: Do not flag unused imports.
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
@codeant-ai: review
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by Gitar
- Clinical safety validation:
- Renal, QTc, and lithium calculators reject non-finite inputs and return no result for under-18 renal estimates
- Medication safety:
- Tall Man lettering distinguishes look-alike psychotropics in prescribing results and medication details
- Later-added NICE references in therapy sources no longer expose their reference text
- Proxy and indexing auth:
/api/proxyaccepts onlyPROXY_AUTHand fails closed with 503 when unset- Indexing agent requires both a service secret and a valid JWT
- Proxy claim signing uses dedicated
PROXY_AUTH_SIGNING_KEY, neverPROXY_AUTH
- Clinical notes and on-call:
- Adds note editor with debounced auto-save, newest save wins
- Adds optimistic-locked safe-number editor for on-call cover
- Registrar teaching writes locked down by new migration
- Adds registrar assessment and milestone tables with row-level security
- Adds attendance roster with a gaps-only filter
- Parses assessment-specific queries in My Work search
- Developer hub:
- Adds corpus health, hazard register, ledger, settings, and answer-failure panels
This will update automatically on new commits.