Skip to content

Ingestion concurrency + scale review (phases 1-2); fixes held for db-reliability - #339

Merged
BigSimmo merged 6 commits into
mainfrom
claude/ingestion-concurrency-scale
Jul 7, 2026
Merged

Ingestion concurrency + scale review (phases 1-2); fixes held for db-reliability#339
BigSimmo merged 6 commits into
mainfrom
claude/ingestion-concurrency-scale

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

Phases 1-2 of the ingestion-concurrency/scale review. Docs only — no behavior changes yet. Phase-3 fixes are deliberately held until the db-reliability branch merges; fix commits will be added to this PR afterwards.

Phase 1 — docs/ingestion-state-machine.md

Full state model of documents × ingestion_jobs × indexing_v3_agent_jobs × index generations: legal composite states, writer × transition matrix (worker / edge agent / API routes / ops scripts), crash-window analysis, and a verified violations registry.

Method: 7 scoped race-hunter agents (one per writer × transition group), 24 consolidated claims, each re-derived by an independent adversarial verifier (exact reaching schedule or killing guard required). 24/24 confirmed, 5 narrowed, 0 refuted. Two facts checked directly against the live catalog.

Highest-severity confirmed findings (7 need no concurrency at all):

  • R11 — aborted DELETEs leave failed ledger rows with live paths; cleanup:storage then permanently deletes a live document's PDF + images
  • R15 — retrying a failed (or completed) job of an indexed document sets it queued, so the next claim's reset_document_index destroys the live committed index
  • R3 — double-build metadata repoint leaves an "indexed" doc retrieval-empty, then abandoned-generation cleanup deletes the surviving rows
  • R4/R19/R23 — generation-blind resets (worker reclaim / queue recovery / cleanup RPC) amputate a live build; commit stamps full client-side counts over the partial row set (silent partial clinical index)
  • R1 — no lease heartbeat: every >45-min job is reclaimed while alive; no write anywhere is fenced by locked_by
  • R12 — every successful reindex permanently strands the previous generation's image objects (only the DELETE route ever writes the storage ledger)
  • R22 — routine queue recovery silently force-completes every queued reindex of indexed docs
  • R24d/c — enrichment writers (edge agent / route mode:'enrichment' / worker inline) are mutually unguarded: completed/"good" docs with zero artifacts, duplicate index units, detached cards; repair_strict_enrichment_gate_batch is invoked by nothing
  • R24e — schema.sql drift: fresh envs have a fatal ingestion_job_stages.job_id FK and a claim RPC that never seeds agent jobs (live verified unaffected)

Phase 2 — docs/scale-readiness-review.md

Read-only live profiling (explain_retrieval_rpc + direct EXPLAIN ANALYZE; one SET LOCAL experiment inside a rolled-back transaction). At 10× (~20k docs):

  • F1match_document_table_facts_text already takes 6.75 s (unindexable 5-column trigram similarity() OR-disjunct); ~linear growth; called 3× in parallel per request
  • F2document_index_units has no vector index and no vector arm — semantic recall for visual/enrichment evidence is structurally zero
  • F3hnsw.ef_search=40 silently caps every vector arm below its LIMIT (measured 40 vs 72 rows at ef=200)
  • F4 — ~5 GB of HNSW on a 256 MB-buffer instance (~50 GB at 10×)
  • F6 — 10-14 RPC fan-out per cold request vs max_connections 60

Ranked mitigation list in the doc; retrieval-affecting changes must pass the content_mrr@10 eval gate before defaults move.

Phase 3 (pending)

Fix backlog is ranked in the state-machine doc §8 (janitor guard, retry-route demotion fix, lease heartbeat + locked_by fences, metadata merge, recovery hardening, storage reconciliation, …). Held until db-reliability merges; each fix will be the smallest safe change, via committed migrations + code, gated on verify:cheap, check:indexing, reindex:health.

🤖 Generated with Claude Code

BigSimmo and others added 2 commits July 7, 2026 02:02
Read-only live profiling (explain_retrieval_rpc + direct EXPLAIN ANALYZE via
MCP; profile:retrieval's underlying RPC — no local Supabase credentials).
Headline findings: table-facts text RPC already at 6.75s (unindexable trigram
OR-disjunct, ~linear growth); index-units hybrid has no vector arm (and no
HNSW index); ef_search=40 silently caps every vector arm below its LIMIT
(measured 40 vs 72); ~5GB of HNSW on a 256MB-buffer instance; 10-14 RPC
fan-out per cold request. Ranked mitigation list included; all changes held
for eval-gated follow-up work.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Full state model of documents x ingestion_jobs x indexing_v3_agent_jobs x
index generations: legal composite states, writer x transition matrix, and
crash-window analysis for all four writers (worker, edge agent, API routes,
ops scripts).

Violations found by 7 scoped race-hunter agents (one per writer x transition
group), consolidated into 24 claims and re-derived by an independent
adversarial verifier: 24/24 confirmed (5 narrowed, 0 refuted). Seven are
deterministic - no concurrency required - including: aborted DELETEs poison
the storage-cleanup ledger so the janitor destroys live documents' storage
(R11); retrying a failed job of an indexed doc destroys its live committed
index (R15); every successful reindex permanently strands the prior image
generation (R12); recovery supersede silently cancels queued reindexes (R22).
Root concurrency enabler: no lease heartbeat (R1), making every >45-min job
multi-master. Ranked phase-3 fix backlog included; fixes HELD until the
db-reliability branch merges.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@supabase

supabase Bot commented Jul 6, 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 ↗︎.

@BigSimmo
BigSimmo marked this pull request as ready for review July 6, 2026 18:19
@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.

@BigSimmo
BigSimmo enabled auto-merge July 6, 2026 18:19
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@BigSimmo
BigSimmo merged commit 9dc337e into main Jul 7, 2026
5 checks passed
@BigSimmo
BigSimmo deleted the claude/ingestion-concurrency-scale branch July 8, 2026 16:16
BigSimmo added a commit that referenced this pull request Aug 18, 2026
… favourites timestamps, and answer notice (#309, #281, #339, #165) (#2074)

* feat(ui): implement filter density tiers, mobile route deduplication, favourites timestamps, and answer notice (#309, #281, #339, #165)

* fix(ui): repair CI blockers on filter density tiers (PR #2074)

* fix(ui): keep document-viewer retry panel ids unique under density tiers (PR #2074)

* fix(favourites): fix O(N²) storage callbacks and hydration mismatch in useSyncExternalStore

Co-authored-by: BigSimmo <87357024+BigSimmo@users.noreply.github.com>

* style: fix prettier formatting in favourites command library page

CI's format:changed check was failing on this file's useSyncExternalStore
formatting.

* fix(ui): keep document rail high-yield summary visible when printing

`max-sm:hidden` (added to dedupe the summary panel on phone viewports)
also suppressed it during print emulation at narrow viewport widths,
since the print stylesheet only restores overflow/box-shadow and never
overrides display:none. Add `print:block`, the pattern already used
elsewhere in this codebase (verification-notice.tsx,
medication-considerations.tsx) to keep a responsively-hidden element
printable.

Fixes the "document viewer content disclosures are naturally closed
and mutually exclusive by default" Production UI failure, which set a
390px viewport and asserted the high-yield-summary content becomes
visible under print media.

* fix(test): update high-yield summary nav assertion for mobile dedup

The exclusive-accordion assertions after clicking the "High-yield
summary" section-nav row assumed the rail's <details id="source-summary">
still opens on a 390px viewport. Since the mobile route-dedup change
hides that rail copy (max-sm:hidden) in favour of the always-visible
in-flow DocumentClinicalSummary card, jumpToDocumentSection's existing
"displayed copy" resolution (use-section-spy.ts's source-summary ->
source-summary-card alias) now scrolls to the card instead of toggling
the hidden accordion — so `summary.open` never becomes true at this
viewport. Assert the visible copy scrolls into view instead, matching
the pattern already used for the "Indexed source text" row above it.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
BigSimmo added a commit that referenced this pull request Aug 19, 2026
…ds bundle

- #QSHHGK: add bundle-budget drift warning threshold and commit-distance indicators in scripts/check-bundle-budget.mjs
- #TF6TPJ: add anti-churn in-flight CI cancellation guard in scripts/sync-open-pr-branches.mjs and sync-pr-branches.mjs
- #DREDWA: expand ledger writer and guard self-tests to cover 26-char Crockford ULID display IDs in scripts/check-outstanding-issues.mjs and outstanding-issues.mjs
- #RZQQBT: add structured ISO UTC diagnostic execution logging to .claude/hooks/precompact-issues-capture.sh
- #164Z0H: add hook permissions (100755) and line-ending (CR=0) contract tests in tests/session-start-hook.test.ts
- #D6G8TC: migrate Therapy Compass headings to shared PageHeader
- #ZF006G: consolidate SectionHeading components in src/components/ui/section-heading.tsx
- #V0EDR4: align Favourites hero presentation between standalone and dashboard variants in favourites-hub.tsx
- #339: gracefully handle empty/unauthenticated local state fallback in favourites-command-library-page.tsx
- #YJ3R7Y: add SSR height reservation attributes to bespoke composer containers in favourites, tools, and dashboard slots
- #308: reserve desktop composer slot height at adoption boundary to eliminate 0.118 CLS jump in master-search-header.tsx
- #XPY409: document phone sticky-header mount and settle timing assertion recipes in docs/testing.md and docs/search-chrome-behaviour.md
BigSimmo added a commit that referenced this pull request Aug 19, 2026
… copy consistency bundle (#2186)

* feat(hardening): implement safe tooling, ui layout, and workflow guards bundle

- #QSHHGK: add bundle-budget drift warning threshold and commit-distance indicators in scripts/check-bundle-budget.mjs
- #TF6TPJ: add anti-churn in-flight CI cancellation guard in scripts/sync-open-pr-branches.mjs and sync-pr-branches.mjs
- #DREDWA: expand ledger writer and guard self-tests to cover 26-char Crockford ULID display IDs in scripts/check-outstanding-issues.mjs and outstanding-issues.mjs
- #RZQQBT: add structured ISO UTC diagnostic execution logging to .claude/hooks/precompact-issues-capture.sh
- #164Z0H: add hook permissions (100755) and line-ending (CR=0) contract tests in tests/session-start-hook.test.ts
- #D6G8TC: migrate Therapy Compass headings to shared PageHeader
- #ZF006G: consolidate SectionHeading components in src/components/ui/section-heading.tsx
- #V0EDR4: align Favourites hero presentation between standalone and dashboard variants in favourites-hub.tsx
- #339: gracefully handle empty/unauthenticated local state fallback in favourites-command-library-page.tsx
- #YJ3R7Y: add SSR height reservation attributes to bespoke composer containers in favourites, tools, and dashboard slots
- #308: reserve desktop composer slot height at adoption boundary to eliminate 0.118 CLS jump in master-search-header.tsx
- #XPY409: document phone sticky-header mount and settle timing assertion recipes in docs/testing.md and docs/search-chrome-behaviour.md

* style: format changed files with Prettier and clean up unused imports

* feat(hardening): safe workflow guards, worktree pruning, and motion contracts bundle

* fix(tooling): cross-platform drive regex and test cleanup bounded retries in clean-worktree

* feat(hardening): 12-task route skeletons, mobile privacy warning, and copy consistency bundle

* test(ui-copy): permit optional suggestions in shared home presentation assertions

* docs(issues): restore base outstanding-issues ledger to maintain write discipline

* docs(inbox): synchronize inbox state with base main

* fix(lint): clean up unused variables, explicit types, and const declarations
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