Skip to content

Database: record the three managed-ingestion migrations already applied to live - #3551

Merged
gitar-bot[bot] merged 17 commits into
mainfrom
claude/project-thread-sr3mdk
Oct 15, 2026
Merged

gitar-bot[bot] merged 17 commits into
mainfrom
claude/project-thread-sr3mdk

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

User description

Requested by Josh · project thread

Summary

Before: the live database is out of step with main. On 13 October three migrations from draft PR #3546 were applied to live straight from a session, before review or commit. Because live now has migrations main does not know about, the four migrations that came with #3538 (20261013140000 to 20261013170000) never applied, the post-merge live drift check has failed since 14 October (issue #3542), and the registrar assessment tables and the force row level security changes from #3538 are missing on live.

After: main records the three migrations as they already exist on live, from the #3546 branch, plus #3546's validation-only guard migration. Two files carry small replay-only edits, described below, that change nothing on live. The schema snapshot, drift manifest and applied-migration hashes match live. When this merges, the Supabase integration has only #3538's four migrations and the guard left to apply, and the live drift check should go green, provided the integration accepts their order (see the open question under Risk).

This is the "keep and fix" option the owner chose on 2026-10-15. Nothing that is already live is changed or reversed. The rest of #3546 (the worker and app code for administrator document intake) is not in this PR and stays in draft for its own review.

Migration history edit approved: these three migrations are already applied to the live database on 2026-10-13, and this records them on main so history matches live. Guard migration 20261014164220 validates the applied objects and builds nothing.

Areas touched: Data platform and access, Delivery and assurance, Knowledge and records

What is in it

  • 20261013144347_managed_generation_quality_repair_ownership.sql and 20261013200007_managed_native_pdf_terminal_append.sql: unchanged copies of the Reconcile admin ingestion, native PDF extraction and grounded Answer #3546 files, which are the versions live recorded.
  • 20261013075944_administrator_txt_fenced_runtime_cutover.sql: the Reconcile admin ingestion, native PDF extraction and grounded Answer #3546 body, wrapped in begin;/commit;. Live applied it inside one external transaction. A fresh chain (CI Migration replay, Supabase Preview) runs each file outside a transaction, where LOCK TABLE fails with SQLSTATE 25P01. It also adds one grant all on table public.document_strict_gate_status to service_role, which live already holds and the body's preimage check pins. On live it is a no-op.
  • 20261014164220_validate_managed_ingestion_historical_reconciliation.sql: Reconcile admin ingestion, native PDF extraction and grounded Answer #3546's fail-fast guard. It checks the objects exist and raises an exception if not. It never builds anything. It now runs in a transaction so set local applies, and it no longer pins raw source_md5 body bytes. Live stores some bodies with CRLF line endings, so a byte pin can never pass a fresh replay. Every body is still pinned by definition_md5.
  • Both edited files were resealed in applied-migration-hashes.json with the owner's approval on 2026-10-15. Their hashes were first sealed in this PR, not on main.
  • supabase/schema.sql, supabase/drift-manifest.json, supabase/applied-migration-hashes.json, .gitattributes: taken from Reconcile admin ingestion, native PDF extraction and grounded Answer #3546, then schema.sql stored with LF endings so the byte-identical parity tests pass. The drift check strips CR before hashing, so the manifest hash is unchanged.
  • tests/supabase-schema.test.ts: Reconcile admin ingestion, native PDF extraction and grounded Answer #3546's anchored owner_id regex, so the new admission events table is checked correctly.
  • docs/codebase-index.md: names document_admission_events.
  • tests/worker-lease-transition-contract.test.ts: anchors on the unfenced complete_ingestion_job overload that main's worker calls.
  • docs/audit/live-drift-forensics-2026-08.md: a post-merge runbook for the case where the integration refuses the out-of-order versions.

Verification

  • Checks run:
    • The drift manifest's function and view hashes match the live hashes reported by the failed live drift run (64a776fa, 0d1f396d, 4c04b607, dcda90c6, 92c7f8f7 and view e84a20e6).
    • None of the Reconcile admin ingestion, native PDF extraction and grounded Answer #3546 migrations touch the tables that feat(audit): comprehensive repository audit remediation and frontend hardening #3538's four pending migrations change.
    • A full local replay of all 309 migrations (Supabase CLI 2.108.0, supabase migration up, Postgres 17.6) applies cleanly. After it, check:drift-manifest-freshness reports "supabase/drift-manifest.json matches a fresh regeneration." and check:chain-mirror-parity --strict reports "No divergence between the migration chain and supabase/schema.sql." The Supabase Preview branch also applied the migrations on fb71e2b.
    • npm run check:migration-role, check:migration-immutability (309 files) and check:function-grants: pass.
    • 14 migration, drift, schema and pr-policy test files: 373 passed.
    • Earlier, on 70ba925: the 17 database-related test files, 448 passed, and npm run verify:pr-local (heavy scope): every static check, lint and typecheck completed. test: Tests 3 failed | 29876 passed | 5 skipped. One failure was real and is fixed in the third commit (the worker transition test now anchors on the unfenced complete_ingestion_job overload, since schema.sql holds both). After the fix that file and tests/supabase-schema.test.ts pass, 177 of 177. The other two are in tests/test-runner-safety.test.ts and come from this container's Playwright browser cache (expects chromium-1243, but /opt/pw-browsers only has: chromium-1194), the same as on CI: remove the never-working CodSpeed check and make CodeRabbit advisory #3549.
    • check:rag:fixtures, check:medication-interactions, check:medication-lexicon-report: pass.
  • Not yet proven: CI's Migration replay job skips while a PR is a draft, so it has not run on these files in CI. The local replay above runs the same command.

Risk and rollout

RAG impact: no retrieval behaviour change. No ranking or retrieval code is changed, and the retrieval functions are recorded as they already are on live.

Notes

  • Administrator document adding and reindexing are switched off on live since 13 October, because the live database now expects Reconcile admin ingestion, native PDF extraction and grounded Answer #3546's new intake path. This PR does not turn them back on. That needs the rest of Reconcile admin ingestion, native PDF extraction and grounded Answer #3546, reviewed separately.
  • A review bot pushed a new migration (20261014170000_recheck_managed_quality_after_repair.sql) to this branch. It was unapproved and Gitar found an ACL gap in it, so it was removed in fb71e2b. Qodo's snapshot finding against the live repair_enrichment_quality_batch stays open for its own reviewed forward migration.
  • After merge, the owner will rotate the database password and Supabase access token so that merging to main is the only route to the live database.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LuYbdEGXeMntVA9KMgtAEx

Summary by CodeRabbit

  • New Features
    • Document processing now records administrator intake events and supports generation-specific page storage and visibility.
    • Ingestion and indexing now include lease-based processing controls.
  • Improvements
    • Document quality repair can fill in missing summaries, sections, embeddings, and index content, and update processing status.
    • Added checks to verify managed-ingestion schema consistency before reconciliation is considered complete.

CodeAnt-AI Description

Align production migration history with administrator document indexing

What Changed

  • Records database changes already applied in production, bringing the repository’s schema and migration records in line with the live database and addressing the mismatch that blocked later migrations.
  • Records administrator text indexing with checks that the indexed content matches the uploaded source.
  • Records a narrowly scoped four-page PDF indexing path that validates page and table evidence while keeping captured table images private; it does not grant clinical or publication approval.
  • Keeps managed administrator documents out of the generic enrichment repair process.

Impact

✅ Fewer database releases blocked by migration-history drift
✅ Administrator text indexed against its uploaded source
✅ PDF table captures remain private

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

…ed to live

Live production applied 20261013075944, 20261013144347 and 20261013200007
from the unmerged ingestion branch (PR 3546) on 2026-10-13. Because main did
not have them, the Supabase integration could not apply PR 3538's four
migrations (20261013140000 to 20261013170000) and the post-merge live-drift
check has failed since 2026-10-14 (issue 3542).

This brings exactly the database half of PR 3546 onto main, byte for byte:
the three applied migrations, their validation-only guard
20261014164220, the matching schema.sql and drift manifest, their sealed
hashes and the -text attributes that keep their bytes intact. No
application, worker or edge-function code changes. The new manifest's
function hashes match the live hashes the failed live-drift run reported.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuYbdEGXeMntVA9KMgtAEx
…, match the owner-delete test

- schema.sql now uses LF like every other copy, so the byte-identical parity
  tests pass. The drift manifest hash is unchanged because check:drift strips
  CR before hashing.
- docs/codebase-index.md names document_admission_events.
- tests/supabase-schema.test.ts takes the anchored owner_id regex from the
  managed-ingestion branch so the admission events table is checked correctly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuYbdEGXeMntVA9KMgtAEx
schema.sql now holds both complete_ingestion_job overloads: the unfenced one
main's worker calls, and the fenced jsonb one already applied to live. The
test now anchors on the unfenced signature so it checks the function this
worker actually calls.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuYbdEGXeMntVA9KMgtAEx
@BigSimmo BigSimmo self-assigned this Oct 15, 2026
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

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 39 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 83 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: ad770088-927b-4270-be13-5ecb2146ecb9
📥 Commits

Reviewing files that changed from the base of the PR and between 8e0ccc9 and 8d05152.

📒 Files selected for processing: 13
  • .gitattributes
  • .gitleaksignore
  • docs/audit/live-drift-forensics-2026-08.md
  • docs/codebase-index.md
  • supabase/applied-migration-hashes.json
  • supabase/drift-manifest.json
  • supabase/migrations/20261013075944_administrator_txt_fenced_runtime_cutover.sql
  • supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql
  • supabase/migrations/20261013200007_managed_native_pdf_terminal_append.sql
  • supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql
  • supabase/schema.sql
  • tests/supabase-schema.test.ts
  • tests/worker-lease-transition-contract.test.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: BigSimmo/PsychSift/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Team
  • Run ID: e4149b3d-0be7-43e4-9101-3cb3d1d6c0e3
📥 Commits

Reviewing files that changed from the base of the PR and between d6bb16b and 8e0ccc9.

📒 Files selected for processing: 13
  • .gitattributes
  • .gitleaksignore
  • docs/audit/live-drift-forensics-2026-08.md
  • docs/codebase-index.md
  • supabase/applied-migration-hashes.json
  • supabase/drift-manifest.json
  • supabase/migrations/20261013075944_administrator_txt_fenced_runtime_cutover.sql
  • supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql
  • supabase/migrations/20261013200007_managed_native_pdf_terminal_append.sql
  • supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql
  • supabase/schema.sql
  • tests/supabase-schema.test.ts
  • tests/worker-lease-transition-contract.test.ts

Included review availability: This review used your included allowance. 6 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 8 reviews per hour.

📝 Walkthrough

The pull request updates managed-ingestion quality repair and records admission, page-generation, and worker contracts in the drift manifest. It adds a migration that validates historical database state against pinned contracts and updates migration records and reconciliation guidance.

Changes: Managed ingestion reconciliation

Layer / File(s) Summary
Repair indexed-document quality
supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql, supabase/drift-manifest.json
The migration replaces the quality-repair function, checks its preserved database attributes, and records its definition hash. The function fills missing artifacts, updates quality records and ingestion jobs, and returns processing counts.
Admission and page-generation contracts
supabase/drift-manifest.json, docs/codebase-index.md, tests/supabase-schema.test.ts
The manifest records administrator-document admission, generation-scoped page storage and visibility, and related constraints, indexes, and functions. The schema inventory and owner foreign-key matcher are updated.
Worker leases and ingestion RPC contracts
supabase/drift-manifest.json, tests/worker-lease-transition-contract.test.ts
The manifest records lease fields and constraints and updates ingestion and indexing RPC contracts. The test extraction now selects the unfenced complete_ingestion_job overload.
Validate reconciled migration state
supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql, supabase/applied-migration-hashes.json, supabase/drift-manifest.json, .gitattributes, .gitleaksignore, docs/audit/live-drift-forensics-2026-08.md
The migration compares catalog state with pinned contracts and raises on differences without repairing state. Migration records and the drift manifest are updated; the runbook, line-ending attributes, and Gitleaks ignore list receive related updates.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix

Suggested reviewers: claude

Merge Risk: 🔵 Low · up to 8e0cc

This change records migrations that are already live and adds a validation-only guard. It does not modify live state. The main remaining risk is operational. After merge, the automatic apply may skip the pending migrations because their versions sort before the newest recorded version. The documented runbook covers that case. Merge in the approved window and confirm that CI migration replay passes first.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (8 skipped: 8 … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the primary change: recording the three managed-ingestion migrations already applied to the live database.
Description check Passed The description is complete and follows the repository template. It includes the summary, areas touched, verification results and limitations, migration risks, rollout conditions, rollback guidance, p…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (8 skipped: 8 unsupported.)

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • 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 15, 2026 •

Copy link
Copy Markdown

Updates to Preview Branch (claude/project-thread-sr3mdk) ↗︎

Deployments Status Updated
Database ✅ Thu, 15 Oct 2026 12:07:31 UTC
Services ✅ Thu, 15 Oct 2026 12:07:31 UTC
APIs ✅ Thu, 15 Oct 2026 12:07:31 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 ✅ Thu, 15 Oct 2026 12:07:32 UTC
Migrations ✅ Thu, 15 Oct 2026 12:07:34 UTC
Seeding ✅ Thu, 15 Oct 2026 12:07:38 UTC
Edge Functions ✅ Thu, 15 Oct 2026 12:07:41 UTC

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

…line

The CRLF to LF rewrite of supabase/schema.sql makes gitleaks rescan an unchanged
seed-data line, where medication labels read as generic API keys. No credential.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuYbdEGXeMntVA9KMgtAEx
@BigSimmo
BigSimmo marked this pull request as ready for review October 15, 2026 10:57

@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 15, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 8d05152 Oct 15, 2026 · 12:06 12:14
✅ Reviewed your PR 70ba925 Oct 15, 2026 · 10:57 11:10

@codeant-ai

codeant-ai Bot commented Oct 15, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 15, 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-15T11:42:14.885448Z c25d36b 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.

@BigSimmo
BigSimmo marked this pull request as draft October 15, 2026 10:57
@claude

claude Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Claude encountered an error after 2s —— View job


I'll analyze this and get back to you.

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Oct 15, 2026
@qodo-code-review

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

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Reconcile managed-ingestion migration history with live

🐞 Bug fix ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Record managed-ingestion migrations already applied to live so repository history can catch up.
• Add a fail-fast guard and refresh drift records against the expected database state.
• Document the remaining migration-order risk and adjust schema tests for the recorded state.
Diagram

graph TD
  Live[("Live database")] --> History["Recorded migrations"] --> Guard["Validation guard"] --> Integration["Supabase integration"]
  Guard --> Live
  Live --> Drift["Drift manifest"] --> Check["Drift check"]
  Integration --> Check
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Repair migration history manually
  • ➕ Could avoid replaying migrations whose objects already exist on live.
  • ➖ Introduces a separate production history operation.
  • ➖ Would still require reviewed schema and drift records in the repository.
2. Replace historical migrations with one reconciliation migration
  • ➕ Could reduce the number of migrations pending in a fresh environment.
  • ➖ Would no longer record the migration versions applied to live.
  • ➖ Risks diverging fresh-chain and production history.

Recommendation: Record the applied versions and validate their resulting contracts, rather than reverse live changes or silently rewrite its migration history. The remaining out-of-order apply risk needs explicit observation and, if necessary, the documented authorised push procedure.

Files changed (11) +2937 / -39

Enhancement (1) +1586 / -0
20261013200007_managed_native_pdf_terminal_append.sqlRecord the applied native-PDF terminal append +1586/-0

Record the applied native-PDF terminal append

• Adds private retained-artifact tables and native-PDF evidence, closure, and terminal functions. It also extends managed ingestion readback and commit functions while checking expected preimages.

supabase/migrations/20261013200007_managed_native_pdf_terminal_append.sql

Bug fix (2) +569 / -0
20261013144347_managed_generation_quality_repair_ownership.sqlRecord the applied quality-repair function migration +289/-0

Record the applied quality-repair function migration

• Adds the migration that replaces repair_enrichment_quality_batch with generation-aware candidate selection and enrichment-quality repair. Preimage and postimage checks protect the function's definition, ownership, privileges, and security contract.

supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql

20261014164220_validate_managed_ingestion_historical_reconciliation.sqlFail fast on managed-ingestion state mismatch +280/-0

Fail fast on managed-ingestion state mismatch

• Adds a validation-only migration that compares expected functions, relations, privileges, and the private schema against database catalogues. It raises on missing or unexpected managed objects without repairing data or changing migration history.

supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql

Tests (2) +7 / -3
supabase-schema.test.tsAnchor owner-delete checks to column definitions +3/-1

Anchor owner-delete checks to column definitions

• Anchors the owner_id foreign-key expression to a schema line, preventing another occurrence in the expanded snapshot from satisfying the test.

tests/supabase-schema.test.ts

worker-lease-transition-contract.test.tsTarget unfenced worker RPC overloads +4/-2

Target unfenced worker RPC overloads

• Adds newline boundaries to function-source lookups so lease-transition assertions select the unfenced overloads the worker calls, rather than newly recorded fenced overloads.

tests/worker-lease-transition-contract.test.ts

Documentation (2) +4 / -0
live-drift-forensics-2026-08.mdDocument post-merge migration reconciliation +2/-0

Document post-merge migration reconciliation

• Adds a runbook for checking integration, confirming the exact pending set, handling an out-of-order rejection in an authorised window, and rerunning drift and history checks.

docs/audit/live-drift-forensics-2026-08.md

codebase-index.mdIndex administrator admission events +2/-0

Index administrator admission events

• Names document_admission_events in the schema-table index so the administrator intake record is discoverable.

docs/codebase-index.md

Other (4) +771 / -36
.gitattributesPreserve bytes of the four managed-ingestion SQL files +4/-0

Preserve bytes of the four managed-ingestion SQL files

• Marks the three historical migrations and their validation guard as non-text to prevent Git line-ending conversion from altering their recorded bytes.

.gitattributes

.gitleaksignoreSuppress two schema-snapshot false positives +5/-0

Suppress two schema-snapshot false positives

• Pins known false positives on an unchanged seed-data line that was rescanned when the schema snapshot's line endings changed.

.gitleaksignore

applied-migration-hashes.jsonSeal the recorded managed-ingestion migrations +6/-2

Seal the recorded managed-ingestion migrations

• Adds hashes for the three historical migration versions and the validation guard, and refreshes the seal timestamp. Existing migration hashes remain unchanged.

supabase/applied-migration-hashes.json

drift-manifest.jsonRefresh the managed-ingestion schema manifest +756/-34

Refresh the managed-ingestion schema manifest

• Records the resulting tables, functions, views, constraints, indexes, and schema hash for managed ingestion. This provides the reference state for drift checks.

supabase/drift-manifest.json

Copy link
Copy Markdown
Owner Author

Status of the failing checks on 70ba925:

  • Gitleaks (on b548c45): the four findings were medication labels in the existing seed-data line of supabase/schema.sql (line 13492), not credentials. The CRLF to LF rewrite makes the unchanged line rescan as new. Pinned by fingerprint in .gitleaksignore in 70ba925, following the file's existing pattern.
  • PR required (on b548c45): cancelled by the newer push, not a failure of this diff.
  • Supabase Preview: duplicate key value violates unique constraint "schema_migrations_pkey", Key (version)=(20260713201542) already exists. That version is a July migration this PR does not touch, and it exists exactly once in supabase/migrations. The same error appeared on feat(audit): comprehensive repository audit remediation and frontend hardening #3538, so I believe this is the preview branch replaying its history a second time after the second push, not this change. That is not proven, and this session cannot re-run the Supabase app check or open the dashboard.
  • Migration replay (db-reset-verify) is the authoritative replay and is skipped while the PR is a draft. It has not run yet. The owner is being asked whether to mark the PR ready, since Gitar auto-merges ready PRs once green.

Generated by Claude Code

@qodo-code-review

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

Copy link
Copy Markdown
Contributor

Code Review by Qodo

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

Grey Divider


Action required

1. Guard misses changed string literals 🔴 High 📜 Skill insight ≡ Correctness
Description
Removing source_md5 leaves definition_md5 as the only function-body pin, but its normalization
also removes whitespace inside quoted string literals. If a live function differs only in a
whitespace-bearing value such as a JSON key, the reconciliation guard accepts the changed behavior
instead of reporting a mismatch.
Code

supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[R12-14]

+-- Raw body bytes (source_md5) are not pinned: some bodies live holds use CRLF line
+-- endings that the recorded files do not, so a byte pin can only ever pass on live
+-- and fails every fresh chain replay. The body runs in begin/commit so SET LOCAL
Relevance

●●● Strong

Recent migration reviews accept findings where validation guards miss semantic schema or
function-definition discrepancies.

PR-#2547
PR-#3485

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed comment explicitly drops the raw body pin, while the remaining definition hash removes
every whitespace sequence from the function definition, including those within executable string
literals. The migrate skill calls for explicit validation of changed migrations and functions.

supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[12-15]
supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[154-169]
Skill: migrate

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 guard drops its raw function-body pin and relies on a definition hash that removes meaningful whitespace inside string literals.
## Fix Focus Areas
- supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[12-15]
- supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[154-168]
## Recommended Fix
Add a separate function-body hash that normalizes CRLF to LF without removing whitespace inside literals. Seal its expected values for both live and a fresh-chain replay, and retain the existing definition hash as an additional check.

ⓘ 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. Staging checks mask live drift ✗ Dismissed
Description
The runbook treats supabase link as selecting the target for check:drift and
check:migration-history, but both npm checks use environment credentials independently of the CLI
link. If the checkout retains staging values, an operator can push migrations to production, pass
both checks against staging, and close live reconciliation without verifying production.
Code

docs/audit/live-drift-forensics-2026-08.md[1667]

+**Post-merge runbook for the managed-ingestion reconciliation.** Watch the integration run after merge. If the apply reports an out-of-order rejection, or the live history still shows `20261013140000`–`20261013170000` as local-only, first link the checkout to production (`supabase link --project-ref sjrfecxgysukkwxsowpy`) so every command below targets the same project. Then run `supabase migration list --linked` and `supabase db push --linked --include-all --dry-run`, and confirm both show exactly those four #3538 migrations plus `20261014164220` as pending. In an authorised production window, run `supabase db push --linked --include-all`, then rerun both `npm run check:drift` and `npm run check:migration-history`. Confirm that #3542 closes and that the migration-history check reports no pending, local-only, remote-only, or preview blockers before closing the reconciliation.
Relevance

●●● Strong

Accepted: production-targeting safeguards and explicit runbook verification have prior acceptance in
this file.

PR-#2205

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The release-readiness-review skill requires a target-database check for production, but the runbook
pins only the Supabase CLI link and says subsequent commands target the same project. The
migration-history check reads its URL and key from the environment, while the drift check validates
an environment-derived project and creates an environment-configured admin client; its project
validation explicitly accepts a declared staging project.

docs/audit/live-drift-forensics-2026-08.md[1667-1667]
scripts/check-drift.ts[494-518]
scripts/check-migration-history-alignment.ts[277-285]
scripts/check-migration-history-alignment.ts[264-267]
scripts/check-drift.ts[493-518]
src/lib/supabase/project.ts[126-142]
src/lib/supabase/admin.ts[60-70]
Skill: release-readiness-review

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 post-push npm checks read their target from environment variables, not the Supabase CLI link, so successful staging checks can be mistaken for production verification.

## Fix Focus Areas
- docs/audit/live-drift-forensics-2026-08.md[1667-1667]

## Recommended Fix
Update the runbook to require production `NEXT_PUBLIC_SUPABASE_URL` and a matching `SUPABASE_SERVICE_ROLE_KEY` for both npm checks. Require the operator to verify the configured production project identity before running or accepting either check, and require both production check results before closing the reconciliation.

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


2. Production migrations may go unchecked ✓ Resolved
Description
The runbook runs supabase migration list --linked against the checkout's linked project, but
directs db push to an explicit production project ref. If the checkout is linked to staging, the
operator can confirm staging's pending set and then apply a different, unverified set of migrations
to production with --include-all.
Code

docs/audit/live-drift-forensics-2026-08.md[1667]

+**Post-merge runbook for the managed-ingestion reconciliation.** Watch the integration run after merge. If the apply reports an out-of-order rejection, or the live history still shows `20261013140000`–`20261013170000` as local-only, first run `supabase migration list --linked` and confirm that the pending set is exactly those four #3538 migrations plus `20261014164220`. In an authorised production window, run `supabase db push --linked --project-ref <prod> --include-all`, then rerun the live-drift workflow and confirm that #3542 closes.
Relevance

●●● Strong

The team accepted project-specific migration checks and rejected relying on a linked target before
production operations.

PR-#2250
PR-#2205

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new runbook specifies production only for the push, while the staging instructions demonstrate
that migration list --linked follows the checkout's staging link. The surrounding runbook states
that --include-all applies every locally absent version, making a check against the wrong project
insufficient.

docs/audit/live-drift-forensics-2026-08.md[1663-1667]
docs/staging-setup.md[35-40]
🌐 The CLI reference lists a project-ref option for migration list and describes the linked-project target.

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 preflight migration list can inspect a different linked project from the production target of the subsequent include-all push.
## Fix Focus Areas
- docs/audit/live-drift-forensics-2026-08.md[1667-1667]
## Recommended Fix
Pass `--project-ref <prod>` to `supabase migration list --linked` as well, and confirm its pending set before running the push.

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


3. Repaired documents stay pending ✓ Resolved
Description
repair_enrichment_quality_batch computes gate from base-table reads that cannot see artifacts
inserted by other data-modifying CTEs in the same statement. When a candidate lacks artifacts that
the batch successfully creates, upsert_quality still records partial and defer_jobs schedules
its ingestion job for another attempt.
Code

supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[R200-203]

+           exists (select 1 from public.document_memory_cards mc where mc.document_id = c.document_id) as has_memory,
+           exists (select 1 from public.document_sections s where s.document_id = c.document_id) as has_sections,
+           exists (select 1 from public.document_embedding_fields e where e.document_id = c.document_id and e.field_type = 'document_title') as has_title_emb,
+           exists (select 1 from public.document_embedding_fields e where e.document_id = c.document_id and e.field_type = 'document_summary') as has_summary_emb,
Relevance

●●● Strong

Accepted repair-migration findings address stale state, exact-count integrity, and data-preservation
risks.

PR-#3111
PR-#2547

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The migrate skill calls for checking data preservation and schema consistency, the data skill calls
for reconciliation and integrity checks, and the ingest skill calls for checking partial failure and
retry behavior. The function inserts missing artifacts, then tests their existence in the same
data-modifying CTE statement; PostgreSQL uses one snapshot for those CTEs, so the subsequent quality
and job updates can reflect the old state.

supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[74-115]
supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[198-225]
supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[240-249]
Skill: migrate
Skill: data
Skill: ingest

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 repair function evaluates quality against the statement's pre-insert snapshot, leaving successfully repaired documents marked partial and their jobs pending. The historical migration is already applied live and must remain byte-identical.

## Fix Focus Areas
- supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[198-225]
- supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[240-249]

## Recommended Fix
Add a new, later migration that replaces the function without editing the applied migration. Separate artifact insertion from the quality check into successive SQL statements so the check sees committed-in-function inserts; verify with a local fixture that starts without required artifacts and ends with good quality and no deferred job.

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


View resolved (2)
4. Live migration history can stay unverified ✓ Resolved
Description
The new post-merge runbook checks the pending set before supabase db push but never reruns the
migration-history check afterward. If recorded history contains no-statement or otherwise
inconsistent rows, the drift workflow may pass while migration history remains unresolved, and the
runbook can incorrectly treat the reconciliation as complete.
Code

docs/audit/live-drift-forensics-2026-08.md[1667]

+**Post-merge runbook for the managed-ingestion reconciliation.** Watch the integration run after merge. If the apply reports an out-of-order rejection, or the live history still shows `20261013140000`–`20261013170000` as local-only, first run `supabase migration list --linked` and confirm that the pending set is exactly those four #3538 migrations plus `20261014164220`. In an authorised production window, run `supabase db push --linked --project-ref <prod> --include-all`, then rerun the live-drift workflow and confirm that #3542 closes.
Relevance

●●● Strong

Recent runbooks require explicit post-change verification of database state, not relying solely on
drift results.

PR-#3522
PR-#2250

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The runbook added in this PR instructs operators to inspect migration history before applying
migrations and then rerun the drift workflow, but it does not require the post-merge
migration-history gate. Repository guidance states that supabase migration list reads recorded
history only and that both drift and migration-history checks are required after migration changes;
the new validation guard also explicitly does not change migration history.

Align local and remote migration history
Verify a green live drift run
docs/audit/live-drift-forensics-2026-08.md[1667-1667]
supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[3-5]
AGENTS.md[146-147]

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 post-merge runbook reruns the live drift workflow but does not require `check:migration-history` to pass after applying the pending migrations. This can leave migration-history inconsistencies undetected while the runbook treats the reconciliation as complete.

## Fix Focus Areas
- docs/audit/live-drift-forensics-2026-08.md[1667-1667]

## Recommended Fix
After `supabase db push --linked --include-all`, require both `npm run check:drift` and `npm run check:migration-history` to complete successfully, and state that the migration-history check must show no pending, local-only, remote-only, or preview blockers before closing the reconciliation.

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


5. Pending live migrations may still not apply on merge ✓ Resolved
Description
After this merge, the newest migration recorded on live is 20261013200007, but the four #3538
migrations still waiting (20261013140000 to 20261013170000) sort before it, so they would be
inserted into history behind the live tip. Supabase's apply path, like a plain supabase db push,
refuses to insert migrations behind the remote tip unless run with --include-all. If the
integration hits that refusal, nothing applies: the registrar tables and FORCE RLS changes stay
missing on live, the guard migration 20261014164220 never runs, and the live drift check (#3542)
stays red even though main now matches live's history.
Code

supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[R1-4]

+-- Validate the final managed-ingestion state already established by historical
+-- migrations 20261013075944, 20261013144347 and 20261013200007. Their original
+-- versions and bytes are preserved. This additive guard neither replays their
+-- preimage-sensitive DDL nor changes migration history or repairs missing state.
Relevance

●●● Strong

Recent migration-history work consistently accepts live-drift and out-of-sync deployment risks as
actionable.

PR-#2198
PR-#2185
PR-#2828

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The repo's own forensics log shows the CLI rejecting this exact case on this production project and
needing --include-all. It also warns that future out-of-order inserts need that flag and a check
of the pending set first. A Supabase issue reports that the integration's migrate step does not use
--include-all and fails on out-of-order timestamps. This PR's premise is that merging alone will
let the integration apply 140000-170000 and the guard, even though all of them sort behind the live
tip 20261013200007.

docs/audit/live-drift-forensics-2026-08.md[1640-1665]
supabase/applied-migration-hashes.json[307-314]
🌐 The preview-branching migrate agent appears to NOT use --include-all (or equivalent), so it bails on out-of-order timestamps... The same gap is applied without error by supabase db push --include-all --linked.
🌐 Found local migration files to be inserted before the last migration on remote database. Rerun the command with --include-all flag to apply these migrations.

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

## Issue description
After merge, the pending migrations 20261013140000-20261013170000 (and the guard 20261014164220 behind them) sit before or around the live tip 20261013200007. Supabase's apply path rejects migrations inserted behind the remote tip unless run with `--include-all`, so the auto-apply on merge may fail and live stays drifted.

## Fix Focus Areas
- supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[1-18]
- docs/audit/live-drift-forensics-2026-08.md[1660-1665]

## Recommended Fix
Add a post-merge runbook step to the PR description, or to docs/database-remediation-plan.md. Watch the integration's run on merge. If it reports the out-of-order rejection, or migration history still shows 140000-170000 as local-only, first confirm with `supabase migration list --linked` that the pending set is exactly the four #3538 migrations plus 20261014164220. Then run `supabase db push --linked --project-ref <prod> --include-all` in an authorised window, and re-run the live-drift workflow to confirm #3542 closes.

ⓘ 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
✅ Web pages:
  +2 more
✅ Skills: 8 invoked
  migrate
  drift
  deploy
  release
  review
  release-readiness-review
  supabase
  operations
✅ Cross-repo context — repo relationships
  Explored: repo: BigSimmo/Medications (sha: f0fe3d04) — View relationship
✅ REVIEW.md
Review mode: Auto: 🧠 Deep: Multiple independent routing, sidebar, rail, and accessibility changes invite subtle defects.

Grey Divider

Tip of the day
💡 Did you know, you can hide the parts of a finding you never read, like the evidence or the agent prompt

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit 8d05152 🧠 Deep

Results up to commit 70ba925 🧠 Deep


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required

No findings for this group


Remediation recommended

No findings for this group


Informational

No findings for this group


Resolved findings

1. Repaired documents stay pending ✓ Resolved
Description
repair_enrichment_quality_batch computes gate from base-table reads that cannot see artifacts
inserted by other data-modifying CTEs in the same statement. When a candidate lacks artifacts that
the batch successfully creates, upsert_quality still records partial and defer_jobs schedules
its ingestion job for another attempt.
Code

supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[R200-203]

+           exists (select 1 from public.document_memory_cards mc where mc.document_id = c.document_id) as has_memory,
+           exists (select 1 from public.document_sections s where s.document_id = c.document_id) as has_sections,
+           exists (select 1 from public.document_embedding_fields e where e.document_id = c.document_id and e.field_type = 'document_title') as has_title_emb,
+           exists (select 1 from public.document_embedding_fields e where e.document_id = c.document_id and e.field_type = 'document_summary') as has_summary_emb,
Relevance

●●● Strong

Accepted repair-migration findings address stale state, exact-count integrity, and data-preservation
risks.

PR-#3111
PR-#2547

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The migrate skill calls for checking data preservation and schema consistency, the data skill calls
for reconciliation and integrity checks, and the ingest skill calls for checking partial failure and
retry behavior. The function inserts missing artifacts, then tests their existence in the same
data-modifying CTE statement; PostgreSQL uses one snapshot for those CTEs, so the subsequent quality
and job updates can reflect the old state.

supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[74-115]
supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[198-225]
supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[240-249]
Skill: migrate
Skill: data
Skill: ingest

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 repair function evaluates quality against the statement's pre-insert snapshot, leaving successfully repaired documents marked partial and their jobs pending. The historical migration is already applied live and must remain byte-identical.

## Fix Focus Areas
- supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[198-225]
- supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql[240-249]

## Recommended Fix
Add a new, later migration that replaces the function without editing the applied migration. Separate artifact insertion from the quality check into successive SQL statements so the check sees committed-in-function inserts; verify with a local fixture that starts without required artifacts and ends with good quality and no deferred job.

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


2. Pending live migrations may still not apply on merge ✓ Resolved
Description
After this merge, the newest migration recorded on live is 20261013200007, but the four #3538
migrations still waiting (20261013140000 to 20261013170000) sort before it, so they would be
inserted into history behind the live tip. Supabase's apply path, like a plain supabase db push,
refuses to insert migrations behind the remote tip unless run with --include-all. If the
integration hits that refusal, nothing applies: the registrar tables and FORCE RLS changes stay
missing on live, the guard migration 20261014164220 never runs, and the live drift check (#3542)
stays red even though main now matches live's history.
Code

supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[R1-4]

+-- Validate the final managed-ingestion state already established by historical
+-- migrations 20261013075944, 20261013144347 and 20261013200007. Their original
+-- versions and bytes are preserved. This additive guard neither replays their
+-- preimage-sensitive DDL nor changes migration history or repairs missing state.
Relevance

●●● Strong

Recent migration-history work consistently accepts live-drift and out-of-sync deployment risks as
actionable.

PR-#2198
PR-#2185
PR-#2828

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The repo's own forensics log shows the CLI rejecting this exact case on this production project and
needing --include-all. It also warns that future out-of-order inserts need that flag and a check
of the pending set first. A Supabase issue reports that the integration's migrate step does not use
--include-all and fails on out-of-order timestamps. This PR's premise is that merging alone will
let the integration apply 140000-170000 and the guard, even though all of them sort behind the live
tip 20261013200007.

docs/audit/live-drift-forensics-2026-08.md[1640-1665]
supabase/applied-migration-hashes.json[307-314]
🌐 The preview-branching migrate agent appears to NOT use --include-all (or equivalent), so it bails on out-of-order timestamps... The same gap is applied without error by supabase db push --include-all --linked.
🌐 Found local migration files to be inserted before the last migration on remote database. Rerun the command with --include-all flag to apply these migrations.

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

## Issue description
After merge, the pending migrations 20261013140000-20261013170000 (and the guard 20261014164220 behind them) sit before or around the live tip 20261013200007. Supabase's apply path rejects migrations inserted behind the remote tip unless run with `--include-all`, so the auto-apply on merge may fail and live stays drifted.

## Fix Focus Areas
- supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[1-18]
- docs/audit/live-drift-forensics-2026-08.md[1660-1665]

## Recommended Fix
Add a post-merge runbook step to the PR description, or to docs/database-remediation-plan.md. Watch the integration's run on merge. If it reports the out-of-order rejection, or migration history still shows 140000-170000 as local-only, first confirm with `supabase migration list --linked` that the pending set is exactly the four #3538 migrations plus 20261014164220. Then run `supabase db push --linked --project-ref <prod> --include-all` in an authorised window, and re-run the live-drift workflow to confirm #3542 closes.

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


Results up to commit fb71e2b ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (1)


Action required
1. Guard misses changed string literals 🔴 High 📜 Skill insight ≡ Correctness
Description
Removing source_md5 leaves definition_md5 as the only function-body pin, but its normalization
also removes whitespace inside quoted string literals. If a live function differs only in a
whitespace-bearing value such as a JSON key, the reconciliation guard accepts the changed behavior
instead of reporting a mismatch.
Code

supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[R12-14]

+-- Raw body bytes (source_md5) are not pinned: some bodies live holds use CRLF line
+-- endings that the recorded files do not, so a byte pin can only ever pass on live
+-- and fails every fresh chain replay. The body runs in begin/commit so SET LOCAL
Relevance

●●● Strong

Recent migration reviews accept findings where validation guards miss semantic schema or
function-definition discrepancies.

PR-#2547
PR-#3485

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed comment explicitly drops the raw body pin, while the remaining definition hash removes
every whitespace sequence from the function definition, including those within executable string
literals. The migrate skill calls for explicit validation of changed migrations and functions.

supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[12-15]
supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[154-169]
Skill: migrate

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 guard drops its raw function-body pin and relies on a definition hash that removes meaningful whitespace inside string literals.
## Fix Focus Areas
- supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[12-15]
- supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[154-168]
## Recommended Fix
Add a separate function-body hash that normalizes CRLF to LF without removing whitespace inside literals. Seal its expected values for both live and a fresh-chain replay, and retain the existing definition hash as an additional check.

ⓘ 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


Resolved findings

1. Production migrations may go unchecked ✓ Resolved
Description
The runbook runs supabase migration list --linked against the checkout's linked project, but
directs db push to an explicit production project ref. If the checkout is linked to staging, the
operator can confirm staging's pending set and then apply a different, unverified set of migrations
to production with --include-all.
Code

docs/audit/live-drift-forensics-2026-08.md[1667]

+**Post-merge runbook for the managed-ingestion reconciliation.** Watch the integration run after merge. If the apply reports an out-of-order rejection, or the live history still shows `20261013140000`–`20261013170000` as local-only, first run `supabase migration list --linked` and confirm that the pending set is exactly those four #3538 migrations plus `20261014164220`. In an authorised production window, run `supabase db push --linked --project-ref <prod> --include-all`, then rerun the live-drift workflow and confirm that #3542 closes.
Relevance

●●● Strong

The team accepted project-specific migration checks and rejected relying on a linked target before
production operations.

PR-#2250
PR-#2205

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new runbook specifies production only for the push, while the staging instructions demonstrate
that migration list --linked follows the checkout's staging link. The surrounding runbook states
that --include-all applies every locally absent version, making a check against the wrong project
insufficient.

docs/audit/live-drift-forensics-2026-08.md[1663-1667]
docs/staging-setup.md[35-40]
🌐 The CLI reference lists a project-ref option for migration list and describes the linked-project target.

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 preflight migration list can inspect a different linked project from the production target of the subsequent include-all push.
## Fix Focus Areas
- docs/audit/live-drift-forensics-2026-08.md[1667-1667]
## Recommended Fix
Pass `--project-ref <prod>` to `supabase migration list --linked` as well, and confirm its pending set before running the push.

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


2. Live migration history can stay unverified ✓ Resolved
Description
The new post-merge runbook checks the pending set before supabase db push but never reruns the
migration-history check afterward. If recorded history contains no-statement or otherwise
inconsistent rows, the drift workflow may pass while migration history remains unresolved, and the
runbook can incorrectly treat the reconciliation as complete.
Code

docs/audit/live-drift-forensics-2026-08.md[1667]

+**Post-merge runbook for the managed-ingestion reconciliation.** Watch the integration run after merge. If the apply reports an out-of-order rejection, or the live history still shows `20261013140000`–`20261013170000` as local-only, first run `supabase migration list --linked` and confirm that the pending set is exactly those four #3538 migrations plus `20261014164220`. In an authorised production window, run `supabase db push --linked --project-ref <prod> --include-all`, then rerun the live-drift workflow and confirm that #3542 closes.
Relevance

●●● Strong

Recent runbooks require explicit post-change verification of database state, not relying solely on
drift results.

PR-#3522
PR-#2250

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The runbook added in this PR instructs operators to inspect migration history before applying
migrations and then rerun the drift workflow, but it does not require the post-merge
migration-history gate. Repository guidance states that supabase migration list reads recorded
history only and that both drift and migration-history checks are required after migration changes;
the new validation guard also explicitly does not change migration history.

Align local and remote migration history
Verify a green live drift run
docs/audit/live-drift-forensics-2026-08.md[1667-1667]
supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql[3-5]
AGENTS.md[146-147]

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 post-merge runbook reruns the live drift workflow but does not require `check:migration-history` to pass after applying the pending migrations. This can leave migration-history inconsistencies undetected while the runbook treats the reconciliation as complete.

## Fix Focus Areas
- docs/audit/live-drift-forensics-2026-08.md[1667-1667]

## Recommended Fix
After `supabase db push --linked --include-all`, require both `npm run check:drift` and `npm run check:migration-history` to complete successfully, and state that the migration-history check must show no pending, local-only, remote-only, or preview blockers before closing the reconciliation.

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


Results up to commit 2314530 ⏭️ Skipped


No changes from previous review

Results up to commit c25d36b ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required

No findings for this group


Remediation recommended

No findings for this group


Informational

No findings for this group


Resolved findings

1. Staging checks mask live drift ✗ Dismissed
Description
The runbook treats supabase link as selecting the target for check:drift and
check:migration-history, but both npm checks use environment credentials independently of the CLI
link. If the checkout retains staging values, an operator can push migrations to production, pass
both checks against staging, and close live reconciliation without verifying production.
Code

docs/audit/live-drift-forensics-2026-08.md[1667]

+**Post-merge runbook for the managed-ingestion reconciliation.** Watch the integration run after merge. If the apply reports an out-of-order rejection, or the live history still shows `20261013140000`–`20261013170000` as local-only, first link the checkout to production (`supabase link --project-ref sjrfecxgysukkwxsowpy`) so every command below targets the same project. Then run `supabase migration list --linked` and `supabase db push --linked --include-all --dry-run`, and confirm both show exactly those four #3538 migrations plus `20261014164220` as pending. In an authorised production window, run `supabase db push --linked --include-all`, then rerun both `npm run check:drift` and `npm run check:migration-history`. Confirm that #3542 closes and that the migration-history check reports no pending, local-only, remote-only, or preview blockers before closing the reconciliation.
Relevance

●●● Strong

Accepted: production-targeting safeguards and explicit runbook verification have prior acceptance in
this file.

PR-#2205

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The release-readiness-review skill requires a target-database check for production, but the runbook
pins only the Supabase CLI link and says subsequent commands target the same project. The
migration-history check reads its URL and key from the environment, while the drift check validates
an environment-derived project and creates an environment-configured admin client; its project
validation explicitly accepts a declared staging project.

docs/audit/live-drift-forensics-2026-08.md[1667-1667]
scripts/check-drift.ts[494-518]
scripts/check-migration-history-alignment.ts[277-285]
scripts/check-migration-history-alignment.ts[264-267]
scripts/check-drift.ts[493-518]
src/lib/supabase/project.ts[126-142]
src/lib/supabase/admin.ts[60-70]
Skill: release-readiness-review

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 post-push npm checks read their target from environment variables, not the Supabase CLI link, so successful staging checks can be mistaken for production verification.

## Fix Focus Areas
- docs/audit/live-drift-forensics-2026-08.md[1667-1667]

## Recommended Fix
Update the runbook to require production `NEXT_PUBLIC_SUPABASE_URL` and a matching `SUPABASE_SERVICE_ROLE_KEY` for both npm checks. Require the operator to verify the configured production project identity before running or accepting either check, and require both production check results before closing the reconciliation.

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


Grey Divider

Qodo Logo

@codeant-ai

codeant-ai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 8d051527
Scan Time: 2026-10-15 12:58:09 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 0.0% 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 (2) · ☑ Fixed (2)

Grey Divider

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

Process — 2 fixed
  • ☑ Fixed: Repaired documents stay pending
  • ☑ Fixed: Pending live migrations may still not apply on merge

@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo Fixer

✅ Committed (2) · ☑ Fixed (2)

Grey Divider

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

Process — 2 fixed
  • ☑ Fixed: Production migrations may go unchecked
  • ☑ Fixed: Live migration history can stay unverified
  • ⏭ Skipped (1)

Owner approved the reseal on 2026-10-15. Both hashes were first sealed in
this PR, not on main. 20261013075944 is wrapped in begin/commit (how live
applied it) plus one grant live already holds. The guard 20261014164220 is
not yet on live. Neither edit changes the live database.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuYbdEGXeMntVA9KMgtAEx
…y check

Keeps the review bot's added migration-history step and runs every command
against the same linked production project.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuYbdEGXeMntVA9KMgtAEx

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb71e2b385

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/applied-migration-hashes.json Resolved
@BigSimmo
BigSimmo marked this pull request as ready for review October 15, 2026 11:27

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

@BigSimmo
BigSimmo marked this pull request as draft October 15, 2026 11:27
gitar-bot[bot]
gitar-bot Bot previously approved these changes Oct 15, 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 2314530

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23145308b8

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo Fixer

✅ Merged (0) · ☑ Fixed (0)

Process

  • ⏭ Skipped (1)

@BigSimmo
BigSimmo marked this pull request as ready for review October 15, 2026 11:37
@gitar-bot
gitar-bot Bot enabled auto-merge (squash) October 15, 2026 11:37

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

@qodo-code-review

Copy link
Copy Markdown
Contributor

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

@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo Fixer

✅ Committed (1) · ☑ Fixed (1)

Grey Divider

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

Process — 1 fixed
  • ☑ Fixed: Staging checks mask live drift
  • ⏭ Skipped (1)

@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)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c25d36b04b

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Owner Author

Unit coverage partition (1) failed on 8e0ccc9 with two 30 s timeouts in tests/production-dynamic-route-reachability.test.ts (13,373 other tests passed). This PR does not touch that test or the route tree it scans, and the same file passes locally on this head in 8 s (11 of 11). Treating it as runner load, not this PR's failure, and re-running the failed job once. If it fails again I will treat it as real.


Generated by Claude Code

@gitar-bot

gitar-bot Bot commented Oct 15, 2026

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

🔴 High risk · These Supabase migrations reconcile live managed-ingestion state and trigger pending schema and RLS changes, which could disrupt production data access or processing.

Records three already-live managed-ingestion migrations on main, with a validation-only guard migration, so migration history matches the live database. Two replay-only edits were resealed with owner approval and change nothing on live. No open findings remain; the resolved items cover the resealed migration hashes and the --include-all route for #3538's out-of-order versions, and four others were closed without a fix in this PR.

✅ 6 closed
✅ Bug: Edited migrations no longer match sealed hashes; immutability check fails

📄 supabase/migrations/20261013075944_administrator_txt_fenced_runtime_cutover.sql:1-8 📄 supabase/migrations/20261013075944_administrator_txt_fenced_runtime_cutover.sql:5648 📄 supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql:12-15 📄 supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql:23 📄 supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql:280 📄 supabase/applied-migration-hashes.json:311 📄 supabase/applied-migration-hashes.json:314
Commit 8cadeda edited both migration files but did not update supabase/applied-migration-hashes.json. It added a begin/commit wrapper and a service_role grant to 20261013075944, and it removed source_md5 and added begin/commit in 20261014164220. The manifest still has the dd709e6 hashes (6a8cf89b… and 548b80f4…), while the LF-normalised files now hash to c6b2cd5a… and 8ffd7529…. Running node scripts/check-migration-immutability.mjs on this head fails with "edited an already-shipped migration" for both files, so the PR's claim that check:migration-immutability passes no longer holds, and the PR-policy and verify gates will go red.

This also breaks the PR's stated premise. 20261013075944 is no longer a byte-for-byte copy of what live recorded on 2026-10-13, so main now describes a migration body that live never ran. That is the exact drift the immutability guard is there to prevent.

To fix this, either keep 20261013075944 byte-identical to live and fix replay some other way (for example, a replay-only wrapper or the CI replay harness), or deliberately reseal with ALLOW_MIGRATION_RESEAL=true npm run migrations:reseal. If you reseal, record the reason in the commit and correct the "unchanged copies / byte for byte" wording in the PR body. The guard file 20261014164220 is not on live yet, so resealing it is just a normal update.

✅ Bug: #3538's migrations sort before live's new tip; db push may refuse them

📄 supabase/migrations/20261013200007_managed_native_pdf_terminal_append.sql:1 📄 supabase/migrations/20261013075944_administrator_txt_fenced_runtime_cutover.sql:1 📄 supabase/migrations/20261014164220_validate_managed_ingestion_historical_reconciliation.sql:9-10 📄 supabase/applied-migration-hashes.json:310-314
After this merges, live's newest recorded version will be 20261013200007. The four #3538 migrations that are still pending (20261013140000, 150000, 160000, 170000) all sort before it, and so does 20261013075944 relative to them. The repo's own forensics in docs/audit/live-drift-forensics-2026-08.md (around lines 1640-1666) record that the Supabase CLI refuses exactly this case with LegacyDbPushMissingRemoteError ("Found local migration files to be inserted before the last migration on remote database") unless --include-all is passed. The same document says the GitHub integration runs the CLI's push. If the integration does not pass --include-all, the merge applies nothing, or at best only the guard 20261014164220 (which pins the final FORCE RLS state and would then raise). Live drift then stays red, which contradicts the PR's claim that the integration has "only #3538's four migrations and the guard left to apply".

Fix: before the approved window, confirm how the integration treats out-of-order versions. If it does not include them, plan an operator supabase db push --linked --include-all --dry-run to confirm the pending set is exactly the five files, then the real push. Write that step into the rollout section, or re-version #3538's four never-applied migrations after 20261013200007, using the history-edit approval.

Closed: Security: Recreated SECURITY DEFINER repair function loses its revoke/grant ACL

📄 supabase/migrations/20261014170000_recheck_managed_quality_after_repair.sql:6-9 📄 supabase/migrations/20261014170000_recheck_managed_quality_after_repair.sql:65
ALTER ... RENAME takes the existing ACL (postgres, service_role only) with it to repair_enrichment_quality_batch_legacy. The new repair_enrichment_quality_batch(integer) is created fresh, so it gets PUBLIC EXECUTE plus Supabase's default anon/authenticated grants in public. Because it is SECURITY DEFINER, any anonymous PostgREST caller can then invoke /rpc/repair_enrichment_quality_batch. That call runs the legacy repair, mass-rewrites document_index_quality, and completes ingestion_jobs on the live clinical database. The guard and drift manifest pin anon_execute:false, authenticated_execute:false (20261014164220 line 103). Add the same revoke/grant pair that schema.sql uses after the owner to statement.

Closed: Bug: Recheck marks managed-owned and out-of-batch documents good

📄 supabase/migrations/20261014170000_recheck_managed_quality_after_repair.sql:22-36 📄 supabase/migrations/20261013144347_managed_generation_quality_repair_ownership.sql:46-60
The legacy function picks at most p_limit (max 100) candidates. It also deliberately skips documents whose current generation is owned by ingestion_generation_evidence.candidates, which is the whole point of 20261013144347. The new recheck applies neither limit. It forces extraction_quality='good' and coverage values of 1.0 on every indexed, non-good document that has the artifacts, and flips the latest job for those documents from pending to completed. So a single call takes over quality and job state for documents the managed fenced worker owns, and the update has no bound under the 30s statement timeout. Fix: restrict repair_quality_rechecked to the documents the legacy call processed, or at least apply the same managed-ownership not exists filter and the same limit.

Closed: Bug: Drift manifest/schema.sql not updated for the new function pair

📄 supabase/migrations/20261014170000_recheck_managed_quality_after_repair.sql:6-9 📄 supabase/drift-manifest.json:19726
The PR says the manifest now matches live. This migration replaces the body of repair_enrichment_quality_batch(integer), but supabase/drift-manifest.json (around line 19726) still pins def_hash dcda90c6. Neither the manifest nor supabase/schema.sql knows about repair_enrichment_quality_batch_legacy. Once this applies, the post-merge check:drift will report a hash mismatch and an extra function. That keeps live drift (#3542) red, which defeats the purpose of the PR. Regenerate schema.sql and the manifest, or drop this migration from the reconciliation PR.

...and 1 more closed from earlier reviews

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 6 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.

Was this helpful? React with 👍 / 👎 | Gitar

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 8d05152

@gitar-bot
gitar-bot Bot merged commit 0fa194b into main Oct 15, 2026
37 of 38 checks passed
@gitar-bot
gitar-bot Bot deleted the claude/project-thread-sr3mdk branch October 15, 2026 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔴 Large blast radius size:XXL This PR changes 1000+ lines, ignoring generated files 🕐 40+ Minutes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants