Skip to content

fix: remediate full-deep audit findings and retain release holds - #3640

Closed
BigSimmo wants to merge 13 commits into
mainfrom
codex/full-deep-audit-remediation-20261018
Closed

BigSimmo wants to merge 13 commits into
mainfrom
codex/full-deep-audit-remediation-20261018

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Prevent stale account requests and rollback from updating a different user's favourites, roster, sharing and calendar state; correct pay-history loading and selected-timezone conversions.
  • Make CME cleanup and ingestion recovery durable and transactional; minimize upload/worker diagnostics, harden RAG cache revocation/freshness and request coalescing, and preserve calculator/staff release holds.
  • Add an explicit isolated rootless catalog replay backend while retaining Docker as the default, preserve all existing migration seals, and document the audit findings, implementation and outstanding acceptance conditions.

Areas touched: App experience; Personal practice; Data platform and access; Answer engine; Source intake and indexing; Delivery and assurance; Knowledge and records.

RAG impact: behaviour change — cache governance/freshness, revocation, fallback and request coalescing. Provider-backed before/after canary evidence is not available; it remains an owner-authorized acceptance condition.

Verification

  • Final candidate: 83a49c5fac0945613114255a4e672a05a5aec3d0. Its parent integration 53ac94091f6072c9b93ac596ce06a45f40447f64, preserving prior PR head f70929e5306413bab2f90348fb68f9ddec8cf450 and merging fetched main 807ce0cb2b8f0850e6c41f04b0b00e856bd585fb once, without conflicts.
  • Fresh local integration proof: all 314/314 selected complete owning tests and 15/15 Codex hook fixture tests passed. The owned report was formatted, the normal pre-commit synchronization hook passed, and the normal guarded push succeeded without bypasses or force. No full local suite rerun is claimed. The subsequent test-only result-readiness correction passed 5/5 repeated cases and 16/16 complete owning Chromium mockup cases with retries disabled, on the offline local development server. Independent source review confirmed the positive and exact-count assertions remain intact; its normal guarded push also passed.
  • Exact prior-head CI run 39115639624 passed selected unit coverage, lint/types, build, containers, local migration/schema/manifest, Chromium UI and offline RAG checks: Required in-scope PR checks passed. It tested f70929e into base9ba5, not the new candidate; skipped release-browser/provider checks are not passes.
  • Integration53 core CI 39117859413 completed success at10:24UTC: migration replay/schema/drift, unit coverage, production UI, static checks, builds and containers passed. Advisory UI retained one actual count-before-readiness failure; the final83 test-only correction addresses it with the local evidence above. Final83 CI is separately pending, not covered by the earlier core pass.
  • Supabase Preview is not verified: its first new-head check failed, a later same-suite check skipped with an association error while fresh provider inventory still lists the failed preview. The retained failure is: Remote migration versions not found in local migrations directory. Read-only comparison retained both complete322-version sets: only remote 20261017221129 versus only local 20261018082910. Documented preview recreation is prepared but not approved/executed; it deletes preview-only state and may incur compute charges.
  • The earlier exactly approved postgres staging default repair remains effective; reserved-creator defaults remain open. No production SQL, new live database change, paid provider evaluation or deployment occurred in this continuation.
  • Exact GitHub high alerts are #24 and #27: NLTK3.10.3 in the worker and cloud Python locks, GHSA-8mgp-746c-j5xp. The authorized existing Composio/GitHub connection resolved the alert-capability gap; PyPI latest is3.10.3 and no fixed upstream release exists. Static call-path review found no caller-controlled model path into the affected persistence APIs, which bounds demonstrated reachability but does not fix/dismiss the alerts.
  • The separate high braces npm advisory GHSA-vfj7-8cjw-p6xm also has no patched upstream version; it remains development-only via Next's ESLint chain. No alert dismissal, invented version or incompatible alias was used. Earlier blocked Python advisory lookup is retained as failed evidence; the exact two repository alerts are now identified.

See docs/audit/2026-10-17-full-deep-remediation-results.md for dated source boundaries, actual failed/passing evidence and the rapid follow-through. Private raw artifacts remain session-local; this PR does not publish them.

Risk and rollout

  • Risk: High. This crosses account isolation, recovery state, private-document cleanup, clinical holds and RAG cache boundaries. Fetched main807ce0cb is now merged and locally verified; later remote drift and new-head hosted CI still require their own evidence. Qualified clinical/privacy/provider approvals and candidate-matched hosted verification remain unmet.
  • Rollback: Revert application changes in a reviewed commit while retaining clinical/privacy holds. SQL and durable queue/state changes need a separately reviewed compatibility and data-recovery plan; reverting TypeScript alone does not undo database effects.
  • Provider or production effects: Creating/updating this PR may trigger configured GitHub CI and the existing Supabase preview-branch integration. No paid RAG evaluation, Railway deployment, production SQL application or merge is authorized by this publication. The earlier approved staging-only default-grant operation is documented separately.

Merge only inside the owner's specifically approved production database window. This PR contains supabase/migrations/20261018082910_audit_durable_recovery_pairing_and_cache_fences.sql; merging to main automatically applies migrations to the live clinical database within seconds. This continuation did not alter owner-controlled auto-merge state. The exact draft hash remains f0667fed9f0294c1f5ba40252d11ee66e6de07be340a1ec789e0503a1192f2ac.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains PsychSift Production (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed

Physiological calculators and staff activation remain held. No qualified clinical, legal, privacy or provider sign-off was fabricated. The four pending/partial privacy conditions, reserved-creator platform repair and candidate-matched hosted Auth/Storage/RAG/cache/performance/rollout evidence remain open. The unchecked classification item is not represented as satisfied.

Notes

This PR publishes the remediation with current-main integration and explicit remaining conditions. It is not a release-readiness assertion, a new repository score, a deployment record or permission to merge. The original /workspace/PsychSift working tree is preserved.


Summary by cubic

Remediates full-deep audit findings: stale account requests and rollbacks can no longer mutate another user's favourites, roster, sharing, or calendar state; CME removal is transactional and durable; ingestion recovery is atomic per document with lease-based expiry; and RAG cache hits are fenced by an authoritative database scope revision instead of the latest-indexed-document stamp. Upload and worker diagnostics are now content-free, with superseded-object release failures reported as structured { stage, code } pairs that never carry raw provider or database messages; worker fatal alerts now read the allowlisted code from the wrapped cause so they report the real failure code instead of unclassified. Request coalescing is isolated in its own module, and physiological calculators, sick-call access, and staff activation remain withheld pending clinical and provider review.

A post-review automated edit to the sealed draft migration was reverted; the migration was resealed to the owner-reviewed bytes and renamed to sort after main's newest migration without changing its hash. The duplicate-job retry close-out and cache-revision metadata change are deferred to a separate reviewed PR.

Rollout

  • The migration is a draft; merging applies it to the live clinical database automatically, so merge only inside the owner's approved window.
  • Reverting the TypeScript alone does not undo the SQL and durable queue changes; they need a separately reviewed compatibility and recovery plan.
  • The drift manifest was three-way merged against main; CI regenerates and verifies it since Docker is unavailable locally.

Verification

  • No hosted CI run or provider-backed RAG canary evidence is claimed; earlier local test selection passed on the pinned candidate, not on current main.
  • Newly added suites wait for search results before asserting rendered counts, so evaluation of the revised RAG paths does not flake on rendering timing.

Written for commit 83a49c5. Summary will update on new commits.

View guided diff Turn on auto-fix

@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Next included review available in 8 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 124 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: BigSimmo/PsychSift/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Team
  • Run ID: b01a4d73-4346-4e1d-b017-ee7c0d19b45d
📥 Commits

Reviewing files that changed from the base of the PR and between 807ce0c and 83a49c5.

📒 Files selected for processing: 113
  • data/repo-awareness-snapshot.json
  • docs/README.md
  • docs/agents/codex-cloud-legacy-bootstrap.md
  • docs/audit/2026-10-17-full-deep-remediation-results.md
  • docs/audit/2026-10-17-full-deep-remediation-spec.md
  • docs/database-drift-detection.md
  • docs/error-tracking.md
  • docs/governance/clinical-release-remediation-handoff-2026-10-17.md
  • docs/governance/physiological-calculator-hold-2026-10-17.md
  • docs/observability-slos.md
  • docs/organisation/systems/data-platform.json
  • docs/organisation/systems/personal-practice.json
  • docs/rag-behaviour/README.md
  • docs/rag-behaviour/cache-freshness.md
  • docs/rag-injection-threat-model.md
  • docs/reindex-runbook.md
  • docs/scripts-index.md
  • docs/superpowers/plans/2026-10-17-full-deep-remediation.md
  • railway.worker.json
  • scripts/check-worker-python-lock.mjs
  • scripts/generate-drift-manifest.ts
  • scripts/generate-worker-python-lock.mjs
  • scripts/lib/drift-rootless.ts
  • scripts/recover-ingestion-queue.ts
  • scripts/reindex.ts
  • scripts/test-run-lock.mjs
  • scripts/worker-python-lock-config.mjs
  • src/app/api/documents/[id]/reviews/route.ts
  • src/app/api/upload/route.ts
  • src/app/api/work/hospital/sick/route.ts
  • src/components/account-data-provider.tsx
  • src/components/admin/admin-new-job-page.tsx
  • src/components/admin/junior/use-roster-leave.ts
  • src/components/admin/new-job/admin-new-job-sharing.tsx
  • src/components/calculators/clinical-math-panel.tsx
  • src/components/roster/manage/roster-cover-tab.tsx
  • src/components/roster/roster-month-page.tsx
  • src/components/roster/roster-settings-page.tsx
  • src/components/roster/use-roster-links.ts
  • src/components/roster/use-roster-settings.ts
  • src/components/roster/use-roster-shifts.ts
  • src/components/roster/use-roster-team.ts
  • src/components/teaching/organise-model.ts
  • src/components/use-account-request-scope.ts
  • src/components/work-calendar/use-work-calendar-entries.ts
  • src/components/work-screens/admin/pay-page.tsx
  • src/instrumentation.ts
  • src/lib/calculators/clinical-math/governance.json
  • src/lib/cme/evidence-repository.ts
  • src/lib/ingestion-recovery.ts
  • src/lib/logger.ts
  • src/lib/observability/agent-monitoring.ts
  • src/lib/open-shifts/mine.ts
  • src/lib/open-shifts/posted.ts
  • src/lib/privacy.ts
  • src/lib/rag/rag-answer-coalescing.ts
  • src/lib/rag/rag-cache.ts
  • src/lib/rag/rag.ts
  • src/lib/site-content/adapters/index.ts
  • src/lib/supabase/database.types.ts
  • src/lib/trusted-document-admission.ts
  • src/lib/work-roles/people.ts
  • supabase/applied-migration-hashes.json
  • supabase/drift-manifest.json
  • supabase/migrations/20261018082910_audit_durable_recovery_pairing_and_cache_fences.sql
  • supabase/schema.sql
  • tests/account-request-scope.dom.test.tsx
  • tests/admin-auth-transition.dom.test.tsx
  • tests/admin-new-job-page.dom.test.tsx
  • tests/admin-pay-history.dom.test.tsx
  • tests/agent-monitoring.test.ts
  • tests/clinical-math-bounds.test.ts
  • tests/clinical-math-governance.dom.test.tsx
  • tests/clinical-math-governance.test.ts
  • tests/clinical-math-panel-breakpoint.dom.test.tsx
  • tests/cme-evidence-api.test.ts
  • tests/diagnostic-minimisation.test.ts
  • tests/drift-rootless.test.ts
  • tests/factsheets-summary-context.test.ts
  • tests/favourites-session-race.dom.test.tsx
  • tests/fixtures/site-content/static-manifest-baseline.json
  • tests/hosted-migration-role-guard.test.ts
  • tests/ingestion-recovery.test.ts
  • tests/instrumentation.test.ts
  • tests/open-shifts-zone.test.ts
  • tests/operational-alerts.test.ts
  • tests/rag-answer-fallback.test.ts
  • tests/rag-cache-governance-revocation.test.ts
  • tests/rag-cache-indexing-stamp.test.ts
  • tests/rag-cache-invalidation.test.ts
  • tests/rag-cache-lru.test.ts
  • tests/rag-cache-test-revision.ts
  • tests/rag-shared-cache.test.ts
  • tests/rag-site-content-freshness.test.ts
  • tests/rag-tail-latency.test.ts
  • tests/railway-config.test.ts
  • tests/retrieval-access-scope.test.ts
  • tests/roster-auth-transition.dom.test.tsx
  • tests/roster-cover-tab.dom.test.tsx
  • tests/roster-month-page.dom.test.tsx
  • tests/test-runner-safety.test.ts
  • tests/trusted-document-admission.test.ts
  • tests/ui-tools-search-mode-mockup.spec.ts
  • tests/ui-tools.spec.ts
  • tests/upload-diagnostic-minimisation.test.ts
  • tests/work-calendar-entries-enabled.dom.test.tsx
  • tests/work-roles-hospital-sick-release.test.ts
  • tests/work-roles-hospital-sick.test.ts
  • tests/work-roles-people-changes.test.ts
  • tests/worker-python-lock.test.ts
  • worker/main.ts
  • worker/python/requirements-cloud.in
  • worker/python/requirements-cloud.txt
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@supabase

supabase Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Updates to Preview Branch (codex/full-deep-audit-remediation-20261018) ↗︎

Deployments Status Updated
Database ✅ Sun, 18 Oct 2026 10:26:04 UTC
Services ✅ Sun, 18 Oct 2026 10:26:04 UTC
APIs ✅ Sun, 18 Oct 2026 10:26:04 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations ✅ Sun, 18 Oct 2026 10:26:05 UTC
Migrations ❌ Sun, 18 Oct 2026 10:26:07 UTC
Seeding ⏸️ Sun, 18 Oct 2026 10:25:47 UTC
Edge Functions ⏸️ Sun, 18 Oct 2026 10:25:47 UTC

❌ Branch Error • Sun, 18 Oct 2026 10:26:08 UTC

Remote migration versions not found in local migrations directory.

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

@BigSimmo
BigSimmo marked this pull request as ready for review October 18, 2026 07:46

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BigSimmo has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@codeant-ai

codeant-ai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Skipping CodeAnt AI review — this PR changes more than 100 files, which usually means a migration, codemod, or vendored drop. Line-level review on diffs this large produces duplicate findings on the same rewrite pattern and drowns out anything that actually matters.

If you still want a review, comment @codeant-ai : review. For better signal, consider splitting the PR into smaller chunks.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-18T07:55:14.625720Z 86540ab Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Comment thread src/lib/rag/rag-cache.ts Resolved
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Remediate audit findings while retaining clinical release holds

🐞 Bug fix ✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Fence account-scoped requests and correct roster, pay-history, and selected-timezone behaviour.
• Make cleanup and recovery transactional; strengthen RAG freshness, revocation, and diagnostic
 privacy.
• Add isolated catalog replay and regression coverage while documenting unresolved release and
 hosted-acceptance conditions.
Diagram

graph TD
  Auth["Auth session"] --> UI["Account-scoped UI"] --> API["Application APIs"] --> SQL["Transactional SQL"] --> Store["Postgres state"]
  RAG["RAG cache"] --> SQL
  Replay["Catalog replay"] --> Store
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Application-only compensation
  • ➕ Avoids adding database RPCs and rollout dependencies.
  • ➖ Cannot atomically commit cleanup with tombstones or reliably fence worker claims and team moves.
2. Event-driven RAG invalidation
  • ➕ Could avoid hashing the full document scope on each eligible cache lookup.
  • ➖ Requires a dependable cross-replica invalidation or revision service and additional failure-mode proof before revocation can be trusted.

Recommendation: Prefer the PR’s transactional SQL and fail-cold scope revision approach for the identified safety failures. Preserve the documented SQL-first rollout, old-replica drain, performance measurement, and clinical/privacy holds; local tests and catalog replay do not substitute for hosted or provider-backed acceptance.

Files changed (109) +8795 / -1339

Enhancement (4) +861 / -54
generate-drift-manifest.tsAdd selectable catalog replay backend +157/-54

Add selectable catalog replay backend

• Shares schema replay and snapshot validation between Docker and explicit rootless execution. Publishes the generated manifest atomically after successful replay and cleanup.

scripts/generate-drift-manifest.ts

drift-rootless.tsImplement isolated offline rootless replay +616/-0

Implement isolated offline rootless replay

• Verifies pinned OCI bytes and the trusted unpacker, then runs PostgreSQL in an isolated rootless namespace. Bounds outputs, records private provenance, and requires verified shutdown and owned-run cleanup.

scripts/lib/drift-rootless.ts

use-account-request-scope.tsAdd shared auth-epoch request fence +34/-0

Add shared auth-epoch request fence

• Provides a reusable current-identity check for retained callbacks, timers, and asynchronous component work.

src/components/use-account-request-scope.ts

privacy.tsAdd content-free error classification +54/-0

Add content-free error classification

• Returns bounded known error types, codes, and HTTP statuses without forwarding arbitrary messages or unsafe properties.

src/lib/privacy.ts

Bug fix (34) +1564 / -679
recover-ingestion-queue.tsUse atomic ingestion recovery actions +25/-185

Use atomic ingestion recovery actions

• Replaces separate destructive recovery writes with the shared lease-aware recovery RPC and current-state reconciliation.

scripts/recover-ingestion-queue.ts

reindex.tsRoute reindex recovery through fenced RPC +45/-73

Route reindex recovery through fenced RPC

• Makes its recovery path use the shared atomic action helper instead of obsolete reset and lock handling.

scripts/reindex.ts

test-run-lock.mjsRecognize defunct test-lock owners safely +18/-2

Recognize defunct test-lock owners safely

• Treats a confirmed single-threaded Linux zombie as dead while retaining conservative behaviour for live or unknown owners.

scripts/test-run-lock.mjs

route.tsInvalidate cache after source review +2/-0

Invalidate cache after source review

• Strengthens review-triggered cache invalidation for changed document governance.

src/app/api/documents/[id]/reviews/route.ts

route.tsMinimize upload cleanup diagnostics +27/-23

Minimize upload cleanup diagnostics

• Replaces object paths and provider prose in logs with opaque references and fixed error classifications. Awaits duplicate-upload compensation so failures remain within its cleanup handling.

src/app/api/upload/route.ts

route.tsEnforce real-staff sick-report release hold +7/-0

Enforce real-staff sick-report release hold

• Rejects held requests before creating a reader or admin client while preserving enabled-path authorization checks.

src/app/api/work/hospital/sick/route.ts

account-data-provider.tsxFence favourites state by auth identity +102/-18

Fence favourites state by auth identity

• Clears account state and mutation queues on identity transitions. Rejects stale loads, saves, failures, rollbacks, and session-expiry effects.

src/components/account-data-provider.tsx

admin-new-job-page.tsxFence New Job actions across account changes +26/-3

Fence New Job actions across account changes

• Clears pending editor and undo state and prevents stale callbacks from changing another account’s view.

src/components/admin/admin-new-job-page.tsx

use-roster-leave.tsScope roster-leave reads to the current account +8/-5

Scope roster-leave reads to the current account

• Prevents a previous identity’s asynchronous leave results from updating retained state.

src/components/admin/junior/use-roster-leave.ts

admin-new-job-sharing.tsxScope sharing state and saves by account +22/-7

Scope sharing state and saves by account

• Keys loaded sharing data to the identity and ignores stale reads, retries, and save completions.

src/components/admin/new-job/admin-new-job-sharing.tsx

clinical-math-panel.tsxWithhold unapproved physiological calculators +25/-0

Withhold unapproved physiological calculators

• Displays a release-hold notice rather than renal, QTc, or lithium outputs until explicit governance approval is recorded.

src/components/calculators/clinical-math-panel.tsx

roster-cover-tab.tsxConvert cover gaps in the selected timezone +27/-8

Convert cover gaps in the selected timezone

• Uses work-zone wall-time conversion and rejects nonexistent daylight-saving times before posting a gap.

src/components/roster/manage/roster-cover-tab.tsx

roster-month-page.tsxExpose failed calendar sources in Roster +16/-1

Expose failed calendar sources in Roster

• Shows separate rotation and course-booking failures with source-specific retries while keeping successfully loaded entries visible.

src/components/roster/roster-month-page.tsx

roster-settings-page.tsxCancel pending Roster actions on account change +27/-2

Cancel pending Roster actions on account change

• Resets destructive-action and notice state, and prevents a delayed delete or save result from affecting the next identity.

src/components/roster/roster-settings-page.tsx

use-roster-links.tsFence calendar-link reads and mutations +79/-43

Fence calendar-link reads and mutations

• Clears retained links on account changes and ignores stale fetch, refresh, add, and remove completions.

src/components/roster/use-roster-links.ts

use-roster-settings.tsIsolate settings and write queues per account +30/-8

Isolate settings and write queues per account

• Resets settings and the serial mutation queue on identity changes; stale responses cannot restore prior-account data.

src/components/roster/use-roster-settings.ts

use-roster-shifts.tsFence shifts and history by account +72/-28

Fence shifts and history by account

• Resets retained shift, team, and history state and rejects stale reads or save completions.

src/components/roster/use-roster-shifts.ts

use-roster-team.tsKey Roster team reads to account scope +11/-6

Key Roster team reads to account scope

• Includes account scope in retained read state and ignores results from an obsolete identity.

src/components/roster/use-roster-team.ts

organise-model.tsPreserve Teaching instants across timezone edits +15/-5

Preserve Teaching instants across timezone edits

• Converts changed wall times using the selected zone, rejects skipped times, and retains the original instant for an unchanged clock time.

src/components/teaching/organise-model.ts

use-work-calendar-entries.tsRetry failed calendar sources individually +8/-6

Retry failed calendar sources individually

• Allows callers to retry one failed source without discarding successfully loaded sources.

src/components/work-calendar/use-work-calendar-entries.ts

pay-page.tsxLoad complete current and previous pay windows +14/-4

Load complete current and previous pay windows

• Requests own-shift history across both fortnights, including the UTC boundary day, and exposes history loading or failure.

src/components/work-screens/admin/pay-page.tsx

instrumentation.tsKeep Node startup dependencies out of Edge builds +82/-84

Keep Node startup dependencies out of Edge builds

• Encloses Node-only startup imports in a positive Node runtime branch while retaining production environment guards and Edge Sentry initialization.

src/instrumentation.ts

evidence-repository.tsUse durable CME removal RPC +11/-11

Use durable CME removal RPC

• Calls the versioned transaction that queues exact-object cleanup with the tombstone; immediate Storage deletion becomes best effort.

src/lib/cme/evidence-repository.ts

ingestion-recovery.tsShare lease-aware recovery planning and execution +59/-9

Share lease-aware recovery planning and execution

• Uses lease expiry and expected-state snapshots, preserves indexed artifacts, and applies actions through one atomic RPC contract.

src/lib/ingestion-recovery.ts

logger.tsTighten logged error handling +1/-1

Tighten logged error handling

• Adjusts logger behaviour to support minimized diagnostics.

src/lib/logger.ts

agent-monitoring.tsMinimize agent monitoring identifiers +6/-1

Minimize agent monitoring identifiers

• Avoids exposing free-form identifier content in monitoring context.

src/lib/observability/agent-monitoring.ts

mine.tsUse selected-zone boundaries for hours meter +4/-4

Use selected-zone boundaries for hours meter

• Replaces fixed Perth midnight offsets when measuring rolling work-hour windows.

src/lib/open-shifts/mine.ts

posted.tsUse selected-zone dates for posted shifts +2/-2

Use selected-zone dates for posted shifts

• Removes fixed-offset assumptions from posted-shift date calculations.

src/lib/open-shifts/posted.ts

rag-answer-coalescing.tsFence in-flight answer sharing by revision +87/-0

Fence in-flight answer sharing by revision

• Rechecks scope revision after waiting, originates against current state when freshness changes, and avoids replacing another caller’s promise.

src/lib/rag/rag-answer-coalescing.ts

rag-cache.tsRequire fresh scope revisions for RAG reuse +107/-107

Require fresh scope revisions for RAG reuse

• Replaces the memoized latest-document stamp with a fail-cold full-scope revision RPC. Fences local and shared cache reads, writes, and invalidation, and advances the dependency namespace.

src/lib/rag/rag-cache.ts

index.tsPreserve Factsheet summary-use context +12/-2

Preserve Factsheet summary-use context

• Adds demonstration-use notice and content-month meaning to Factsheet retrieval text and lineage.

src/lib/site-content/adapters/index.ts

people.tsMove hospital teams through atomic RPC +14/-27

Move hospital teams through atomic RPC

• Replaces the separate move and grant-revocation writes with a versioned transactional operation and maps its failure outcomes.

src/lib/work-roles/people.ts

20261017221129_audit_durable_recovery_pairing_and_cache_fences.sqlAdd transactional audit-remediation contracts +569/-0

Add transactional audit-remediation contracts

• Atomically pairs CME tombstones with cleanup jobs, fences ingestion recovery, adds RAG scope revisions, and serializes team authority and Teaching pairing changes. Introduces service-role RPC grants and backfills existing CME tombstones; deployment requires an approved database window.

supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql

main.tsMinimize fatal worker alerts +4/-4

Minimize fatal worker alerts

• Replaces free-form exception prose in fatal diagnostics and webhook payloads with bounded classifications.

worker/main.ts

Refactor (1) +4 / -55
rag.tsDelegate revision-aware answer coalescing +4/-55

Delegate revision-aware answer coalescing

• Routes answer requests through the extracted coalescing helper without changing retrieval ranking.

src/lib/rag/rag.ts

Tests (42) +4001 / -418
account-request-scope.dom.test.tsxTest auth-epoch request scope +121/-0

Test auth-epoch request scope

• Checks current versus retained callback behaviour across mounted account changes.

tests/account-request-scope.dom.test.tsx

admin-auth-transition.dom.test.tsxTest New Job account transitions +95/-0

Test New Job account transitions

• Covers stale admin interactions and state after switching identities.

tests/admin-auth-transition.dom.test.tsx

admin-new-job-page.dom.test.tsxAdjust New Job component coverage +36/-1

Adjust New Job component coverage

• Extends existing page tests for the fenced interaction behaviour.

tests/admin-new-job-page.dom.test.tsx

admin-pay-history.dom.test.tsxTest full-fortnight pay prefill +176/-0

Test full-fortnight pay prefill

• Covers older roster days, UTC boundary inclusion, and loading or failed history.

tests/admin-pay-history.dom.test.tsx

agent-monitoring.test.tsTest minimized agent monitoring +76/-0

Test minimized agent monitoring

• Checks that monitoring output does not retain sensitive diagnostic content.

tests/agent-monitoring.test.ts

clinical-math-bounds.test.tsRetain calculator bounds tests under hold +54/-2

Retain calculator bounds tests under hold

• Separates synthetic arithmetic checks from assertions about production availability.

tests/clinical-math-bounds.test.ts

clinical-math-governance.dom.test.tsxTest calculator hold rendering +30/-0

Test calculator hold rendering

• Verifies pending clinical governance withholds physiological outputs.

tests/clinical-math-governance.dom.test.tsx

clinical-math-governance.test.tsTest calculator governance inventory +55/-0

Test calculator governance inventory

• Checks approval requirements and the maintained pending source inventory.

tests/clinical-math-governance.test.ts

clinical-math-panel-breakpoint.dom.test.tsxAdapt panel layout tests to release hold +21/-18

Adapt panel layout tests to release hold

• Keeps layout coverage compatible with withheld production calculator content.

tests/clinical-math-panel-breakpoint.dom.test.tsx

cme-evidence-api.test.tsTest versioned durable CME removal +23/-5

Test versioned durable CME removal

• Covers the removal RPC and best-effort Storage cleanup after durable queueing.

tests/cme-evidence-api.test.ts

diagnostic-minimisation.test.tsTest content-free diagnostics +72/-0

Test content-free diagnostics

• Checks bounded error classification against synthetic sensitive messages and properties.

tests/diagnostic-minimisation.test.ts

drift-rootless.test.tsTest offline rootless replay safeguards +399/-0

Test offline rootless replay safeguards

• Covers image verification, path ownership, isolation, cleanup, evidence, and manifest-publication contracts.

tests/drift-rootless.test.ts

factsheets-summary-context.test.tsTest Factsheet retrieval context +34/-0

Test Factsheet retrieval context

• Asserts demonstration notice and content-month meaning survive the adapter projection.

tests/factsheets-summary-context.test.ts

favourites-session-race.dom.test.tsxTest favourites identity races +319/-0

Test favourites identity races

• Delays reads, mutations, failures, and rollbacks across account changes to verify stale work cannot update the next session.

tests/favourites-session-race.dom.test.tsx

static-manifest-baseline.jsonRefresh Factsheet manifest fixture +19/-19

Refresh Factsheet manifest fixture

• Records content and lineage changes caused by the amended Factsheet projection.

tests/fixtures/site-content/static-manifest-baseline.json

hosted-migration-role-guard.test.tsMatch shared replay call shape +1/-1

Match shared replay call shape

• Corrects a stale test expectation after the schema replay was extracted into a common helper.

tests/hosted-migration-role-guard.test.ts

ingestion-recovery.test.tsTest lease-fenced recovery plans +81/-1

Test lease-fenced recovery plans

• Covers current leases, expected snapshots, preserved artifacts, and shared RPC action execution.

tests/ingestion-recovery.test.ts

instrumentation.test.tsTest Node and Edge startup separation +77/-0

Test Node and Edge startup separation

• Checks runtime-specific import graphs and retained startup guards.

tests/instrumentation.test.ts

open-shifts-zone.test.tsTest selected-zone open-shift calculations +116/-0

Test selected-zone open-shift calculations

• Covers Sydney, Perth, fractional-zone, and daylight-saving boundaries.

tests/open-shifts-zone.test.ts

operational-alerts.test.tsTest documented alert contracts +18/-0

Test documented alert contracts

• Checks configured alert codes against the expanded SLO runbook.

tests/operational-alerts.test.ts

rag-answer-fallback.test.tsTest fallback under fresh revision rules +133/-39

Test fallback under fresh revision rules

• Updates answer-fallback fixtures and verifies cache restrictions remain effective.

tests/rag-answer-fallback.test.ts

rag-cache-governance-revocation.test.tsTest governance revocation across cache paths +505/-0

Test governance revocation across cache paths

• Exercises local and shared answer/search reuse, failed deletions, concurrent reviews, late writes, and fail-cold revisions.

tests/rag-cache-governance-revocation.test.ts

rag-cache-indexing-stamp.test.tsTest complete-scope revision stamps +38/-36

Test complete-scope revision stamps

• Replaces latest-indexed-document assumptions with fresh revision and unavailable-RPC cases.

tests/rag-cache-indexing-stamp.test.ts

rag-cache-invalidation.test.tsTest revision-aware invalidation +91/-86

Test revision-aware invalidation

• Adapts cache invalidation coverage to durable revision and local epoch fences.

tests/rag-cache-invalidation.test.ts

rag-cache-lru.test.tsTest local cache bounds with revisions +37/-35

Test local cache bounds with revisions

• Updates LRU fixtures for the fresh scope-revision contract.

tests/rag-cache-lru.test.ts

rag-cache-test-revision.tsShare RAG revision test fixtures +67/-0

Share RAG revision test fixtures

• Provides consistent synthetic scope-revision RPC responses to cache suites.

tests/rag-cache-test-revision.ts

rag-shared-cache.test.tsTest shared-cache freshness checks +103/-80

Test shared-cache freshness checks

• Covers revised shared cache hits, misses, and post-read revision validation.

tests/rag-shared-cache.test.ts

rag-site-content-freshness.test.tsTest site-content cache freshness +24/-19

Test site-content cache freshness

• Updates site-content caching fixtures and assertions for revised dependency keys.

tests/rag-site-content-freshness.test.ts

rag-tail-latency.test.tsTest revision-aware coalescing and latency +142/-64

Test revision-aware coalescing and latency

• Checks in-flight joining and stale-waiter fallback while accounting for fresh revision reads.

tests/rag-tail-latency.test.ts

railway-config.test.tsTest worker rebuild watch patterns +2/-0

Test worker rebuild watch patterns

• Asserts model artifact and verifier changes select the Railway worker build.

tests/railway-config.test.ts

retrieval-access-scope.test.tsTest scope-specific revision requests +82/-2

Test scope-specific revision requests

• Extends retrieval-access coverage for owner, public, and document-filtered revisions.

tests/retrieval-access-scope.test.ts

roster-auth-transition.dom.test.tsxTest mounted Roster account switches +257/-0

Test mounted Roster account switches

• Exercises settings, shifts, queues, and pending deletion across identities and same-account controls.

tests/roster-auth-transition.dom.test.tsx

roster-cover-tab.dom.test.tsxTest cover-gap timezone conversion +60/-2

Test cover-gap timezone conversion

• Covers selected-zone labels, posted instants, and invalid wall times.

tests/roster-cover-tab.dom.test.tsx

roster-month-page.dom.test.tsxTest partial calendar-source failures +30/-1

Test partial calendar-source failures

• Verifies source-specific warnings and retries preserve successfully loaded shifts.

tests/roster-month-page.dom.test.tsx

test-runner-safety.test.tsTest defunct lock-owner handling +175/-0

Test defunct lock-owner handling

• Checks zombie detection without reclaiming locks from live or uncertain owners.

tests/test-runner-safety.test.ts

ui-tools.spec.tsExercise calculator release hold in browser +32/-0

Exercise calculator release hold in browser

• Adds UI coverage for withheld physiological tools across supported layouts.

tests/ui-tools.spec.ts

upload-diagnostic-minimisation.test.tsTest upload cleanup logging privacy +198/-0

Test upload cleanup logging privacy

• Exercises upload failure and duplicate compensation with synthetic identifiers, inspecting diagnostic output.

tests/upload-diagnostic-minimisation.test.ts

work-calendar-entries-enabled.dom.test.tsxTest targeted calendar-source retry +15/-2

Test targeted calendar-source retry

• Verifies the hook retries a selected failed source independently.

tests/work-calendar-entries-enabled.dom.test.tsx

work-roles-hospital-sick-release.test.tsTest sick-report release gate +102/-0

Test sick-report release gate

• Asserts held requests never create readers and enabled requests retain authorization requirements.

tests/work-roles-hospital-sick-release.test.ts

work-roles-hospital-sick.test.tsExtend hospital sick-report controls +17/-0

Extend hospital sick-report controls

• Adds coverage for the held versus enabled endpoint behaviour.

tests/work-roles-hospital-sick.test.ts

work-roles-people-changes.test.tsTest atomic team moves +46/-5

Test atomic team moves

• Updates move and error-path assertions for transactional supervisor revocation.

tests/work-roles-people-changes.test.ts

worker-python-lock.test.tsTest optional cloud Python lock selection +22/-0

Test optional cloud Python lock selection

• Validates the separate cloud input and lock configuration without replacing the production lock.

tests/worker-python-lock.test.ts

Documentation (17) +1417 / -47
repo-awareness-snapshot.jsonRefresh repository awareness snapshot +30/-0

Refresh repository awareness snapshot

• Records the newly added remediation documents and repository areas in the awareness snapshot.

data/repo-awareness-snapshot.json

README.mdLink audit remediation records +9/-0

Link audit remediation records

• Adds entry points to the remediation and related governance documentation.

docs/README.md

codex-cloud-legacy-bootstrap.mdDocument optional cloud Python bootstrap +24/-0

Document optional cloud Python bootstrap

• Explains the separate Python 3.12 cloud lock and its relationship to the production worker lock.

docs/agents/codex-cloud-legacy-bootstrap.md

2026-10-17-full-deep-remediation-results.mdRecord remediation results and acceptance limits +473/-0

Record remediation results and acceptance limits

• Tracks each audit finding, local verification, failed attempts, staging-only grant repair, rollout sequence, and outstanding external approvals. Explicitly distinguishes local evidence from hosted and production acceptance.

docs/audit/2026-10-17-full-deep-remediation-results.md

2026-10-17-full-deep-remediation-spec.mdSpecify audit findings and required outcomes +181/-0

Specify audit findings and required outcomes

• Defines findings F01–F16, additional leads, reproduction boundaries, and acceptance criteria without treating engineering work as clinical or legal approval.

docs/audit/2026-10-17-full-deep-remediation-spec.md

database-drift-detection.mdDocument isolated rootless catalog replay +40/-0

Document isolated rootless catalog replay

• Describes the optional offline replay backend and its controls while retaining Docker as the default.

docs/database-drift-detection.md

error-tracking.mdClarify minimized diagnostic handling +7/-1

Clarify minimized diagnostic handling

• Updates guidance for content-free upload and worker error diagnostics.

docs/error-tracking.md

clinical-release-remediation-handoff-2026-10-17.mdCarry forward clinical and privacy release blockers +66/-0

Carry forward clinical and privacy release blockers

• Lists outstanding provider, privacy, and accountable review evidence required before covered production activation.

docs/governance/clinical-release-remediation-handoff-2026-10-17.md

physiological-calculator-hold-2026-10-17.mdDocument physiological calculator release hold +33/-0

Document physiological calculator release hold

• Inventories withheld renal, QTc, and lithium tools and specifies the clinical validation needed to release them.

docs/governance/physiological-calculator-hold-2026-10-17.md

observability-slos.mdAlign SLO runbook with configured alerts +105/-45

Align SLO runbook with configured alerts

• Documents implemented alert codes, thresholds, windows, operator responses, and the difference between configured detection and observed delivery.

docs/observability-slos.md

data-platform.jsonRegister data-platform remediation references +3/-0

Register data-platform remediation references

• Adds audit and recovery documentation to the data-platform system record.

docs/organisation/systems/data-platform.json

personal-practice.jsonRegister personal-practice remediation reference +1/-0

Register personal-practice remediation reference

• Connects the system record to the relevant audit handoff.

docs/organisation/systems/personal-practice.json

README.mdLink RAG cache freshness contract +1/-0

Link RAG cache freshness contract

• Adds the new cache-governance document to the RAG behaviour index.

docs/rag-behaviour/README.md

cache-freshness.mdSpecify revision-fenced RAG caching +82/-0

Specify revision-fenced RAG caching

• Explains fresh scope revisions, read and write fences, coalescing, fail-cold behaviour, rollout compatibility, and unmeasured performance costs.

docs/rag-behaviour/cache-freshness.md

rag-injection-threat-model.mdUpdate RAG threat-model reference +1/-1

Update RAG threat-model reference

• Adjusts the threat model to reference the changed cache-governance behaviour.

docs/rag-injection-threat-model.md

reindex-runbook.mdDocument lease-safe ingestion recovery +52/-0

Document lease-safe ingestion recovery

• Replaces obsolete destructive recovery guidance with the atomic recovery contract and rollout precautions.

docs/reindex-runbook.md

2026-10-17-full-deep-remediation.mdRecord cross-area remediation plan +309/-0

Record cross-area remediation plan

• Sets out implementation lanes, safety boundaries, verification, and handoff steps for the audit findings.

docs/superpowers/plans/2026-10-17-full-deep-remediation.md

Other (11) +948 / -86
railway.worker.jsonExpand worker rebuild watch inputs +2/-0

Expand worker rebuild watch inputs

• Includes copied model artifact and verification inputs so changes to them select a worker rebuild.

railway.worker.json

check-worker-python-lock.mjsCheck cloud lock against its separate input +3/-3

Check cloud lock against its separate input

• Aligns optional Python 3.12 lock checking with its cloud-specific dependency input.

scripts/check-worker-python-lock.mjs

generate-worker-python-lock.mjsGenerate cloud lock from cloud input +3/-3

Generate cloud lock from cloud input

• Uses the optional cloud dependency input when generating its Python lock.

scripts/generate-worker-python-lock.mjs

worker-python-lock-config.mjsDeclare optional cloud-lock input +2/-0

Declare optional cloud-lock input

• Separates the cloud Python dependency input from the canonical production input.

scripts/worker-python-lock-config.mjs

governance.jsonRecord pending calculator clinical governance +95/-0

Record pending calculator clinical governance

• Defines the physiological tool inventory and unapproved review state used by the release hold.

src/lib/calculators/clinical-math/governance.json

database.types.tsType new database recovery and revision contracts +65/-3

Type new database recovery and revision contracts

• Adds generated-facing types for migration columns and RPCs used by application code.

src/lib/supabase/database.types.ts

applied-migration-hashes.jsonAppend the new migration seal +3/-2

Append the new migration seal

• Seals the new migration without changing prior migration hashes.

supabase/applied-migration-hashes.json

drift-manifest.jsonCapture the updated full schema catalog +82/-5

Capture the updated full schema catalog

• Updates schema hash and expected catalog from isolated replay rather than a hash-only edit.

supabase/drift-manifest.json

schema.sqlMirror audit-remediation database schema +572/-0

Mirror audit-remediation database schema

• Adds the migration’s functions, triggers, grants, and cleanup column to the maintained full-schema replay source.

supabase/schema.sql

requirements-cloud.inConstrain optional Python 3.12 Cython resolution +6/-0

Constrain optional Python 3.12 Cython resolution

• Adds a cloud-specific input compatible with quicksectx while retaining the canonical production input.

worker/python/requirements-cloud.in

requirements-cloud.txtRegenerate optional cloud Python dependency lock +115/-70

Regenerate optional cloud Python dependency lock

• Updates the hash-pinned Python 3.12 dependency closure for the compatible Cython and Thinc resolution.

worker/python/requirements-cloud.txt

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Auto-fix isn't included in your plan ↗

Upgrade to Team

@qodo-code-review

qodo-code-review Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Cached answers survive evidence edits 🔴 High 🐞 Bug ≡ Correctness
Description
rag_cache_scope_revision_v1 hashes table-fact and image metadata but omits evidence fields
including fact thresholds and actions, and image captions and relevance scores. When those fields
change without a parent-document or hashed-field change, the cache revision still matches and an
earlier answer or search result can be reused.
Code

supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[R136-139]

+      (select pg_catalog.jsonb_agg(pg_catalog.jsonb_build_array(f.id,f.metadata) order by f.id)
+       from public.document_table_facts f where f.document_id = d.id),
+      (select pg_catalog.jsonb_agg(pg_catalog.jsonb_build_array(i.id,i.metadata,i.searchable) order by i.id)
+       from public.document_images i where i.document_id = d.id)
Relevance

●●● Strong

Recent RAG precedents accept cache and retrieval freshness corrections when evidence changes can
alter results.

PR-#2628
PR-#3596

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The newly added child-row hashes include only IDs, metadata, and image searchability. Fact retrieval
uses the omitted fact fields; image hydration selects captions and ranks by relevance. The cache
uses the RPC digest as its indexing version.

supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[130-145]
src/lib/rag/rag-candidate-sources.ts[1764-1828]
src/lib/rag/rag-hydration.ts[354-400]
src/lib/rag/rag-cache.ts[1180-1201]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The cache scope revision does not change for edits to several fields used to retrieve or present table facts and images.
## Fix Focus Areas
- supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[134-140]
- src/lib/rag/rag-candidate-sources.ts[1764-1828]
- src/lib/rag/rag-hydration.ts[354-400]
## Recommended Fix
Include all mutable evidence-bearing fact and image columns in a deterministic revision hash, or use an atomically maintained evidence revision that changes whenever those fields change. Add cache-reuse tests for edits to previously omitted fields.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗



Remediation recommended

No findings for this group


Informational

No findings for this group

Grey Divider


Resolved findings

1. Documents with two stale workers never recover ✓ Resolved
Description
applyIngestionRecoveryActions now skips every sibling supersede for a document that has a planned
retry and relies on the retry RPC to close those siblings. But recover_ingestion_job's retry
branch first returns state_changed whenever any sibling is still pending or processing (lease
state does not matter), so its in-transaction sibling update for processing rows can never run.
The planner prefers a stale processing job as the retry and lists any other stale processing job
as a supersede. When a document has two expired-lease processing jobs, every recovery run is now
rejected and nothing gets requeued. The old flow committed the sibling supersede first, so the retry
then went through.
Code

src/lib/ingestion-recovery.ts[R234-236]

+  const retryDocuments = new Set(
+    applicable.filter(({ action }) => action.action === "retry").map(({ action }) => action.documentId),
+  );
Relevance

●●● Strong

Recent ingestion recovery precedent accepts stale-worker race fixes and atomic recovery corrections.

PR-#3596

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The planner (lines 105-112) picks a processing job as retryJob and emits supersede actions for
the other recoverable jobs, including stale processing ones. The apply loop (lines 234-236) drops
those supersedes because the document has a retry. In the SQL retry branch (lines 90-92), any other
job with status in ('pending','processing') causes a state_changed return before the
sibling-closing UPDATE at lines 99-103. That UPDATE's status in ('failed','processing') filter can
therefore only ever match failed rows. The sibling is never closed, so re-running the same plan
fails the same way every time.

src/lib/ingestion-recovery.ts[105-112]
src/lib/ingestion-recovery.ts[230-244]
supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[89-104]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The retry RPC rejects whenever any sibling job is `pending` or `processing`, even when that sibling's lease has expired. The app no longer sends separate supersedes for retry documents, so a document with two stale processing jobs can never be recovered.

## Fix Focus Areas
- supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[89-103]
- src/lib/ingestion-recovery.ts[230-244]

## Recommended Fix
In the retry branch, change the extra `exists(... status in ('pending','processing'))` guard so it rejects only `pending` siblings and `processing` siblings with a live lease (`lease_expires_at > v_now`). `v_active` already covers live leases. Stale processing siblings then get closed by the in-transaction UPDATE. Add a SQL/unit test with two expired-lease processing jobs on one document.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Recovery can strand failed documents ✓ Resolved
Description
applyIngestionRecoveryActions commits each sibling supersede through a separate RPC before
attempting the planned retry. If that retry returns managed_recovery_required because generation
evidence exists, the supersedes remain committed while no job is requeued, and repeating this
recovery plan cannot clear that rejection.
Code

src/lib/ingestion-recovery.ts[R235-238]

+  const results: Array<{ action: IngestionRecoveryAction; applied: boolean; reason: string | null }> = [];
+  for (const { action, expected } of applicable) {
+    const { data, error } = await client.rpc("recover_ingestion_job", {
+      p_job_id: action.jobId,
Relevance

●●● Strong

The team accepts fixes for independently committed recovery steps that can leave durable state
partially applied.

PR-#2974
PR-#3596

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The ingestion skill calls for partial-failure safety, and the recovery skill calls for idempotent
recovery steps. The new loop makes independently committed RPC calls, while the new RPC can reject a
retry after earlier supersede calls succeeded.

src/lib/ingestion-recovery.ts[105-121]
src/lib/ingestion-recovery.ts[235-250]
supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[89-115]
Skill: ingest
Skill: recovery

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Separate recovery transactions can commit sibling supersedes even when the retry is subsequently rejected, leaving a document without a runnable job.
## Fix Focus Areas
- src/lib/ingestion-recovery.ts[220-251]
- supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[83-115]
- tests/ingestion-recovery.test.ts[344-384]
## Recommended Fix
Validate all retry preconditions before changing siblings and apply a document's supersedes and retry in one database transaction. Test the generation-evidence rejection with multiple recoverable sibling jobs and verify that no sibling is superseded.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Revoked evidence survives cache reuse ✓ Resolved
Description
rag_cache_scope_revision_v1 hashes documents rows but not the table-fact or image-review
metadata that can change answer evidence. When a review changes on another application replica
without updating its parent document, the revision remains unchanged and a cached answer can be
reused after that evidence changes.
Code

supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[R127-130]

+    select d.id, pg_catalog.md5(pg_catalog.jsonb_build_array(d.id,d.owner_id,d.status,d.updated_at,d.metadata,d.index_generation_id)::text) as row_hash
+    from public.documents d
+    where (d.owner_id = p_owner_id or (coalesce(p_include_public,false) and d.owner_id is null))
+      and (coalesce(cardinality(p_document_ids),0) = 0 or d.id = any(p_document_ids))
Relevance

●●● Strong

RAG governance precedents accept filtering stale evidence and treating retrieval freshness changes
as behavioral correctness issues.

PR-#3596
PR-#2628

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The RAG skill requires conservative fallback and preservation of source governance. The new revision
covers documents alone, while the review route updates separate evidence tables and only invalidates
caches in its own process; shared-answer reuse depends on that revision.

supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[123-131]
src/app/api/documents/[id]/table-facts/route.ts[163-194]
src/lib/rag/rag-cache.ts[1345-1365]
Skill: rag

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The durable RAG cache revision does not change when table-fact or image reviews change on another replica, permitting stale answer reuse.
## Fix Focus Areas
- supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql[123-135]
- src/app/api/documents/[id]/table-facts/route.ts[163-194]
- tests/rag-cache-governance-revocation.test.ts[1-505]
## Recommended Fix
Make review changes advance a durable revision for the affected retrieval scope, or include their committed metadata in the revision calculation. Add a cross-replica regression test that changes a review and rejects the formerly cached answer.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View resolved (5)
4. Admission cleanup tests now fail ✓ Resolved
Description
releaseSupersededDocumentObject now returns structured failure objects, but its existing
unrecorded-cleanup test still asserts the removed string format. Both assertions fail when removal
and ledger insertion fail, leaving the owning test suite red.
Code

src/lib/trusted-document-admission.ts[R389-391]

+    failures.push({ stage: "remove", code: releaseFailureCode(error) });
  } catch (error) {
-    failures.push(releaseFailureMessage("remove", error));
+    failures.push({ stage: "remove", code: releaseFailureCode(error) });
Relevance

●●● Strong

Recent admission precedent accepts propagating structured, sanitized cleanup failure diagnostics.

PR-#3580

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The implementation pushes { stage, code } objects for both failed operations, while the existing
test compares the resulting array with strings.

src/lib/trusted-document-admission.ts[385-400]
tests/trusted-document-admission.test.ts[567-580]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The cleanup result changed from strings to structured failure classifications, but its existing test still expects strings.
## Fix Focus Areas
- src/lib/trusted-document-admission.ts[385-398]
- tests/trusted-document-admission.test.ts[567-580]
## Recommended Fix
Update both assertions to check the expected stage and safe code for each failure, preserving coverage of returned errors and thrown exceptions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Wrapped worker failures lose their code ✓ Resolved
Description
runWorkerMain derives the webhook's failure code from the outer WorkerAbortError, while
contentFreeErrorDetails does not inspect its cause. In one-shot mode, claim failures with an
allowlisted database or network code are wrapped before reaching this handler, so their alerts say
errorCode=unclassified.
Code

worker/main.ts[R2502-2503]

+    const failureDetails = contentFreeErrorDetails(error);
+    const failureCode = failureDetails.errorCode ?? "unclassified";
Relevance

●●● Strong

Worker observability precedents accept preserving failure details through asynchronous and wrapped
execution paths.

PR-#2170
PR-#3628

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The run loop wraps one-shot claim errors as the cause of a WorkerAbortError; the classifier reads
only the supplied error's top-level code, and the webhook prints that classifier result.

worker/run-loop.ts[78-88]
src/lib/privacy.ts[77-115]
worker/main.ts[2501-2510]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
One-shot worker failures retain their underlying error only as a cause, so the new fatal alert classification loses its allowlisted error code.
## Fix Focus Areas
- worker/main.ts[2502-2510]
- worker/run-loop.ts[78-88]
- src/lib/privacy.ts[77-115]
## Recommended Fix
For a wrapped worker abort, classify the underlying cause through the existing fixed allowlists while keeping free-text messages out of the alert. Test a wrapped claim failure with an allowlisted code.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Orphaned uploads lose cleanup diagnostics ✓ Resolved
Description
releaseSupersededUpload replaces the cleanup failure details with failureCount, so its
manual-reconciliation log no longer identifies the failed stages or their error classifications.
When storage removal and cleanup-ledger insertion both fail, there is no durable cleanup row, and
the alert does not tell responders what failed while trying to recover the object.
Code

src/app/api/upload/route.ts[R213-214]

+      storageObjectRef: createHash("sha256").update(supersededPath).digest("hex"),
+      failureCount: release.failures.length,
Relevance

●●● Strong

PR #3580 accepted propagating sanitized removal and ledger failure causes into manual-reconciliation
alerts.

PR-#3580

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The release helper records separate remove and queue failures, but the changed log discards them
precisely when neither operation succeeded. A prior accepted fix in this same path added failure
causes to the manual-reconciliation record.

src/lib/trusted-document-admission.ts[376-394]
src/app/api/upload/route.ts[196-216]
PR-#3580

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The unrecorded superseded-upload cleanup alert retains only a count of failures, even though both storage removal and ledger insertion can fail.
## Fix Focus Areas
- src/app/api/upload/route.ts[204-216]
- src/lib/trusted-document-admission.ts[364-396]
## Recommended Fix
Return structured, privacy-safe failure stages and allowlisted error classifications from the release helper. Include those fields with the opaque object reference in the manual-reconciliation log; do not restore provider messages or storage paths.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Worker alerts point to absent tracking ✓ Resolved
Description
runWorkerMain replaces the fatal webhook's error details with an instruction to consult
privacy-filtered error tracking. When SENTRY_DSN is absent or tracking initialization fails,
captureWorkerException records nothing, so the webhook contains no failure classification or
location and directs responders to a nonexistent event, although local process logs retain a type
and code.
Code

worker/main.ts[2485]

+            text: `CRITICAL: PsychSift worker ${abort ? "aborted" : "stopped unexpectedly"}. See privacy-filtered error tracking for diagnostics.`,
Relevance

●●● Strong

Recent observability fixes preserve sanitized failure causes when fallback tracking or durable
cleanup paths fail.

PR-#3580
PR-#3148

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed webhook sends only generic text. Worker tracking is optional and its capture function
returns without recording an event when it was not initialized; the console call retains limited
classifications but does not put them in the webhook.

worker/main.ts[2473-2486]
worker/observability.ts[23-36]
worker/observability.ts[63-75]
src/lib/privacy.ts[77-124]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Fatal worker webhooks refer responders to error tracking even when tracking is unavailable and provide no diagnostic classification of their own.
## Fix Focus Areas
- worker/main.ts[2473-2491]
- worker/observability.ts[23-36]
## Recommended Fix
Include an allowlisted, content-free error type and code in fatal webhook messages, and avoid asserting that a tracking event exists unless tracking is active. Keep free-text error messages and document identifiers out of the webhook.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. The new test keeps a namespace type ✓ Resolved
Description
The new test wrapper types children as React.ReactNode instead of importing ReactNode as a
type. Later readers and edits must follow a namespace-qualified pattern where this TSX file should
use an explicit type import.
Code

tests/favourites-session-race.dom.test.tsx[115]

+const wrapper = ({ children }: { children: React.ReactNode }) => <AccountDataProvider>{children}</AccountDataProvider>;
Relevance

●●● Strong

This is a deterministic style-rule fix: replace the namespace-qualified React type with an explicit
type import.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed TSX test introduces React.ReactNode on line 115, while the checklist requires specific
React type imports and direct type usage.

Rule 3891512: Prefer explicit type imports over React namespace types in TSX
tests/favourites-session-race.dom.test.tsx[115-115]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new TSX test uses the namespace-qualified type `React.ReactNode` instead of an explicit type-only import, contrary to the project convention.

## Fix Focus Areas
- tests/favourites-session-race.dom.test.tsx[3-5]
- tests/favourites-session-race.dom.test.tsx[115-115]

## Recommended Fix
Add `import type { ReactNode } from "react"` and change the wrapper prop type from `React.ReactNode` to `ReactNode`. Do not add a runtime React import solely for this type.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 9 rules
✅ Cross-repo context — repo relationships
  Explored: repo: BigSimmo/Medications (sha: 93e6ccc7) — View relationship
✅ REVIEW.md
Review mode: Auto: ⚖️ Balanced: Comparison failure: full PR diff.

Grey Divider

Tip of the day
💡 Did you know, you can move or hide resolved findings to focus on what still needs action

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/app/api/upload/route.ts Resolved
Comment thread worker/main.ts Resolved
Comment thread src/lib/ingestion-recovery.ts Resolved
@codeant-ai

codeant-ai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: f70929e5
Scan Time: 2026-10-18 09:51:48 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 0.4% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED Rating S: No issues

View Full Results

@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo Fixer

✅ Committed (5) · ☑ Fixed (5)

Grey Divider

Commits pushed directly to this PR — no separate fix PR opened.

Process — 5 fixed
  • ☑ Fixed: Recovery can strand failed documents
  • ☑ Fixed: Revoked evidence survives cache reuse
  • ☑ Fixed: Orphaned uploads lose cleanup diagnostics
  • ☑ Fixed: Worker alerts point to absent tracking
  • ☑ Fixed: The new test keeps a namespace type

@gitar-bot
gitar-bot Bot enabled auto-merge (squash) October 18, 2026 08:11
gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 18, 2026

@gitar-bot gitar-bot Bot 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.

Gitar has auto-approved this PR (configure)

# Conflicts:
#	supabase/applied-migration-hashes.json
#	supabase/drift-manifest.json
#	supabase/schema.sql
…a.sql

The snapshot is the clean three-way merge of this branch's and main's manifests;
schema_sha256 is recomputed with the repo's normalizedSchemaSha256. CI's
'Regenerate and verify drift manifest freshness' step verifies the full manifest
(Docker is unavailable on this box); its artifact replaces this if it differs.
Reverts a62fc95. That automated commit edited
the already-sealed draft migration after review: it changed
rag_cache_scope_revision_v1 and added a duplicate-job close-out to
recover_ingestion_job. The owner approved resealing only the reviewed bytes
(f0667fed9f0294c1f5ba40252d11ee66e6de07be340a1ec789e0503a1192f2ac); approval
relayed by Grok Bot at 16:17 AWST 2026-10-18, option (b) confirmed at 16:33 AWST.
The matching src/lib/ingestion-recovery.ts change skipped sibling supersedes on
the assumption that the new SQL performs them, so it is reverted too. The
retry close-out can come back as a separate reviewed PR.
gitar-bot[bot]

This comment was marked as resolved.

Comment thread supabase/applied-migration-hashes.json Resolved
… alert

In --once mode the run loop wraps claim and health failures in WorkerAbortError, so the
outer error carries no code and the failure webhook always said errorCode=unclassified.
Read the allowlisted code from the wrapped cause as well. contentFreeErrorDetails only ever
returns a fixed class or known code, so no message content reaches the alert. Add a test that
the code is reported and the private text is not.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V2VWJXoHMnr3XnAhrREN8V
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 3e8d2e9

@BigSimmo

Copy link
Copy Markdown
Owner Author

Splitting the work with the active Claude session (e49f10fa0d, 3e8d2e94dc) so we don't overlap:

  • Grok Bot (me): only the owner-approved database steps. I'll rename the draft migration to 20261018082910_audit_durable_recovery_pairing_and_cache_fences.sql with the same bytes (f0667fed…), reseal it via npm run migrations:reseal citing the owner approval (16:17 AWST, option (b) at 16:33 AWST), update the schema.sql projection header, the runbook reference and the drift-manifest schema_sha256, and re-merge main if it moves. I'm dropping my own trusted-document-admission test fix in favour of your e49f10fa0d.
  • Claude: the app, worker and test fixes (e.g. the worker alert code and the upload test). Please don't touch supabase/migrations/**, supabase/applied-migration-hashes.json, supabase/schema.sql or supabase/drift-manifest.json, and don't change rag_cache_scope_revision_v1.

I'll push once this branch has been quiet for 15 minutes, after fetching and integrating your commits; I won't force-push. Auto-merge stays off, because the owner chooses the production database window.

Renames 20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql to
20261018082910_audit_durable_recovery_pairing_and_cache_fences.sql so it sorts
after main's newest migration (20261018062736). The bytes are unchanged:
normalized SHA-256 f0667fed9f0294c1f5ba40252d11ee66e6de07be340a1ec789e0503a1192f2ac.

Resealed with `npm run migrations:reseal`, with
MIGRATION_RESEAL_OWNER_APPROVAL="the owner, relayed by Grok Bot in chat at 16:17 AWST
2026-10-18 (rename and reseal the reviewed migration f0667fed; option (b) confirmed at
16:33 AWST 2026-10-18)". The only manifest change is that the old name is removed and
the new name added with the same hash.

The schema.sql projection header and the runbook reference now use the new name,
and the projection matches the migration byte for byte. The drift manifest's
schema_sha256 follows schema.sql; CI's freshness step verifies the full manifest.
No SQL was applied. No clinical sign-off is recorded.
@BigSimmo

Copy link
Copy Markdown
Owner Author

Update to the split with the Claude session: I'm taking on only the migration rename and reseal, the drift manifest, and the failing PR policy check. That check fails on 20261017221129_…, which is dated before main's newest 20261018062736, and the rename to 20261018082910_… fixes it. The bytes are unchanged at f0667fed…, and the reseal cites the owner approval from 16:17 AWST, with option (b) confirmed at 16:33 AWST.

My files are limited to supabase/migrations/**, supabase/applied-migration-hashes.json, supabase/schema.sql (projection header only), supabase/drift-manifest.json (schema_sha256 only), docs/reindex-runbook.md and a dated note in docs/audit/2026-10-17-full-deep-remediation-results.md. The worker and upload fixes (worker/**, src/**, tests/**) stay with Claude. I'm pushing on top of 3e8d2e94dc without force; auto-merge stays off.

@gitar-bot
gitar-bot Bot enabled auto-merge (squash) October 18, 2026 09:31
gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 18, 2026

@gitar-bot gitar-bot Bot 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.

Gitar has auto-approved this PR (configure)

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit f70929e

gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 18, 2026

@gitar-bot gitar-bot Bot 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.

Gitar has auto-approved this PR (configure)

@BigSimmo
BigSimmo disabled auto-merge October 18, 2026 10:10
BigSimmo added a commit that referenced this pull request Oct 18, 2026
Adds draft migration 20261018095804_rag_cache_scope_evidence_revision.sql.
It is stacked on #3640 and must merge after it, because it replaces #3640's
rag_cache_scope_revision_v1.

- public.document_evidence_revisions holds a per-document counter. Statement-level
  triggers on document_table_facts and document_images bump it in the writing
  transaction when a fact or image row is inserted, deleted or changed. Every
  column except created_at/search_tsv counts; a no-op update does not bump it.
- rag_cache_scope_revision_v1 keeps its signature, digest shape and grants, and
  each document's row hash now also carries that counter. The revision stays one
  pass over documents plus a keyed join, with no per-request scan of facts or
  images (gitar's cost concern).
- tests/sql/rag-cache-scope-evidence-revision.sql runs on the replayed chain in
  CI. It shows that a fact threshold edit and image caption, relevance and
  searchability edits change the revision, that a no-op update and an edit on
  another document do not, and that deleting the document still cascades.
- tests/rag-cache-governance-revocation.test.ts shows that a counter bump
  rejects local and shared cached answers and searches.

Sealed with the append-only `npm run migrations:seal`. The owner approved this
migration at 17:55 AWST 2026-10-18, relayed by Grok Bot. The drift manifest's
schema_sha256 follows schema.sql; the full manifest comes from CI's
regenerated artifact. No SQL applied; no clinical or hazard sign-off recorded.
@BigSimmo

Copy link
Copy Markdown
Owner Author

Supabase Preview note: the owner approved marking 20261017221129 as reverted on this PR's preview branch only (17:55 AWST 2026-10-18, relayed by Grok Bot). I identified the branch: enkvvwbeyhkbzavburcq (pr 3640, parent production sjrfecxgysukkwxsowpy, status MIGRATIONS_FAILED). I did not run the repair. Read-only checks show the old version's objects already exist on the preview, so after a revert the integration would re-apply 20261018082910, and its non-idempotent add column / create function statements would fail. Options for the owner: (a) reset the preview branch so it rebuilds from the migrations, or (b) revert plus mark 20261018082910 applied (falls under the guard-migration contract). Neither is covered by the current approval. Production is untouched. Auto-merge stays off. RAG cache follow-up: #3650 (stacked).

@gitar-bot gitar-bot Bot 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.

Gitar has auto-approved this PR (configure)

@gitar-bot

gitar-bot Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor
Code Review ✅ Approved 2 closed / 2 findings

🔴 High risk · The migration and account-authority/RAG changes could mis-scope staff access, strand private evidence, or serve stale clinical answers.

Remediates full-deep audit findings across account isolation, CME cleanup, ingestion recovery, and RAG cache fencing, with content-free upload and worker diagnostics. Resolved: the new migration's date ordering relative to migrations already on main has been corrected. No open findings remain; the scope-revision RPC corpus-hashing concern was closed without a fix in this PR.

✅ 2 closed
✅ Bug: New migration is dated before migrations already on main (out-of-order)

📄 supabase/applied-migration-hashes.json:325-327 📄 supabase/schema.sql:34925-34927
After the merge from main, 20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql sorts before 20261018053558_recheck_ingestion_claim_scope_after_job_lock.sql and 20261018062736_recheck_legacy_ingestion_claim_document_after_job_lock.sql. Both of those are already on main and sealed in supabase/applied-migration-hashes.json (lines 325-326). The new entry is even appended after them at line 327, so the seal file's order doesn't match version order.

This causes three problems:

  • scripts/pr-policy.mjs raises an out-of-order violation for this case ("Rename it with a version newer than <newestBase>") and blocks the PR.
  • The live deploy path (supabase db push / the GitHub integration) treats a version older than the newest applied one as out-of-order history. It either refuses to apply it or needs --include-all, so on merge the cache-fence/recovery RPCs the app now calls (rag_cache_scope_revision_v1, recover_ingestion_job, cme_remove_evidence_v2, work_move_team_v1) may never reach production.
  • Local replay runs this file before the two later claim-scope migrations, but schema.sql projects it after them, so the order validated in CI differs from the projection.

Fix: rename the migration to a version newer than 20261018062736 and re-seal its hash entry under the new name. Per the repo rules, resealing needs the owner's explicit permission. Then regenerate the drift manifest.

Closed: Performance: Scope-revision RPC hashes whole corpus several times per RAG request

📄 src/lib/rag/rag-cache.ts:403-409 📄 src/lib/rag/rag-cache.ts:674-676 📄 src/lib/rag/rag-cache.ts:989-990 📄 src/lib/rag/rag-cache.ts:1173-1187 📄 src/lib/rag/rag-cache.ts:1215-1216 📄 src/lib/rag/rag-cache.ts:1239 📄 supabase/migrations/20261017221129_audit_durable_recovery_pairing_and_cache_fences.sql
This PR removes the 5 s TTL memo from cacheIndexingVersion and replaces the one-row limit(1) stamp with rag_cache_scope_revision_v1. That RPC md5-hashes jsonb_build_array(id, owner_id, status, updated_at, metadata, index_generation_id) for every document in scope. resolveRetrievalAccessScope always sets includePublic: true, so each call scans the whole public corpus plus the owner's documents and serialises every row's full metadata jsonb.

It now runs uncached at every cache touchpoint:

  • answerInflightCacheKey (again after each coalesced wait)
  • getCachedAnswer and getCachedSearch
  • getSharedCachedSearch and getSharedCachedAnswer, twice each (before and after the row read)
  • each setCached* write
  • request start in rag.ts

That is roughly 6–10 O(corpus) round trips per question, including on the shared-cache hit path that the latency audit (L1-1) set out to keep fast. The hash also covers non-indexed rows and updated_at, and the documents_updated_at trigger bumps that on every update. So any ingestion or enrichment write to a public document changes the revision for every user. Because setCached* and get* drop entries when the revision differs from the one taken at request start, cache writes and reads will mostly miss while ingestion is active.

Suggested fix: keep a single revision per request, captured once in cacheContext and reused. Back it with a cheap value rather than a full-scan digest, for example a per-scope revision counter or a max(updated_at)/count read from an index that a trigger keeps current. Consider limiting the digest to retrieval-relevant states (indexed rows and governance fields), not every metadata change.

Verification

Rules No rules evaluated

Functional validation Not enabled

Set up

Auto-approval Approved

For more verification details, comment gitar display:verbose.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing compact verification results.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Important

Your trial ends in 3 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.

Was this helpful? React with 👍 / 👎 | Gitar

Copy link
Copy Markdown
Owner Author

Superseded by #3653: a clean one-commit rebuild with identical final code (head 83a49c5fa merged with current main). The owner chose this because qodo-code-review[bot] commits in this PR's history fail the bot-authored-sensitive-commits PR policy, and history rewrites are banned. The branch is kept because #3650 is stacked on it.


Generated by Claude Code

@BigSimmo BigSimmo closed this Oct 18, 2026
BigSimmo pushed a commit that referenced this pull request Oct 18, 2026
#3650 merged into the old #3640 branch after this rebuild was cut. This
applies exactly that branch's new changes, so the tree now equals the old
branch merged with main. Includes migration 20261018095804 and its seal
entry, which the owner approved by name.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UBtJDgQZJ3eBsxLWte9r4
gitar-bot Bot added a commit that referenced this pull request Oct 18, 2026
fix: remediate full-deep audit findings and retain release holds (rebuild of #3640)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants