Skip to content

Audit remediation wave 1: catalog rate limits, public-doc redaction, ingestion recovery#680

Merged
BigSimmo merged 13 commits into
mainfrom
claude/rag-scalability-review-x0s55l
Jul 14, 2026
Merged

Audit remediation wave 1: catalog rate limits, public-doc redaction, ingestion recovery#680
BigSimmo merged 13 commits into
mainfrom
claude/rag-scalability-review-x0s55l

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the code-level findings from the 2026-07-14 repository audit handover (docs/rag-scalability-wip-review-handover / audit-remediation-plan-2026-07-14.md). This is a focused code-hardening wave; operator/legal findings (M1–M3, M5, release evals) are out of scope for code and are not addressed here.

Security / API

  • M4/C1 — anonymous catalog rate-limit bypass. The medications, registry, and differentials list routes short-circuited to the full seed catalog (~MBs) before the limiter whenever a request had no session cookie/bearer. They now always resolve access and pass the registry limiter; a tighter anonymous registry allowance (60/min) is added. publicAccessContext still skips the Supabase auth round-trip for truly anonymous callers, so the hot path stays cheap — it just can no longer be used as an unauthenticated high-volume egress lever. The single-record [slug] detail routes are intentionally left as-is (bounded payloads, much weaker lever).
  • S1/D1 — public-document DTO leak. withOwnerReadScope returns PUBLIC (owner_id IS NULL) documents to an authenticated caller alongside their own. The document list route now redacts owner-internal storage fields (storage_path, content_hash, source_path, import_batch_id, error_message) on non-owned rows while keeping shared governance metadata. The document detail route now gates the full owner projection (raw metadata, index health, image storage paths) on ownership rather than mere authentication, so an authed non-owner gets the same redacted view an anonymous caller already gets. Redaction helpers added to src/lib/public-api-access.ts.
  • S10/D5 — raw DB error in bulk edits. The bulk route returned raw per-document error.message (constraint names, column details) in its results array. It now logs the sanitized detail server-side (safeErrorLogDetails) and returns a generic per-document failure message.
  • S11/H6 — demo jobs on partial misconfig. /api/jobs served unauthenticated demo jobs when the server env was partially missing (isDemoMode() false but createAdminClient throws), masking the misconfiguration. It now surfaces a real error.

Ingestion

  • I1/E1 — unreachable commit code. Removed dead post-throw statements in commitDocumentIndexGeneration and the fully-orphaned client-side deleteStaleIndexGenerationRows fallback (plus its now-unused types). The commit RPC upserts index quality and prunes stale/legacy generation rows atomically server-side (20260702000000 + lease-fenced by 20260713062125); the worker only surfaces failures (fail closed). Zero runtime-behavior change. The worker-visual-capture test's two lexical assertions that pinned the dead function were replaced with an assertion of the actual fail-closed behavior.
  • I2/E2 — recovery double-retry crash (real bug). When a document had both a pending and a failed job, buildIngestionRecoveryPlan emitted two retry actions and tried to set both rows to pending, tripping ingestion_jobs_one_open_per_document_uidx and leaving the queue in a self-perpetuating stall that re-crashed on every run. It now requeues only the first recoverable job per document, supersedes the rest, and orders supersedes before retries so an open sibling is always closed before a retry flips a row to pending. Fixes both consumers (recover-ingestion-queue.ts, reindex.ts) via the shared planner.

I3/E3 (reindex eval gate unwired) was verified to be staged-by-design per docs/reindex-runbook.md / docs/reindex-shadow-harness-design.md and is intentionally left unchanged.

Verification

  • npm run verify:cheap — runtime, GitHub-Actions pin, sitemap, brand, type-scale, icon-scale checks, lint, typecheck, and test (2417 passed, 3 skipped) all pass offline.
  • Prettier --check clean on all changed files.
  • npm run verify:pr-local — not run in this environment (adds production build / client-bundle scan). No provider-backed gates were run (API-confirmation boundary).

New/updated regression tests: anonymous catalog 429 + limiter-consulted (medications, registry); authed-non-owner public-doc redaction for list + detail, plus owner-keeps-fields; bulk raw-error non-leak; recovery pending+failed dedup/ordering; worker fail-closed assertion.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use — unchanged (no answer-generation change)
  • No patient-identifiable document workflow was introduced or expanded
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy) — unchanged (no env change)
  • Service-role keys and private document access remain server-only — tightened: non-owners can no longer read owner storage internals of public documents (S1)
  • Demo/synthetic content remains clearly separated from real clinical sources — tightened: /api/jobs no longer serves demo jobs into a misconfigured production (S11)
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative — unchanged
  • Deployment classification/TGA SaMD impact — no clinical decision-support behavior changed

Notes

  • Scope deliberately excludes operator/legal findings (M1 overseas processing, M2 secret verification, M3 release evals, M5 backlog reconciliation) which cannot be resolved in code, and the remaining lower-priority P2/P3 items (envelope standardization, write-route rate limits, a11y polish, CI-scope, etc.) which can follow in subsequent themed waves.
  • One small list/detail asymmetry is intentional: the list keeps shared governance metadata on public rows (badges), the detail view redacts it (owner diagnostics) — both close the flagged storage_path/content_hash leak.

🤖 Generated with Claude Code


Generated by Claude Code

Summary by CodeRabbit

  • Security & Privacy
    • Anonymous/public catalog and seed-detail endpoints now consistently resolve access and then apply registry rate limits.
    • Document listings and detail views redact non-owner internal fields (including nested label/summary metadata); owners see full fields.
    • Bulk document edits sanitize per-item failures to avoid exposing raw database constraint details.
  • Reliability
    • Ingestion recovery is per-document: it preserves one active job, supersedes obsolete siblings first, and retries only when needed.
    • Index-generation commit now relies solely on the server RPC, removing legacy/stale cleanup behavior.
    • “Missing environment” no longer falls back to demo jobs.
  • Tests
    • Added/updated coverage for rate limiting, redaction behavior, bulk error sanitization, ingestion recovery ordering, and worker RPC failure handling.

claude added 2 commits July 14, 2026 19:05
…ion recovery

Addresses the code-level findings from the 2026-07-14 repository audit handover.

Security / API:
- M4/C1: anonymous curated-catalog GETs (medications, registry, differentials)
  no longer short-circuit before the limiter. Every caller now resolves access
  and passes the registry limiter; anonymous requests get a tighter registry
  allowance. Prevents using the public catalog endpoints as an unauthenticated
  high-volume egress lever.
- S1/D1: authenticated callers can read PUBLIC (owner_id IS NULL) documents they
  do not own via withOwnerReadScope. The document list and detail routes now
  redact owner-internal storage fields (storage_path, content_hash, source_path,
  import_batch_id, error_message) on non-owned rows, and the detail route gates
  the full owner projection (raw metadata, index health, image storage paths) on
  ownership rather than mere authentication.
- S10/D5: the bulk edit route returned raw per-document DB error text (constraint
  names, column details). It now logs the sanitized detail server-side and
  returns a generic per-document failure message.
- S11/H6: /api/jobs served unauthenticated demo jobs when the server env was
  partially missing, masking the misconfiguration. It now fails with a real error.

Ingestion:
- I1/E1: removed unreachable post-throw code in commitDocumentIndexGeneration and
  the orphaned client-side deleteStaleIndexGenerationRows fallback. The commit RPC
  upserts index quality and prunes stale/legacy generation rows atomically
  server-side; the worker only surfaces failures (fail closed).
- I2/E2: buildIngestionRecoveryPlan requeued two jobs for one document when a
  document had both pending and failed jobs, tripping
  ingestion_jobs_one_open_per_document_uidx and leaving the queue in a
  self-perpetuating stall. It now requeues only the first recoverable job per
  document, supersedes the rest, and orders supersedes before retries so an open
  sibling is always closed before a retry flips a row to pending.

Verification: npm run verify:cheap (lint, typecheck, 2417 tests) passes offline.

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

supabase Bot commented Jul 14, 2026

Copy link
Copy Markdown

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


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

@coderabbitai

coderabbitai Bot commented Jul 14, 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

API routes now enforce anonymous catalog rate limits and redact non-owner document fields. Bulk and jobs errors are sanitized. Ingestion recovery de-duplicates retries, and worker index commits rely on the atomic RPC.

Changes

API access and document privacy

Layer / File(s) Summary
Catalog access resolution and rate limiting
src/app/api/differentials/..., src/app/api/medications/..., src/app/api/registry/records/..., src/lib/public-api-access.ts, src/lib/api-rate-limit.ts, tests/*route.test.ts
Anonymous catalog list and detail requests resolve access and pass through the registry limiter before receiving public data.
Document ownership and redaction
src/lib/public-api-access.ts, src/app/api/documents/..., tests/private-access-routes.test.ts
Non-owner document rows, related metadata, and details omit owner-internal fields, while owned documents retain them.

API error handling

Layer / File(s) Summary
Safe API failure responses
src/app/api/documents/bulk/route.ts, src/app/api/jobs/route.ts, tests/document-mutation-routes.test.ts
Bulk failures return generic messages with sanitized server logging, and missing server configuration no longer produces demo jobs.

Ingestion recovery

Layer / File(s) Summary
De-duplicate and order recovery actions
src/lib/ingestion-recovery.ts, tests/ingestion-recovery.test.ts
Only one recoverable job per document is retried; siblings are superseded first, with updated counts and ordering.
Centralized recovery status wiring
scripts/recover-ingestion-queue.ts, scripts/reindex.ts
Recovery scripts use the shared job-status constant and include pending jobs in reindex recovery inputs.

Worker index commit flow

Layer / File(s) Summary
Atomic index generation commit
worker/main.ts, tests/worker-visual-capture.test.ts
Commit RPC failures are surfaced, while client-side stale-generation cleanup and its query adapters are removed.

Review records

Layer / File(s) Summary
Review verification ledger
docs/branch-review-ledger.md
A dated ledger entry records related review findings and verification status.

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

Sequence Diagram(s)

sequenceDiagram
  participant AnonymousCaller
  participant CatalogRoute
  participant publicAccessContext
  participant RegistryRateLimiter
  AnonymousCaller->>CatalogRoute: request public catalog
  CatalogRoute->>publicAccessContext: resolve access
  publicAccessContext->>RegistryRateLimiter: consume registry subject limit
  RegistryRateLimiter-->>CatalogRoute: allow or reject
  RegistryRateLimiter-->>CatalogRoute: 429 when limited
  CatalogRoute-->>AnonymousCaller: catalog response
Loading

Possibly related PRs

  • BigSimmo/Database#488: Both changes update anonymous public-access enforcement and registry quota behavior.
  • BigSimmo/Database#489: Both changes address how indexHealth is exposed or rendered in document views.

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. 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 concisely summarizes the main remediation themes in the changeset and matches the code updates.
Description check ✅ Passed The description follows the required template and covers summary, verification, clinical preflight, and notes with relevant details.
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 claude/rag-scalability-review-x0s55l

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

@BigSimmo
BigSimmo marked this pull request as ready for review July 14, 2026 19:09
@BigSimmo
BigSimmo enabled auto-merge July 14, 2026 19:11

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

🤖 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 `@src/app/api/documents/route.ts`:
- Around line 188-193: Extend the mapping around redactNonOwnedDocumentFields so
nested label and summary rows are also redacted for document IDs not owned by
access.ownerId, preserving ownership information before the map. Apply the
existing public projections/redaction to non-owned nested rows while keeping
owned rows unchanged, and add a targeted regression test covering an
authenticated viewer reading a public document.

In `@src/app/api/medications/route.ts`:
- Around line 108-113: Update the medication, registry-record, and differential
detail handlers to remove anonymous early returns before publicAccessContext, so
known-slug requests always pass the registry limiter before serving payloads.
Reuse the existing createAdminClient and publicAccessContext flow, and add
coverage verifying anonymous detail requests receive 429 responses when
rate-limited.

In `@tests/private-access-routes.test.ts`:
- Around line 556-575: Update the list handler’s per-row redaction logic so
document fields, labels, summaries, and metadata projections are gated by that
row’s ownership rather than the request-wide context. Preserve authenticated
projections for non-owned public rows while excluding owner-only storage and
nested data, and add a mixed-owner includeMeta=true regression test alongside
this case.
🪄 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: 0766e523-2138-41a7-bab6-f201e3b464ea

📥 Commits

Reviewing files that changed from the base of the PR and between 43a8a3e and e686048.

📒 Files selected for processing (17)
  • src/app/api/differentials/route.ts
  • src/app/api/documents/[id]/route.ts
  • src/app/api/documents/bulk/route.ts
  • src/app/api/documents/route.ts
  • src/app/api/jobs/route.ts
  • src/app/api/medications/route.ts
  • src/app/api/registry/records/route.ts
  • src/lib/api-rate-limit.ts
  • src/lib/ingestion-recovery.ts
  • src/lib/public-api-access.ts
  • tests/document-mutation-routes.test.ts
  • tests/ingestion-recovery.test.ts
  • tests/medications-route.test.ts
  • tests/private-access-routes.test.ts
  • tests/registry-records-route.test.ts
  • tests/worker-visual-capture.test.ts
  • worker/main.ts

Comment thread src/app/api/documents/route.ts
Comment thread src/app/api/medications/route.ts
Comment thread tests/private-access-routes.test.ts

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

ℹ️ 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 src/app/api/documents/route.ts Outdated
Comment thread src/lib/ingestion-recovery.ts 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 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: e686048d4a

ℹ️ 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 src/lib/ingestion-recovery.ts Outdated

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

Caution

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

⚠️ Outside diff range comments (1)
scripts/reindex.ts (1)

257-270: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep fresh processing siblings in the recovery-plan input.

This filter removes fresh processing jobs before buildIngestionRecoveryPlan can recognize them as active owners. With a failed sibling, reindex will retry the failed row and may collide with or supersede the in-flight job; the later hasActiveProcessingJobs check only skips the worker after recovery has already been applied.

Pass every queried status to the planner and let its active/recoverable classification handle filtering.

Proposed fix
       const jobs = (data ?? [])
         .map((job: RawJobRow) => ({
           ...job,
           documents: Array.isArray(job.documents)
             ? (job.documents[0] as RecoveryDocument | undefined)
             : (job.documents as RecoveryDocument | undefined),
-        }))
-        .filter((job) => {
-          if (job.status === "pending") {
-            return true;
-          }
-          if (job.status === "failed") {
-            return true;
-          }
-          if (job.status !== "processing") {
-            return false;
-          }
-          if (job.locked_at === null) {
-            return true;
-          }
-          return new Date(job.locked_at) <= staleAfterCutoff;
-        });
+        }));

Add a targeted reindex test covering a failed job with a fresh processing sibling. As per coding guidelines, “When behavior changes, add or update the smallest relevant targeted test and run the narrowest relevant validation before broader suites.”

🤖 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 `@scripts/reindex.ts` around lines 257 - 270, Update the job filter before
buildIngestionRecoveryPlan to pass every queried job status through, including
fresh processing jobs, and let the planner’s active/recoverable classification
determine handling. Add a focused reindex test covering a failed job with a
fresh processing sibling, verifying the active sibling prevents conflicting
recovery.

Source: Coding guidelines

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

Outside diff comments:
In `@scripts/reindex.ts`:
- Around line 257-270: Update the job filter before buildIngestionRecoveryPlan
to pass every queried job status through, including fresh processing jobs, and
let the planner’s active/recoverable classification determine handling. Add a
focused reindex test covering a failed job with a fresh processing sibling,
verifying the active sibling prevents conflicting recovery.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: aa932fce-bc0d-4758-98a8-901ef094d4cb

📥 Commits

Reviewing files that changed from the base of the PR and between e686048 and aa161b7.

📒 Files selected for processing (7)
  • docs/branch-review-ledger.md
  • scripts/recover-ingestion-queue.ts
  • scripts/reindex.ts
  • src/app/api/documents/route.ts
  • src/lib/ingestion-recovery.ts
  • tests/ingestion-recovery.test.ts
  • tests/private-access-routes.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/private-access-routes.test.ts

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

ℹ️ 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 scripts/reindex.ts
claude and others added 4 commits July 14, 2026 20:33
… routes

Follow-up to the review of aa161b7.

Ingestion recovery (P1, confirmed by CodeRabbit + Codex):
- scripts/reindex.ts still filtered out fresh `processing` jobs before calling
  buildIngestionRecoveryPlan, so a document with a failed row plus a fresh
  processing retry passed only the failed row to the planner. Applying the
  resulting retry set the failed row to `pending` while the processing sibling
  was still open, tripping ingestion_jobs_one_open_per_document_uidx again. The
  filter is removed; every queried job (pending/processing/failed) now flows to
  the planner, whose active-vs-recoverable classification keeps the in-flight
  owner and supersedes only failed/stale siblings. Covered by the planner's
  "preserves a fresh processing job and supersedes its failed sibling" test.

Anonymous catalog detail rate limits (finding C):
- The medications, registry-record, differential, and presentation [slug] detail
  routes still short-circuited to the seed detail before publicAccessContext and
  the registry limiter, so known-slug requests bypassed rate limiting. They now
  resolve access and pass the limiter like the list routes. Added anonymous-detail
  429 coverage for the medications and registry detail routes.
- Removed the now-unused shouldResolvePublicCatalogAccess / hasPublicApiAuthSignal
  / hasBearerAuthAttempt / hasSessionCookieSignal helpers (no remaining callers).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U3gX2PtXiEELGtfL7cmCQb
…y-review-x0s55l

# Conflicts:
#	docs/branch-review-ledger.md

@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 `@docs/branch-review-ledger.md`:
- Line 557: Update the recovery-selection wording in the ledger entry to state
that the planner prioritizes a recoverable processing job and otherwise falls
back to the first recoverable sibling, replacing the inaccurate claim that it
always picks the first recoverable row.
🪄 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: 073d2f6c-b835-4d7c-bee3-e92966e02266

📥 Commits

Reviewing files that changed from the base of the PR and between aa161b7 and 920ac63.

📒 Files selected for processing (1)
  • docs/branch-review-ledger.md

Comment thread docs/branch-review-ledger.md Outdated
… from main)

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

@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: 920ac631ae

ℹ️ 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 src/app/api/documents/[id]/route.ts
BigSimmo and others added 4 commits July 15, 2026 04:47
…s55l' into claude/rag-scalability-review-x0s55l

# Conflicts:
#	docs/branch-review-ledger.md
Follow-up to the review of aa161b7/920ac631 (Codex P1).

The [id] document detail route fetches the summary with select("*") and, for a
non-owner viewing a PUBLIC document, redacted it with omitPublicInternalFields —
which did not strip source_chunk_ids, source_image_ids, or model, so summary
provenance still leaked. Those keys (present only on document_summaries rows) are
now added to the omit set, matching the list route's PUBLIC_SUMMARY projection.
Extended the authed-non-owner detail test to assert the summary is readable but
its provenance/owner fields are redacted.

Also corrected the PR #680 ledger row: catalog detail-route throttling is now
actually fixed (not "already fixed"), and the recovery description matches the
implemented planner behavior.

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

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

Caution

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

⚠️ Outside diff range comments (1)
tests/private-access-routes.test.ts (1)

567-574: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Redact arbitrary metadata from non-owned list rows.

Line 569 codifies exposing raw metadata to authenticated non-owners, while the non-owner detail contract below correctly removes it. This reintroduces the prior privacy issue: arbitrary metadata can carry owner-internal provenance or import data. Redact it per row (or return an explicit public allowlist) and assert it is absent here.

🤖 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 `@tests/private-access-routes.test.ts` around lines 567 - 574, The non-owner
list-row contract currently exposes raw metadata through sharedRow.metadata.
Update the list-row serialization or access path used by the private access
routes to redact metadata for non-owners, or apply the established public
metadata allowlist, while preserving permitted public fields such as id and
title. Adjust the assertions around sharedRow to verify metadata is absent or
limited to the approved public fields.

Source: Coding guidelines

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

Outside diff comments:
In `@tests/private-access-routes.test.ts`:
- Around line 567-574: The non-owner list-row contract currently exposes raw
metadata through sharedRow.metadata. Update the list-row serialization or access
path used by the private access routes to redact metadata for non-owners, or
apply the established public metadata allowlist, while preserving permitted
public fields such as id and title. Adjust the assertions around sharedRow to
verify metadata is absent or limited to the approved public fields.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e857b850-69a0-4b65-87f6-8b922929a971

📥 Commits

Reviewing files that changed from the base of the PR and between d842f3f and 72bdff1.

📒 Files selected for processing (12)
  • docs/branch-review-ledger.md
  • scripts/reindex.ts
  • src/app/api/differentials/[slug]/route.ts
  • src/app/api/differentials/presentations/[slug]/route.ts
  • src/app/api/documents/[id]/route.ts
  • src/app/api/medications/[slug]/route.ts
  • src/app/api/registry/records/[slug]/route.ts
  • src/components/ui-primitives.tsx
  • src/lib/public-api-access.ts
  • tests/medications-route.test.ts
  • tests/private-access-routes.test.ts
  • tests/registry-records-route.test.ts
💤 Files with no reviewable changes (1)
  • src/lib/public-api-access.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/branch-review-ledger.md
  • src/app/api/documents/[id]/route.ts
  • scripts/reindex.ts

Follow-up to the review of 72bdff1 (CodeRabbit Major).

redactNonOwnedDocumentFields kept  on non-owned public rows in the
document list, but metadata is arbitrary and can carry owner-internal provenance
(bulk-edit author user id, prior titles, indexing internals). Anonymous list
callers never receive metadata (PUBLIC_DOCUMENT_LIST_COLUMNS excludes it) and the
[id] detail route already strips it, so this closes the last inconsistency:
metadata is now redacted for non-owners in the list too. Owned rows are
unchanged. Updated the list redaction test to assert metadata is absent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U3gX2PtXiEELGtfL7cmCQb
@BigSimmo
BigSimmo merged commit 9722f41 into main Jul 14, 2026
16 checks passed
@BigSimmo
BigSimmo deleted the claude/rag-scalability-review-x0s55l branch July 17, 2026 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants