Skip to content

audit fixes (P20): refresh the generated database types and drop the casts that hid the gap - #2629

Merged
BigSimmo merged 6 commits into
mainfrom
claude/audit-fix-p20
Sep 5, 2026
Merged

audit fixes (P20): refresh the generated database types and drop the casts that hid the gap#2629
BigSimmo merged 6 commits into
mainfrom
claude/audit-fix-p20

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Summary

Audit remediation package P20 — Data, generated types and dependencies, from docs/audit/full-repository-audit-2026-09-02.md (PR #2573). One finding fixed, three deliberately deferred with reasons.

  • b855d64 supabase: refresh the generated database types and drop the missing-type casts (L118)

L118src/lib/supabase/database.types.ts was stale, and several call sites carried as escapes written purely to work around the gap. Those escapes are the real defect: they turn a schema mismatch into silence.

Five tables added (with their supabase/schema.sql line): api_rate_limit_subjects (:988), document_title_words (:5111), indexing_v3_agent_jobs (:5701), document_corpus_access_state (:9650), document_corpus_access_snapshots (:9659). The three with a documents(id) foreign key carry the same two-entry Relationships shape the neighbouring generated tables use.

Nine callable RPCs added: backfill_legacy_index_health_batch, match_document_chunks_text_scoped, match_document_index_units_hybrid_scoped, migration_history_versions, purge_expired_rag_query_misses, retrieval_owner_matches, schema_drift_snapshot, set_document_corpus_access_mode, update_indexing_v3_agent_job_status.

The audit said fifteen RPCs; the real name-level gap is twenty, and nine were added. That discrepancy is deliberate and worth recording. Eleven of the twenty return trigger (set_updated_at, set_owner_id_from_auth_uid, sync_document_title_words, enforce_document_title_word_scope, cleanup_registry_corpus_document, guard_document_publication_transition, notify_document_change_ingestion_webhook, prevent_document_publication_approval_mutation, prevent_source_review_event_mutation, require_document_publication_approval_state_digest, set_document_embedding_field_content_hash). The committed file carries zero trigger functions today, and they are not callable as RPCs, so emitting them would have broken the file's own convention. The count could not be reconciled to exactly fifteen, and the file was not padded to make it match.

Casts removed, each proven by a clean typecheck:

  • src/lib/ingestion-mutation-safety.ts — both args.supabase as unknown as SupabaseClient escapes (lines 186 and 257) and the comment claiming the table "is not in the generated Database types", plus the two now-redundant row casts, the local alias they needed, and the unused import.
  • scripts/check-drift.ts:537supabase.rpc("schema_drift_snapshot" as never)supabase.rpc("schema_drift_snapshot").

Casts deliberately left: scripts/archive/check-july8-live-batch.ts:90,308scripts/archive/** is excluded from tsconfig.typecheck.json, so removing them could not be proven here. scripts/reindex-image-generation-metadata.ts:60from(table as never) is load-bearing for a genuinely dynamic table name.

Deferred, with reasons

  • L45 (the specifiers search-index generator and its freshness check) — its npm-script entry lands in package.json, which PR audit fixes (P7): make the maintenance scripts refuse by default instead of mutating by default #2620's package owns while open. Pick up once that merges.

  • L131 (de-duplicating pdfjs-dist and the ZIP implementations, declaring playwright-core) — needs package.json, package-lock.json and npm registry resolution. Same ownership block.

  • L49 (pinning the docling model download to a revision) — cannot be done offline. docling is not installed in this environment, and eval/docling/requirements.txt pins Python wheels and their sha256s but records no HuggingFace model revisions; those revisions are constants inside the wheel. Neither a pip install nor a huggingface.co read was made. The owner can obtain them with, in a terminal at the repo root:

    docker run --rm -v "$PWD/eval/docling/requirements.txt:/tmp/r.txt:ro" python:3.11-slim bash -lc \
      'apt-get update -qq && apt-get install -y -qq --no-install-recommends libgl1 libglib2.0-0 >/dev/null && \
       pip install --no-cache-dir --require-hashes -r /tmp/r.txt >/dev/null && \
       docling-tools models download --help && \
       python -c "import inspect, docling.utils.model_downloader as m; print(inspect.getsource(m))"'
    

    Then pin those revisions in the prefetch step of both Dockerfile.worker:83-84 and eval/docling/Dockerfile:44-45 — they must stay identical or the Gate B shadow measurements stop being comparable — and record the resulting model digests in the Gate B decision record.

RAG impact: none

Verification

  • npm run verify:pr-local — result: - completed: check:runtime, check:installed-lock-parity, format:changed, check:diff-integrity, lint, typecheck, test, check:repo-awareness-snapshot, build, check:rag:fixtures, check:medication-interactions, check:medication-lexicon-report · - failed: (none) · - not reached: (none) · Tests 15135 passed | 2 expected fail | 3 skipped (15140) (the gate runner recorded exit code 0)
  • npx tsc --noEmit -p tsconfig.typecheck.json — exit 0. The same command on the untouched base also exits 0, so this is a real pass rather than a pre-existing-error baseline.
  • node scripts/check-owner-scope-api.mjs✓ owner-scope phase 1: 60 src/app/api files clean against 26 owner-scoped tables. / ✓ owner-scope phase 2: 85 direct, 18 user-keyed, 29 derived-tier, 1 untiered-table and 1 dynamic-table-dispatch queries scoped. Run deliberately, because scripts/lib/tenancy-scan.mjs derives its tenancy tiers by parsing database.types.ts, so adding tables can move a table between tiers.
  • npm run check:diff-integrity[diff-integrity] PASS — 0 changed test file(s), 0 -> 0 test case(s), against base 33c2dc161. No test file is touched.

Verification not run: npm run verify:ui, npm run verify:release, and every provider-backed gate — all work was offline and nothing was pointed at the hosted Supabase project.

Risk and rollout

  • Risk: medium, and the shape of it matters. The regenerated types come from supabase/schema.sql, not from the live database. If the live schema has drifted from that file, the types now assert a shape the database may not have — and because the as never / as unknown as escapes are gone, a drifted column surfaces as a runtime error rather than being silently swallowed. That is the safer failure direction, but it is a real change in behaviour under drift. The offline machinery cannot close this: only the post-merge live-drift workflow, with both check:drift and check:migration-history green, confirms schema.sql matches production, and that is provider-backed and was not run.
  • Second residual: document_corpus_access_snapshots carries an owner_id column, so the tenancy scan now classifies it into the direct tier. Nothing queries it today, but the first API route that does will need owner scoping.
  • Third: the two _scoped retrieval RPCs are dispatched dynamically from src/lib/rag/**, which was not read into or modified. Their new types are additive and the typecheck is clean, but no retrieval behaviour was exercised. There is no RAG behaviour change here — this commit is types plus cast removal only.
  • Rollback: revert the single commit.
  • Provider or production effects: none at build or test time.
  • RAG impact: none

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
    no change to source verification or citation requirements.
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
    none introduced or expanded.
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
    unchanged; no env value or project ref altered, and no tool was pointed at the hosted project — the types were written from supabase/schema.sql.
  • Service-role keys and private document access remain server-only
    unchanged; removing the escapes strengthens type checking on the service-role client rather than widening access.
  • Demo/synthetic content remains clearly separated from real clinical sources
    unchanged.
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
    unchanged.
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed
    reviewed; generated types and cast removal only, no decision-support behaviour added.

Notes

  • No file under supabase/migrations/**, package.json, package-lock.json or src/lib/rag/** is touched by this PR.
  • One owner per file across the remediation programme: this package's files are edited by no other open remediation PR, and the three findings that would have overlapped are deferred above.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DHSyfuC6mS98ystWFiitAR


Generated by Claude Code


Note

Medium Risk
Types reflect schema.sql, not live Postgres; with casts removed, schema drift vs production can surface as type or runtime failures instead of being silently bypassed. First queries against newly typed tables like document_corpus_access_snapshots will need correct owner scoping.

Overview
Refreshes database.types.ts from supabase/schema.sql so generated Supabase types match the committed schema: five tables (including indexing_v3_agent_jobs, corpus-access tables, rate-limit subjects, document_title_words) and nine callable RPCs (e.g. schema_drift_snapshot, scoped retrieval helpers, agent-job status updates).

Removes type escapes that existed only because types were stale: ingestion-mutation-safety.ts now queries indexing_v3_agent_jobs on the typed admin client (no SupabaseClient cast or local row alias), and check-drift.ts calls schema_drift_snapshot without as never.

No migrations, package changes, or RAG route logic in this diff—compile-time safety and audit remediation only.

Reviewed by Cursor Bugbot for commit eea69cb. Configure here.

…ype casts (L118)

Add the five public tables and nine callable RPCs that supabase/schema.sql
defines but src/lib/supabase/database.types.ts had never carried:

  tables  api_rate_limit_subjects, document_corpus_access_snapshots,
          document_corpus_access_state, document_title_words,
          indexing_v3_agent_jobs
  RPCs    backfill_legacy_index_health_batch, match_document_chunks_text_scoped,
          match_document_index_units_hybrid_scoped, migration_history_versions,
          purge_expired_rag_query_misses, retrieval_owner_matches,
          schema_drift_snapshot, set_document_corpus_access_mode,
          update_indexing_v3_agent_job_status

The eleven remaining schema functions return `trigger` and are deliberately not
emitted, matching the file's existing convention (it carries no trigger
functions today).

The Supabase CLI is not installed in this environment and installing it would
need network access, so the entries were written by hand from the DDL in
supabase/schema.sql, following the ordering, nullability and Relationships
conventions of the surrounding generated entries.

With the gap closed, remove the three casts that existed only to work around it:
two `as unknown as SupabaseClient` clients in ingestion-mutation-safety.ts (plus
the now-redundant row casts and the local AgentEnrichmentJobRow alias they
needed) and the `"schema_drift_snapshot" as never` RPC name in check-drift.ts.
The same cast in scripts/archive/check-july8-live-batch.ts is left alone because
scripts/archive/** is excluded from tsconfig.typecheck.json, so its removal
could not be proven here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHSyfuC6mS98ystWFiitAR
@supabase

supabase Bot commented Sep 4, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 40cf2dda-9bfb-4a35-a2e0-d965606f2a19


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@BigSimmo
BigSimmo marked this pull request as ready for review September 4, 2026 18:29
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@BigSimmo
BigSimmo enabled auto-merge (squash) September 4, 2026 18:30
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_3bd9f7a0-e69a-4fcf-84ba-511cb96536a7)

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_6579db46-0ba9-4adc-94bc-bedad590f796)

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_92e18b47-218a-4f56-abb8-eed18d1395bd)

@BigSimmo
BigSimmo merged commit f7e757c into main Sep 5, 2026
31 checks passed
@BigSimmo
BigSimmo deleted the claude/audit-fix-p20 branch September 5, 2026 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants