Skip to content

fix: complete repository audit remediation#715

Merged
BigSimmo merged 13 commits into
mainfrom
codex/audit-remediation-merge-20260717
Jul 17, 2026
Merged

fix: complete repository audit remediation#715
BigSimmo merged 13 commits into
mainfrom
codex/audit-remediation-merge-20260717

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • Bound PDF extraction resources and filter document search to committed generations.
  • Require explicit publication approvals and transactional document delete/retry exclusion.
  • Fail closed on unsafe Supabase default ACLs, with local bootstrap, catalog fixtures, and operator verification tooling.
  • Integrate the current main PR-policy hardening without dropping either review-ledger addition.

Verification

  • npm run verify:pr-local — passed on the audit remediation head: formatting, lint, typecheck, 2,628 tests, production build, client-secret scan, and offline RAG fixtures.
  • npm run verify:cheap — passed after review fixes: 276 files and 2,629 tests.
  • Focused Python budget tests — 4/4 passed.
  • Disposable Docker schema replay and publication/delete/ACL SQL fixtures — passed.
  • npm run check:pr-policy, npm run check:github-actions, and npm run check:ci-scope — passed after current-main integration.
  • Final combined-tree npm run verify:pr-local rerun was not run to completion because the repository lock is held by another worktree Chromium run; hosted checks are running on the combined head.
  • UI verification not run: this PR does not change UI, routing, styling, or browser behavior.

Risk and rollout

  • Risk: medium; this changes ingestion limits, document lifecycle transactions, publication governance, database privileges, and migration replay behavior. Fail-closed checks and transactional fixtures reduce the primary risks.
  • Rollback: revert this PR before applying dependent app/worker changes; if migrations have been applied, use a reviewed forward migration rather than destructive schema rollback.
  • Provider or production effects: None. No live migration, provider audit, deployment, or production-data operation was performed.

Database migrations must deploy before dependent app/worker code. The default-ACL assertion is intentionally last and blocks deployment until the operator-owned Supabase ACL remediation is complete. Historical public rows are audited but are not automatically changed.

Clinical Governance Preflight

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

Notes

  • The external Supabase Preview is expected to remain blocked until separately authorized provider-side default-ACL remediation is completed.
  • JavaScript PDFParse fallback process isolation remains a separate follow-up because it requires a broader worker design; aggregate fallback limits remain enforced.

Summary by CodeRabbit

  • New Features

    • Added manifest-based publication controls with approval evidence and validation.
    • Added PDF extraction resource limits for pages, text, images, processing time, and output size.
    • Added safeguards for document deletion and ingestion-job retries during concurrent activity.
    • Added tools to audit publication approvals and verify database access settings.
  • Bug Fixes

    • Reindex requests now return a clear conflict when a document is deleted mid-operation.
    • Uploaded artifacts are cleaned up when downstream persistence fails.
  • Documentation

    • Updated operational records and deployment verification guidance.

BigSimmo added 7 commits July 17, 2026 20:02
Port the reviewed containment fixes onto current main without changing external API contracts. Drift manifest regeneration remains part of the final remediation verification.
Replace broad public promotion with append-only operator evidence, explicit manifest confirmation, and an atomic service-role publication RPC. Historical public rows remain audit-only.
Move delete safety, cleanup snapshots, trace cleanup, and parent deletion into one RPC. Return normal 409s for delete/reindex races and compensate failed image-row persistence.
Assert effective supabase_admin defaults from pg_default_acl and acldefault, block unsafe applies with operator remediation, and add an explicitly gated read-only verifier.
@supabase

supabase Bot commented Jul 17, 2026

Copy link
Copy Markdown

Updates to Preview Branch (codex/audit-remediation-merge-20260717) ↗︎

Deployments Status Updated
Database Fri, 17 Jul 2026 14:10:51 UTC
Services Fri, 17 Jul 2026 14:10:51 UTC
APIs Fri, 17 Jul 2026 14:10:51 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 Fri, 17 Jul 2026 14:10:54 UTC
Migrations Fri, 17 Jul 2026 14:10:57 UTC
Seeding ⏸️ Fri, 17 Jul 2026 14:10:43 UTC
Edge Functions ⏸️ Fri, 17 Jul 2026 14:10:43 UTC

❌ Branch Error • Fri, 17 Jul 2026 14:10:57 UTC

ERROR: Unsafe supabase_admin default privileges; migration blocked. (SQLSTATE 42501)
{"safe": false, "entries": ["function:PUBLIC:execute", "function:anon:execute", "function:authenticated:execute", "function:postgres:execute", "function:service_role:execute", "function:supabase_admin:execute", "sequence:anon:select", "sequence:anon:update", "sequence:anon:usage", "sequence:authenticated:select", "sequence:authenticated:update", "sequence:authenticated:usage", "sequence:postgres:select", "sequence:postgres:update", "sequence:postgres:usage", "sequence:service_role:select", "sequence:service_role:update", "sequence:service_role:usage", "sequence:supabase_admin:usage", "table:anon:delete", "table:anon:insert", "table:anon:maintain", "table:anon:references", "table:anon:select", "table:anon:trigger", "table:anon:truncate", "table:anon:update", "table:authenticated:delete", "table:authenticated:insert", "table:authenticated:maintain", "table:authenticated:references", "table:authenticated:select", "table:authenticated:trigger", "table:authenticated:truncate", "table:authenticated:update", "table:postgres:delete", "table:postgres:insert", "table:postgres:maintain", "table:postgres:references", "table:postgres:select", "table:postgres:trigger", "table:postgres:truncate", "table:postgres:update", "table:service_role:delete", "table:service_role:insert", "table:service_role:maintain", "table:service_role:references", "table:service_role:select", "table:service_role:trigger", "table:service_role:truncate", "table:service_role:update", "table:supabase_admin:delete", "table:supabase_admin:insert", "table:supabase_admin:maintain", "table:supabase_admin:references", "table:supabase_admin:select", "table:supabase_admin:trigger", "table:supabase_admin:truncate", "table:supabase_admin:update"], "role_exists": true, "schema_exists": true}
At statement: 3
do $$
declare
  v_status jsonb;
begin
  if not exists (select 1 from pg_catalog.pg_roles where rolname = 'supabase_admin') then
    raise notice 'role supabase_admin does not exist; default-privilege assertion is not applicable';
    return;
  end if;

  begin
    -- Local/Superuser-capable environments can assume the target role even
    -- when the migration role cannot use ALTER DEFAULT PRIVILEGES FOR ROLE
    -- directly. Hosted environments that cannot assume it fall through to the
    -- catalog assertion and block with operator instructions.
    execute 'set local role supabase_admin';
    -- Revokes must be global: per-schema ACLs cannot subtract privileges from
    -- built-in or previously granted global defaults.
    alter default privileges for role supabase_admin
      revoke all privileges on tables from public, anon, authenticated, service_role;
    alter default privileges for role supabase_admin in schema public
      revoke all privileges on tables from public, anon, authenticated, service_role;
    alter default privileges for role supabase_admin
      revoke all privileges on sequences from public, anon, authenticated, service_role;
    alter default privileges for role supabase_admin in schema public
      revoke all privileges on sequences from public, anon, authenticated, service_role;
    alter default privileges for role supabase_admin
      revoke execute on functions from public, anon, authenticated, service_role;
    alter default privileges for role supabase_admin in schema public
      revoke execute on functions from public, anon, authenticated, service_role;
    alter default privileges for role supabase_admin in schema public
      grant select, insert, update, delete on tables to service_role;
    alter default privileges for role supabase_admin in schema public
      grant usage, select on sequences to service_role;
    alter default privileges for role supabase_admin in schema public
      grant execute on functions to service_role;
    execute 'reset role';
  exception when insufficient_privilege then
    begin execute 'reset role'; exception when others then null; end;
    raise notice 'current role % cannot remediate supabase_admin default privileges; asserting the catalog postcondition', current_user;
  end;

  v_status := public.default_privileges_status('supabase_admin', 'public');
  if not coalesce((v_status->>'safe')::boolean, false) then
    raise exception using
      errcode = '42501',
      message = 'Unsafe supabase_admin default privileges; migration blocked.',
      detail = v_status::text,
      hint = E'Run these six statements as supabase_admin, then retry the migration:\n'
        'DO $remediate$ BEGIN ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin REVOKE ALL PRIVILEGES ON TABLES FROM PUBLIC, anon, authenticated, service_role; ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL PRIVILEGES ON TABLES FROM PUBLIC, anon, authenticated, service_role; END $remediate$;\n'
        'DO $remediate$ BEGIN ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin REVOKE ALL PRIVILEGES ON SEQUENCES FROM PUBLIC, anon, authenticated, service_role; ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE ALL PRIVILEGES ON SEQUENCES FROM PUBLIC, anon, authenticated, service_role; END $remediate$;\n'
        'DO $remediate$ BEGIN ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC, anon, authenticated, service_role; ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC, anon, authenticated, service_role; END $remediate$;\n'
        'ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO service_role;\n'
        'ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO service_role;\n'
        'ALTER DEFAULT PRIVILEGES FOR ROLE supabase_admin IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO service_role;';
  end if;
end;
$$

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

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds manifest-controlled document publication, database-backed deletion and retry coordination, PDF extraction resource budgets, default-ACL verification, committed-generation search filtering, storage compensation, and related migrations, scripts, tests, schema typings, and operational documentation.

Changes

Publication governance

Layer / File(s) Summary
Manifest validation and publication orchestration
src/lib/publication-manifest.ts, scripts/promote-public-documents-batch.ts, scripts/audit-public-document-approvals.ts, package.json
Publication manifests are validated, hashed, confirmation-gated, audited, and submitted through approval records and the publish_approved_documents RPC.
Database publication guards and typings
supabase/migrations/20260717131000_guard_document_publication_approval.sql, supabase/schema.sql, supabase/drift-manifest.json, src/lib/supabase/database.types.ts
Append-only approval evidence, ownership-transition validation, artifact ownership checks, and service-role-only publication execution are added with matching schema metadata and typings.
Publication verification
scripts/sql/verify-publication-approval.sql, tests/publication-manifest.test.ts, tests/supabase-schema.test.ts
Manifest parsing, publication transitions, ownership preservation, and approval immutability are verified.

Serialized deletion, retry, and reindex races

Layer / File(s) Summary
RPC-backed deletion and retry coordination
supabase/migrations/20260717132000_delete_document_if_idle.sql, src/app/api/documents/[id]/route.ts, src/app/api/ingestion/jobs/[id]/retry/route.ts
Deletion and retry locking, job checks, cleanup bookkeeping, and state transitions move into validated RPC flows.
Reindex deletion-race handling
src/app/api/documents/[id]/reindex/route.ts, src/app/api/documents/bulk/reindex/route.ts, tests/private-access-routes.test.ts
Foreign-key enqueue failures caused by concurrent deletion return HTTP 409 responses and are covered by single and bulk route tests.
Database race verification
scripts/sql/verify-delete-reindex-exclusion.sql, tests/supabase-schema.test.ts
Transactional fixtures verify retry ordering, active-job deletion blocking, cleanup snapshots, and delete-first ingestion exclusion.

PDF extraction and storage controls

Layer / File(s) Summary
Shared extraction budget model
src/lib/extractors/pdf-extraction-budget.ts, src/lib/extractors/document.ts, src/lib/types.ts, src/lib/ingestion.ts
TypeScript extraction tracks pages, text, artifacts, result size, deadlines, and resource-specific errors across Python and fallback paths.
Python extractor enforcement
worker/python/extract_pdf_assets.py
OCR, rendering, embedded artifacts, text, page counts, and serialized output are bounded by configurable extraction limits, with usage reported in the result.
Budget validation tests
tests/pdf-extraction-budget.test.ts, worker/python/test_extract_pdf_assets_budget.py
Tests cover budget boundaries, process-tree termination, cleanup, fallback consistency, render geometry, OCR timeouts, and non-retryable resource errors.
Uploaded-artifact compensation
src/lib/storage-upload-compensation.ts, worker/main.ts, tests/storage-upload-compensation.test.ts
Failed image persistence removes the already-uploaded storage object and preserves cleanup errors alongside the original persistence failure.

ACL and search hardening

Layer / File(s) Summary
Default privilege bootstrap and assertion
supabase/roles.sql, supabase/migrations/20260717161000_assert_supabase_admin_default_privileges.sql, scripts/check-default-acl.ts, scripts/sql/verify-default-acl-catalog.sql
Default privileges are bootstrapped and checked through catalog-derived, fail-closed ACL status.
Replay and search integration
scripts/generate-drift-manifest.ts, .github/workflows/ci.yml, supabase/migrations/20260717130000_filter_search_document_chunks_committed_generation.sql, supabase/schema.sql, supabase/drift-manifest.json
Drift replay and CI apply role defaults, while document chunk search restricts results to committed generations with service-role-only execution.
Schema and operational validation
tests/supabase-schema.test.ts, tests/retrieval-owner-filter-guard.test.ts, docs/process-hardening.md, docs/operator-backlog.md
Replay guards validate ACL behavior, committed-generation filtering, migration ordering, and updated operational verification instructions.

Operational records

Layer / File(s) Summary
Review and deployment records
docs/branch-review-ledger.md
The review ledger records the repository audit and subsequent remediation review outcomes.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • BigSimmo/Database#465: Both changes update validated extraction payload handling in src/lib/extractors/document.ts.
  • BigSimmo/Database#640: Both changes relate to committed-generation semantics used by public.search_document_chunks.
  • BigSimmo/Database#565: Both changes harden execution privileges for public.search_document_chunks.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: completing repository audit remediation.
Description check ✅ Passed The description follows the required template and includes summary, verification, risk, clinical governance, and notes sections with substantive detail.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/audit-remediation-merge-20260717

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

@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: ac7fbdb1bc

ℹ️ 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/migrations/20260717161000_assert_supabase_admin_default_privileges.sql Outdated
@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: ac7fbdb1bc

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

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

CI triage

CI failed on this PR. Automated classification of the 2 failed job(s):

  • Migration replayneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • PR requiredneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.

Compared with main CI run #2769 (success).

Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger.

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
worker/python/extract_pdf_assets.py (1)

850-877: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Mark pages when required OCR did not produce text.

When should_ocr_page() is true but rendering is skipped or OCR fails, the page is returned without needsOcr. Downstream quality checks can therefore treat incomplete clinical content as healthy.

Proposed fix
         text = page.get_text("text", sort=True) or ""
         ocr_used = False
+        needs_ocr = False
         image_coverage = page_image_coverage_ratio(page)

         if should_ocr_page(text, page):
             ocr_text, ocr_warning = maybe_ocr_page(page, budget)
             if ocr_warning:
                 warnings.append(ocr_warning)
             if ocr_text.strip():
                 text = merge_ocr_text(text, ocr_text)
                 ocr_used = True
+            else:
+                needs_ocr = True

         budget.add_text(text)
         pages.append(
             {
                 "pageNumber": page_number,
                 "text": text,
                 "ocrUsed": ocr_used,
+                "needsOcr": needs_ocr,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@worker/python/extract_pdf_assets.py` around lines 850 - 877, Update the
page-processing flow around should_ocr_page and maybe_ocr_page to track when OCR
is required but produces no usable text, including skipped or failed rendering.
Mark that page’s output with needsOcr while preserving the existing merge
behavior and leaving pages with successful OCR or no OCR requirement unchanged.
src/lib/extractors/document.ts (1)

226-244: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Keep the PDFParse fallback under the same killable boundary. It runs in-process on non-resource Python failures, so a malformed PDF can still bypass the timeout and isolation that protect the main extractor. Run this path in the same killable worker/child, or fail closed outside developer-only setups.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/extractors/document.ts` around lines 226 - 244, The PDFParse fallback
in the document extraction flow must not execute in the main process outside
developer-only setups. Move the parser creation and the getText/getImage
processing around PDFParse into the same killable worker or child boundary used
by the primary extractor, or fail closed when that boundary is unavailable;
preserve the existing page extraction and budget tracking behavior within the
protected path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@supabase/migrations/20260717131000_guard_document_publication_approval.sql`:
- Line 14: Remove decision from the unique key for the publication approval
entry in
supabase/migrations/20260717131000_guard_document_publication_approval.sql:14
and apply the same canonical-schema correction in supabase/schema.sql:7542.
Regenerate the corresponding unique-index snapshot at
supabase/drift-manifest.json:5115-5119 and constraint snapshot at
supabase/drift-manifest.json:7391-7394 so they match the corrected key.
- Around line 84-87: Update the documents_require_publication_approval trigger
and guard_document_publication_transition function in
supabase/migrations/20260717131000_guard_document_publication_approval.sql
(lines 84-87) to cover INSERT operations and reject inserts with a NULL owner_id
unless equivalent approval evidence is present; mirror the same trigger/function
correction in supabase/schema.sql (lines 7612-7615), then regenerate the trigger
snapshot in supabase/drift-manifest.json (lines 6270-6274).

In `@supabase/migrations/20260717132000_delete_document_if_idle.sql`:
- Around line 30-55: Update the retry queueing flow to use a transaction/RPC
that acquires the same parent document lock as the deletion routine before
changing an existing job to pending. Perform the job status change and document
update atomically, and verify the document row still exists before returning
success. Align this protocol with the v_active_job handling in the deletion
routine so retries and deletion cannot race.

In
`@supabase/migrations/20260717161000_assert_supabase_admin_default_privileges.sql`:
- Around line 65-75: Update the default-privilege verifier predicate and
remediation in
supabase/migrations/20260717161000_assert_supabase_admin_default_privileges.sql
(lines 65-75) to reject and revoke table:PUBLIC:* and sequence:PUBLIC:* entries,
including corresponding hints. Mirror these predicate and remediation changes in
supabase/schema.sql (lines 7938-7948). In scripts/sql/drift-replay-scaffold.sql
(lines 79-90), revoke PUBLIC table and sequence defaults during replay setup. In
scripts/sql/verify-default-acl-catalog.sql (lines 46-58), add isolated negative
cases covering PUBLIC table and sequence defaults.

---

Outside diff comments:
In `@src/lib/extractors/document.ts`:
- Around line 226-244: The PDFParse fallback in the document extraction flow
must not execute in the main process outside developer-only setups. Move the
parser creation and the getText/getImage processing around PDFParse into the
same killable worker or child boundary used by the primary extractor, or fail
closed when that boundary is unavailable; preserve the existing page extraction
and budget tracking behavior within the protected path.

In `@worker/python/extract_pdf_assets.py`:
- Around line 850-877: Update the page-processing flow around should_ocr_page
and maybe_ocr_page to track when OCR is required but produces no usable text,
including skipped or failed rendering. Mark that page’s output with needsOcr
while preserving the existing merge behavior and leaving pages with successful
OCR or no OCR requirement unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7a9b505b-ea3b-4709-91af-950c23a7dff1

📥 Commits

Reviewing files that changed from the base of the PR and between 220de89 and ac7fbdb.

📒 Files selected for processing (37)
  • docs/branch-review-ledger.md
  • docs/operator-backlog.md
  • docs/process-hardening.md
  • package.json
  • scripts/audit-public-document-approvals.ts
  • scripts/check-default-acl.ts
  • scripts/promote-public-documents-batch.ts
  • scripts/promote-public-documents.ts
  • scripts/sql/drift-replay-scaffold.sql
  • scripts/sql/verify-default-acl-catalog.sql
  • scripts/sql/verify-delete-reindex-exclusion.sql
  • scripts/sql/verify-publication-approval.sql
  • src/app/api/documents/[id]/reindex/route.ts
  • src/app/api/documents/[id]/route.ts
  • src/app/api/documents/bulk/reindex/route.ts
  • src/lib/extractors/document.ts
  • src/lib/extractors/pdf-extraction-budget.ts
  • src/lib/ingestion.ts
  • src/lib/publication-manifest.ts
  • src/lib/storage-upload-compensation.ts
  • src/lib/supabase/database.types.ts
  • src/lib/types.ts
  • supabase/drift-manifest.json
  • supabase/migrations/20260717130000_filter_search_document_chunks_committed_generation.sql
  • supabase/migrations/20260717131000_guard_document_publication_approval.sql
  • supabase/migrations/20260717132000_delete_document_if_idle.sql
  • supabase/migrations/20260717161000_assert_supabase_admin_default_privileges.sql
  • supabase/schema.sql
  • tests/pdf-extraction-budget.test.ts
  • tests/private-access-routes.test.ts
  • tests/publication-manifest.test.ts
  • tests/retrieval-owner-filter-guard.test.ts
  • tests/storage-upload-compensation.test.ts
  • tests/supabase-schema.test.ts
  • worker/main.ts
  • worker/python/extract_pdf_assets.py
  • worker/python/test_extract_pdf_assets_budget.py
💤 Files with no reviewable changes (2)
  • scripts/promote-public-documents.ts
  • tests/retrieval-owner-filter-guard.test.ts

Comment thread supabase/migrations/20260717131000_guard_document_publication_approval.sql Outdated
Comment thread supabase/migrations/20260717132000_delete_document_if_idle.sql
@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.

@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

Copy link
Copy Markdown
Owner Author

Review follow-up: the Python extractor now reports needsOcr when required OCR produces no text, with focused budget tests passing. The separate suggestion to move the in-process JavaScript PDFParse fallback into a killable worker is deferred: that requires a broader worker-isolation design and is not a safe, scoped change for this remediation merge. Existing fallback aggregate limits remain in place; this residual CPU-preemption risk should be tracked separately.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/sql/verify-publication-approval.sql`:
- Around line 63-77: Update the exception handling around the direct insert
fixture in the publication-guard verification block to assert the trigger’s
specific expected error message, rather than accepting any insertion failure.
Preserve re-raising the success sentinel and make unrelated SQL errors fail the
test, matching the existing specific-error assertion used for unique_violation
below.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 160f2c48-8156-4b71-abe9-2ae079e47abe

📥 Commits

Reviewing files that changed from the base of the PR and between a973931 and 00a1794.

📒 Files selected for processing (14)
  • scripts/sql/verify-default-acl-catalog.sql
  • scripts/sql/verify-delete-reindex-exclusion.sql
  • scripts/sql/verify-publication-approval.sql
  • src/app/api/ingestion/jobs/[id]/retry/route.ts
  • src/lib/supabase/database.types.ts
  • supabase/drift-manifest.json
  • supabase/migrations/20260717131000_guard_document_publication_approval.sql
  • supabase/migrations/20260717132000_delete_document_if_idle.sql
  • supabase/migrations/20260717161000_assert_supabase_admin_default_privileges.sql
  • supabase/roles.sql
  • supabase/schema.sql
  • tests/private-access-routes.test.ts
  • tests/supabase-schema.test.ts
  • worker/python/extract_pdf_assets.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • supabase/roles.sql
  • src/lib/supabase/database.types.ts
  • supabase/migrations/20260717161000_assert_supabase_admin_default_privileges.sql
  • tests/supabase-schema.test.ts
  • supabase/drift-manifest.json
  • supabase/migrations/20260717131000_guard_document_publication_approval.sql
  • worker/python/extract_pdf_assets.py

Comment thread scripts/sql/verify-publication-approval.sql
@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.

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

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@supabase/roles.sql`:
- Around line 79-116: Update the v_safe predicate to explicitly allow only
supabase_admin and the permitted service_role entries, rejecting grants to every
other role, including login or inherited roles. Validate the structured exploded
rows rather than relying on parsing v_entries, while preserving the existing
exact service_role table, sequence, and function allowlists.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 431cd927-5231-4d2c-8ad7-f80777067bbc

📥 Commits

Reviewing files that changed from the base of the PR and between 00a1794 and 39c52df.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • docs/process-hardening.md
  • supabase/roles.sql
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/process-hardening.md

Comment thread supabase/roles.sql
@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.

@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 merged commit 6fa2b30 into main Jul 17, 2026
32 of 33 checks passed
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.

1 participant