Skip to content

Add M2 atomic reindex staged generation recovery - #91

Merged
BigSimmo merged 1 commit into
mainfrom
codex/m2-atomic-reindex-implementation
Jun 29, 2026
Merged

Add M2 atomic reindex staged generation recovery#91
BigSimmo merged 1 commit into
mainfrom
codex/m2-atomic-reindex-implementation

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

  • add a service-role-only Supabase RPC to dry-run or clean abandoned staged atomic reindex generations
  • add a dry-run-first CLI wrapper via npm run reindex:cleanup-staged
  • add M2-focused helper/schema tests for staged generation identification and recovery grants

Verification

  • npm run test -- tests/reindex-pipeline.test.ts
  • npm run test -- tests/supabase-schema.test.ts
  • npm run typecheck
  • npm run verify:cheap
  • npm run check:supabase-project
  • npm run check:production-readiness

Notes

  • This does not apply the Supabase migration to the live project; it adds the migration and schema snapshot for review/release.
  • Phase 6 re-audit, lower-confidence batch, and broad DocumentViewer papercuts remain deferred.

@BigSimmo
BigSimmo merged commit a2764d8 into main Jun 29, 2026
6 checks passed

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

ℹ️ 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 on lines +95 to +99
const applied = await supabase.rpc("cleanup_abandoned_document_index_generations", {
p_document_id: args.documentId,
p_limit: limit,
p_dry_run: false,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply cleanup to the dry-run selection

When there are more eligible documents than p_limit, the dry-run RPC selects a limited candidate set, but this second RPC recomputes candidates instead of applying to the document_ids just returned. Because the SQL limit has no deterministic ordering and data can change between the two calls, apply mode can delete a different set of staged rows than the counts the operator confirmed; pass the dry-run IDs through to the apply step or otherwise make the selection stable.

Useful? React with 👍 / 👎.

Comment on lines +168 to +170
and c.document_id = any(target_document_ids)
and c.index_generation_id is not null
and c.index_generation_id::text is distinct from nullif(coalesce(d.metadata, '{}'::jsonb)->>'index_generation_id', '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Recheck active jobs before deleting staged rows

If cleanup runs while workers/API requests can start reindexing, a document can be added to target_document_ids while it has no pending/processing job, then receive a new active job before these DELETE statements execute. Since the delete predicates only check the saved document IDs and generation mismatch, they can remove rows from the newly running staged generation; repeat the active-job guard in the delete phase or lock the target document/job rows before applying.

Useful? React with 👍 / 👎.

Comment on lines +172 to +177
delete from public.document_images a
using public.documents d
where d.id = a.document_id
and a.document_id = any(target_document_ids)
and nullif(coalesce(a.metadata, '{}'::jsonb)->>'index_generation_id', '') is not null
and nullif(coalesce(a.metadata, '{}'::jsonb)->>'index_generation_id', '') is distinct from nullif(coalesce(d.metadata, '{}'::jsonb)->>'index_generation_id', '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve image paths before deleting image rows

For failed staged generations that uploaded extracted images, deleting document_images here removes the only stored storage_path for those blobs; unlike document deletion, this path never enqueues a storage_cleanup_jobs entry or calls storage removal, so the generated image files remain orphaned in SUPABASE_IMAGE_BUCKET and cannot be cleaned by cleanup:storage afterward. Capture the paths before deleting and enqueue/remove them as part of the cleanup.

Useful? React with 👍 / 👎.

@BigSimmo
BigSimmo deleted the codex/m2-atomic-reindex-implementation branch June 29, 2026 04:29
BigSimmo pushed a commit that referenced this pull request Jul 28, 2026
Records the five follow-ups that surfaced during PR #1316 and would
otherwise be lost with this session's context: the band's inability to
express a partial-source failure (and the favourites mask that papers
over it), the refetch pulse deferred on auth-backed registries by the
identity-clearing invariant, the Next streaming-clone strict-mode flake,
the design-system gates that assert structure rather than rendered
effect, and `PR required` reporting concurrency cancellations as
failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
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