Skip to content

Blank-DB Restore Matrix

⚠️ HISTORICAL / SUPERSEDED (S491, 22/07/2026). Point-in-time artefact (16/04/2026 DB queries against the pre-cutover prod project). Its new-project transfer model is dead — the ratified cutover is in place onto existing prod (see reingest-cutover-runbook.md §7), reframed by DR-025 as a one-time onboarding ingest. The schema it classifies predates ID-131 (content_items retired S449; extraction tables re-parented to source_document_id) and the cocoindex pipeline rebuild. Its restore discipline (FK-ordered, category classification) remains a useful reference; its table names, item counts, and entry-point queries must NOT be executed as written.

Status: DRAFT (S176 WP3 — Liam decisions resolved + squash results) Last updated: 16/04/2026

Purpose: classifies every ingress path and every persistent-state surface in the Knowledge Hub by how it can be re-populated when bringing up a fresh Supabase project (the target re-ingestion environment per the S165 decision locked at .planning/.archive/.specs/content-format-standardisation-spec.md:1323-1324).

The matrix is the input to the two-stage re-ingestion runbook (docs/operations/two-stage-re-ingestion-runbook.md) — Stage 1 ingests the Phew .docx corpus + replayable sources via the canonical pipeline; Stage 2 (conditional) re-imports the client’s new markdown set if Stage 1 quality justifies it.

Read alongside:

  • docs/reference/data-entry-points.md (entry-point inventory; refreshed S174)
  • docs/operations/re-ingestion-quality-protocol.md (6-step protocol + DOCX pre-processing checklist; shipped S168)
  • docs/operations/database-rebuild-runbook.md (pre-existing rebuild runbook; see §Reconciliation below)

CategoryDefinitionConfidence at restore
Replayable-from-sourceSource artefact (URL / .docx / .md) preserved; re-run through the canonical pipelineHigh
Re-seedableStatic config / taxonomy / template — restore via SQL dump or seed migrationHigh
Manual-recreateNo source artefact; must be manually re-authored (e.g. MCP-created guides via Claude Desktop)Medium (depends on author availability)
Export-then-reimportNo source artefact but DB content can be exported as markdown and re-ingested via the canonical pipelineMedium (loses some metadata)
Lost-acceptableHistorical / audit / observability state; acceptable to lose on fresh instancen/a (no restore attempt)

Item counts are from live DB queries run 16/04/2026 against project rovrymhhffssilaftdwd. Entry point attribution uses these markers:

SignalEntry point
metadata->>'source' = 'intelligence_pipeline'EP11 (RSS)
metadata->>'ingestion_source' = 'markdown_file'EP2 (Python MD)
metadata->>'ingestion_source' = 'upload'EP3 (File Upload)
metadata->>'ingestion_source' = 'manual'EP5 (Manual API)
source_url != '' AND source_file IS NOT NULLEP8 (Q&A Import)
source_url IS NOT NULL AND source_file IS NULL AND file_path IS NULL AND metadata->>'source' IS NULLEP1/EP4 (URL)
No standard markers (batch_tag only or nothing)EP9 (MCP)

Mapped to entry points 1–11 from data-entry-points.md. Plus side-table state surfaces that are not entry points but require restore decisions.

FieldValue
CategoryReplayable-from-source
Source artefactOriginal URLs. No canonical URL inventory file exists — extract from DB before re-ingestion.
Estimated item count~13 items (articles + policies with source_url set, no source_file, no file_path, no intelligence_pipeline metadata). Cannot distinguish EP1 (Python CLI) from EP4 (TS API) in existing data — both write source_url without a distinguishing marker.
Restore mechanismExport URL list via SELECT source_url FROM content_items WHERE source_url IS NOT NULL AND source_file IS NULL AND file_path IS NULL AND metadata->>'source' IS NULL. Then python3 scripts/ingest.py --file urls.txt.
Resolution (S175)No canonical URL inventory exists. The metadata.ingestion_source field is NULL for all 13 items (pre-dates the field). URL extraction query above is the only reliable method. Export this list to data/url-inventory-pre-reingest.txt as a pre-requisite step before wiping the old project.

Entry Point 2 — Python Markdown Ingestion

Section titled “Entry Point 2 — Python Markdown Ingestion”
FieldValue
CategoryReplayable-from-source
Source artefact.md files in documentation directory (Phew client corpus). 13 items have ingestion_source='markdown_file'. Additionally, 222 Q&A items written by EP8 (import_bid_library.py) also have source_file set — those are attributed to EP8, not EP2.
Estimated item count13 items (metadata->>'ingestion_source' = 'markdown_file').
Restore mechanismpython3 scripts/ingest_markdown.py <dir> with --skip-existing, --tag, --author.
Resolution (S175)Stage 1 vs Stage 2 question resolved. Stage 1 = Phew .docx corpus via EP8 + EP2 (existing markdown). Stage 2 (conditional) = client’s new markdown. The 13 markdown items are part of Stage 1.
Known gapNo chunking — need post-ingest bun run scripts/backfill-chunks.ts.
FieldValue
CategoryReplayable-from-source (if storage files preserved) OR Export-then-reimport (if not)
Source artefactOriginal PDF/DOCX/MD files in Supabase Storage documents bucket (13 files), tender-documents bucket (1 file), templates bucket (6 files). source_documents table (37 rows) provides lineage.
Estimated item count3 items (2 with file_path IS NOT NULL + 1 E2E upload sentinel with ingestion_source='upload').
Restore mechanism(a) Download files from old project’s Storage buckets → upload to new project → replay via POST /api/upload per file. OR (b) Export current content as markdown and re-ingest via EP2.
LIAM DECISION (S176)Storage bucket strategy — RESOLVED. Files downloaded to docs/temp/. Investigation (S176 Wave 0) found: (a) documents bucket: 13 files are all E2E test artifacts (e2e-upload-sentinel-8-0-4.pdf duplicated from Playwright test runs), not production data; (b) tender-documents bucket: 1 PDF from manual testing of bid feature (only 1 draft bid workspace exists); (c) templates bucket: files from bid template testing (duplicated content). All 3 buckets contain only development/test artifacts — no production files. Buckets were created via Supabase dashboard (not config.toml or E2E tests). Decision: SKIP preservation. Buckets will be recreated empty by migrations (INSERT INTO storage.buckets now included in squashed migration). No production content at risk.
FieldValue
CategoryReplayable-from-source
Source artefactOriginal URLs (same as EP1 — source_url column).
Estimated item count0–13 items (cannot distinguish from EP1 in existing data; combined count is 13).
Restore mechanismUse Python CLI (EP1) for bulk replay — same pipeline, no rate limit, no auth required.
Resolution (S175)Recommend EP1 (Python CLI) for all bulk URL replay. The API route (EP4) adds rate limiting (10/min) and auth overhead with no benefit for batch operations. Collect all URLs into data/url-inventory-pre-reingest.txt and run via EP1.

Entry Point 5 — Manual Item Creation API (POST /api/items)

Section titled “Entry Point 5 — Manual Item Creation API (POST /api/items)”
FieldValue
CategoryLost-acceptable (negligible population, all test items)
Source artefactNone (web-form authored).
Estimated item count2 items (ingestion_source='manual'): “S167 Markdown Editor Test” and “S167 Chunking Pipeline Test”. Both created 14/04/2026 as development test artefacts.
Restore mechanismNone needed — test items, not production content.
Resolution (S175)Reclassified from Export-then-reimport to Lost-acceptable. Both items are S167 development tests with no production value. No export script needed. If future manual items accumulate before re-ingestion, revisit — but current population is zero production items.

Entry Point 6 — Batch Item Creation API (Q&A autosplit)

Section titled “Entry Point 6 — Batch Item Creation API (Q&A autosplit)”
FieldValue
CategoryNot applicable (never used for production data)
Source artefactn/a
Estimated item count0 items (metadata->>'autosplit_batch_id' IS NOT NULL returns 0).
Restore mechanismn/a
Resolution (S175)No autosplit items exist. The batch API route exists and is tested but has never been used for production ingestion. All Q&A pairs were ingested via EP8 (Python import_bid_library.py). This entry point requires no restore action.
FieldValue
CategoryLost-acceptable (UPDATE-only path — no items created)
Source artefactn/a
Restore mechanismRe-run bun run scripts/batch-reclassify.ts --execute on items restored via EP1–EP8 if classification quality needs improvement post-re-ingestion.
Resolution (S175)No open questions — this is a maintenance path, not an ingress. Post-re-ingestion reclassification may be needed if the initial keyword-only classification from EP8 is insufficient.

Entry Point 8 — Q&A Import (Bid Library)

Section titled “Entry Point 8 — Q&A Import (Bid Library)”
FieldValue
CategoryReplayable-from-source
Source artefactOriginal .docx files (Phew bid library).
Estimated item count222 items (content_type='q_a_pair' AND source_url = '', indicating Python import wrote empty-string source_url). Note: 2 additional Q&A items exist with source_url IS NULL (from TEST-pigeon-post-demo batch) — those are attributed to EP9, not EP8.
Restore mechanismRe-run python3 scripts/import_bid_library.py <dir> --batch-tag <tag> against the same .docx corpus.
Resolution (S175)Idempotency check is not an issue on clean DB. The check uses title-match against existing content_items. Against a blank DB, no existing items → no duplicates found → all items inserted. --force is not implicitly invoked — the check simply passes benignly. Autosplit grouping non-determinism (S174 question) is also moot: 0 autosplit items exist — all Q&A was imported via this script, not the batch API.
FieldValue
CategoryManual-recreate (no source artefact preserved)
Source artefactOriginal Claude Desktop conversation prompts. No metadata markers distinguish these items — they lack ingestion_source, source_url, source_file, and file_path.
Estimated item count~13 content_items without standard provenance markers: 7 × consolidation-phew-march-2026 batch (company docs — Corporate Identity, Company Profile, Social Value, Business Continuity, Certifications, GDPR, InfoSec Controls), 3 × TEST-pigeon-post-demo batch (LMS Product Description, Bid Q&A, Security Q&A), 1 × Telehouse fact sheet, 1 × SI Feed brief, 1 × Shaw Education Trust case study. Plus 9 guides (117 guide_sections) in the guides table — created via MCP create_guide tool, separate from content_items.
Restore mechanismRe-run original Claude Desktop prompts against the new project’s MCP server. A/B compare current-DB items vs new.
Resolution (S175)Prompt archive is WP3 scope (docs/operations/guide-regeneration-prompts.md). The 7 consolidation-phew items are company reference docs that could alternatively be re-authored from the original .docx sources if the prompts are unrecoverable. The 3 pigeon-post items are demo/test content — Lost-acceptable. The 9 guides + 117 sections are the highest-priority manual-recreate items (sector/product/company guides actively used in the MCP workflow).

Entry Point 10 — Bid Outcome KB Integration

Section titled “Entry Point 10 — Bid Outcome KB Integration”
FieldValue
CategoryNot applicable (no bid data exists)
Source artefactn/a
Estimated item count0 items. bid_questions: 0 rows. bid_responses: 0 rows. bid_response_history: 0 rows. Only 1 bid workspace exists (name: “BROKEN_NAME_PHASE4”, status: draft) — a development artefact.
Restore mechanismn/a. After bid workspace tables are restored (if any real bids exist by then), re-run POST /api/bids/:id/outcome/integrate for each won bid.
Resolution (S175)No batch endpoint exists — per-bid only. Moot for current data (0 bids). If real bids accumulate before re-ingestion, a batch script would need writing. The bid workspace schema is restored by migrations; bid data is populated by users through the UI.
FieldValue
CategoryRe-seedable (feed config) + Replayable-from-source (promoted articles via their URLs) + Lost-acceptable (historical unpromoted articles)
Source artefacts(a) feed_sources (25 rows) + feed_prompts (3 rows) = re-seedable config. (b) 75 promoted articles have content_item_id IS NOT NULL — their source_url (from feed_articles.external_url) enables replay via EP1. (c) 339 unpromoted feed_articles = historical LLM filter scores only.
Estimated item count75 promoted items in content_items (identified by metadata->>'source' = 'intelligence_pipeline'). 414 total feed_articles. 25 feed_sources. 3 feed_prompts.
Restore mechanism(1) Re-seed feed_sources + feed_prompts via SQL dump. (2) Re-ingest promoted-article URLs via EP1 (Python CLI) using exported URL list. (3) After re-ingestion, re-link feed_articles.content_item_id to new content_items.id UUIDs via URL match. (4) Cron resumes polling — new articles flow normally.
LIAM DECISION (S176)Historical feed_articles preservation — RESOLVED. Preserve feed_articles snapshot for promoted rows only (75). Accept loss of unpromoted rows (339) — intermediate LLM filter state with no user-facing value. FK re-link of content_item_id to new UUIDs via URL match is needed post-re-ingestion (Step 14 in restore order).
Known gapNo chunking — need post-ingest bun run scripts/backfill-chunks.ts.

41 tables exist in public schema. Organised by restore category.

Re-seedable (restore via SQL dump or seed migration)

Section titled “Re-seedable (restore via SQL dump or seed migration)”
SurfaceRow countRestore mechanismNotes
taxonomy_domains15Seed migration or bun run sync:taxonomyTaxonomy is DB-driven; sync:taxonomy regenerates classification prompt + plugin files. No subtopic key rename issue — keys are stable strings.
taxonomy_subtopics57Seed migration or bun run sync:taxonomySame as above.
workspaces4SQL dump with UUID preservation1 bid workspace (draft), 2 intelligence workspaces, 1 GNews dedup workspace. UUIDs must be preserved — content_item_workspaces has FK dependency.
content_item_workspaces75Re-created after workspace + content_item restoreFK to both workspaces.id and content_items.id. Must restore after both parent tables. UUIDs will change for content_items — requires re-linking.
user_roles8bun run seed:e2e-users + manual admin seedingget_user_role() function created by migrations. E2E users auto-seeded. Production users need manual role assignment.
entity_aliases24SQL dumpConfig-like lookup table. No FK dependencies. BLOCKING: no CREATE TABLE migration existssupabase db push on a fresh project will NOT create this table. A migration must be authored before re-ingestion execution.
layer_vocabulary4SQL dump or seed migrationLayer display labels.
company_profiles1SQL dumpSingle company profile (Phew Design Ltd).
template_requirements96SQL dumpTemplate requirement definitions. No FK to content_items.
templates0n/a (empty)Schema exists; no data to restore.
template_fields0n/a (empty)Schema exists; no data to restore.
template_completions0n/a (empty)Schema exists; no data to restore.
content_templates0n/a (empty)Schema exists; no data to restore.
coverage_targets0n/a (empty)Schema exists; no data to restore.
governance_config0n/a (empty)Schema exists; no data to restore.
review_assignments0n/a (empty)Schema exists; no data to restore.
verification_history1SQL dump (optional)Single row; low value.
feed_sources25SQL dump (see EP11)RSS/Atom feed configuration.
feed_prompts3SQL dump (see EP11)LLM filter prompt templates.
feed_flags1SQL dump (optional) — must restore AFTER feed_articles (Step 9)Single flag row. FK: feed_article_id → feed_articles(id), prompt_version_id → feed_prompts(id).

Manual-recreate (MCP-created via Claude Desktop)

Section titled “Manual-recreate (MCP-created via Claude Desktop)”
SurfaceRow countRestore mechanismNotes
guides9Prompt-based recreation via Claude Desktop (see EP9). SQL dump as backup.4 sector, 3 product, 1 company, 1 research guide. Preferred path is prompt recreation for quality validation; SQL backup preserves content if prompts unrecoverable.
guide_sections117Coupled to guides — recreated atomically. SQL dump as backup.9–19 sections per guide.

Generated by re-ingestion (do NOT migrate — let pipeline regenerate)

Section titled “Generated by re-ingestion (do NOT migrate — let pipeline regenerate)”
SurfaceRow countNotes
entity_mentions714Re-populated by classifyContent() during re-ingestion. Clean re-classification is the point.
entity_relationships3,636Same — regenerated during classification.
content_chunks444Re-populated by regenerateChunks() for entry points that invoke it; backfill required for EP2/EP6/EP10/EP11 gaps.
content_history36New v1 row per item created by canonical ingest pipelines. Pre-restore history is lost. Acceptable.
content_citations0Empty; will be regenerated if citation features are used post-restore.

Lost-acceptable (observability / ephemeral state)

Section titled “Lost-acceptable (observability / ephemeral state)”
SurfaceRow countNotes
pipeline_runs43Observability data. New runs created during re-ingestion.
notifications133UI notification state.
read_marks1Per-user UI state.
digests1Single change report. See decision note below.
ingestion_quality_log3Quality logging from Python pipeline. New entries created during re-ingestion.
processing_queue3Ephemeral processing state.
si_processing_queue2,206Sector Intelligence processing records. Historical — new runs create new entries.
source_documents37Lost if Storage bucket not preserved (see EP3 decision). Restored if bucket preserved + files re-uploaded.
source_document_diffs0Empty; coupled to source_documents.

Digests decision (S176 — Liam confirmed): 1 digests row exists. Change reports are generated fresh from content_history data. Post-re-ingestion, the new content_history will be all v1 records — no meaningful change report possible until content evolves. Accept loss — confirmed.

Bid workspace tables (Re-seedable, but currently empty/test-only)

Section titled “Bid workspace tables (Re-seedable, but currently empty/test-only)”
SurfaceRow countNotes
bid_questions0No real bids exist.
bid_responses0No real bids exist.
bid_response_history0No real bids exist.
Workspace type='bid'1”BROKEN_NAME_PHASE4” (draft) — development artefact. Do not restore.

Feed articles (split category — see EP11)

Section titled “Feed articles (split category — see EP11)”
SurfaceRow countNotes
feed_articles (promoted, content_item_id IS NOT NULL)75Snapshot-preserve. Re-link content_item_id to new UUIDs after re-ingestion (Step 14).
feed_articles (unpromoted)339Lost-acceptable. Intermediate LLM filter state with no user-facing value. See EP11 Liam decision.

Note: The skeleton referenced bids and bid_workspaces tables — these do not exist. Bid data lives in bid_questions/bid_responses linked to workspaces with type='bid'. No production bid data exists; all tables are empty or contain test artefacts.

BucketFilesNotes
documents13Private. Source files for EP3 uploads. Per-project — cannot share.
tender-documents1Private. Single tender document.
templates6Private. Template files.

Total: 20 files. See EP3 decision for preservation strategy.


FK dependency chain determines ordering. Steps marked with ★ require operator action beyond running a script.

Pre-requisite: Migration squash (S176 — COMPLETE). 43 migrations squashed to 1 (20260416102457_pre_squash_reconciliation.sql, 8,600 lines). Gaps found and fixed: entity_aliases table (missing entirely), digests table (9 missing columns), workspaces + processing_queue (missing created_by / updated_by columns), 4 functions created via MCP (claim_next_job, content_history_auto_version, get_source_documents, get_verification_stats), 46 ALTER FUNCTION signature mismatches, 3 storage buckets (missing INSERT statements), 6 storage RLS policies (missing for documents + tender-documents buckets). Full reconciliation report: docs/operations/schema-reconciliation-report-s176.md.

StepActionDependencyEst. time
0★ New Supabase project provisioned (eu-west-2, pgvector 0.8.0). Note project ID. Populate env vars.Migration squash complete10 min
1Apply migrations: /opt/homebrew/bin/supabase db push (single squashed migration)Step 02 min
2Regenerate types: supabase gen types typescript --project-id mgrmucazfiibsomdmndh --schema public > supabase/types/database.types.tsStep 11 min
3Seed auth users: bun run seed:e2e-users + verify pipeline service accountStep 12 min
4Seed user_roles for production users (manual INSERT or dump-restore)Step 35 min
5Seed static config: taxonomy_domains, taxonomy_subtopics via bun run sync:taxonomyStep 12 min
6Seed remaining config: entity_aliases (24), layer_vocabulary (4), company_profiles (1), template_requirements (96) via SQL dumpStep 15 min
7Restore workspaces (4 rows, with UUIDs preserved)Step 12 min
8Restore feed_sources (25) + feed_prompts (3)Step 7 (workspace FK)5 min
9★ (If preserving) Restore feed_articles snapshot — promoted rows only (75), with content_item_id = NULL (re-linked in Step 14)Step 810 min
9bRestore feed_flags (1 row) via SQL dump. FK: feed_article_id → feed_articles(id), prompt_version_id → feed_prompts(id)Step 8, Step 91 min
10Storage buckets — SKIPPED (S176 decision: all buckets contain only test artifacts). Buckets auto-created empty by migration.Step 00 min
11Stage 1 re-ingest — Phew .docx corpus: python3 scripts/import_bid_library.py <dir> --batch-tag phew-reingest-2026 (EP8, ~222 items)Step 5 (taxonomy needed for classification)~30 min
12Stage 1 re-ingest — markdown files: python3 scripts/ingest_markdown.py <dir> --tag phew-markdown-reingest (EP2, ~13 items)Step 5~5 min
13Stage 1 re-ingest — URL inventory: python3 scripts/ingest.py --file data/url-inventory-pre-reingest.txt (EP1, ~13 items)Step 5~10 min
14Re-link feed_articles.content_item_id for promoted rows via URL-match SQL (see runbook Step 14 for SQL)Step 9, Step 1310 min
15Backfill chunks: bun run scripts/backfill-chunks.ts (for EP2/EP8/EP11 gap items)Steps 11–13~15 min
16Re-ingest RSS-promoted URLs: extract URLs from preserved feed_articles → run via EP1 (75 items)Steps 5, 8~15 min
17Re-link content_item_workspaces for intelligence workspace itemsSteps 7, 165 min
18★ MCP guide regeneration (EP9): re-run Claude Desktop prompts for 9 guides + 117 sections. A/B compare.Steps 11–13 (KB content needed for guide context)1–2 hours
19★ MCP content_item recreation (EP9): re-run prompts for ~13 orphan items (7 consolidation-phew, etc.)Steps 11–1330 min
20Stage 1 decision gate: Run quality protocol (snapshot, compare, human review). Proceed to Stage 2 only if all thresholds met.Steps 11–191 hour
21(Conditional) Stage 2 — client new markdown: python3 scripts/ingest_markdown.py <new-dir> + backfill chunksStep 20 passVariable
22Post-Stage-2 quality comparison: A/B against Stage 0 + Stage 1 snapshotsStep 2130 min
23Embedding smoke test: bun run scripts/embedding-smoke-test.tsSteps 11–215 min
24Final snapshot: bun run scripts/snapshot-content-state.tsStep 235 min

FK dependency justification:

  • content_item_workspacesworkspaces.id + content_items.id (Step 17 after Steps 7 + 11–16)
  • feed_articles.content_item_idcontent_items.id (Step 14 after Steps 9 + 13)
  • feed_articles.feed_source_idfeed_sources.id (Step 9 after Step 8)
  • feed_prompts.workspace_idworkspaces.id (Step 8 after Step 7)
  • feed_sources.workspace_idworkspaces.id (Step 8 after Step 7)
  • entity_mentions.content_item_idcontent_items.id (auto-generated during Steps 11–16)
  • entity_relationships.source_item_idcontent_items.id (auto-generated during Steps 11–16)
  • user_roles.user_idauth.users.id (Step 4 after Step 3)
  • guide_sections.guide_idguides.id (Step 18 creates both atomically)

Reconciliation with database-rebuild-runbook.md

Section titled “Reconciliation with database-rebuild-runbook.md”

The existing docs/operations/database-rebuild-runbook.md covers four scenarios: fresh demo DB, Phew re-ingest, disaster recovery, and local dev reset. This restore matrix and the two-stage re-ingestion runbook (WP2) supersede the “Phew re-ingest” scenario specifically.

Runbook sectionOverlapAction needed
§3 Step 1 (db reset)Overlaps — but the restore matrix uses a new project, not a reset of the existing one.No change needed. The runbook’s reset path is for same-project rebuilds; the matrix’s new-project path is distinct.
§4 Step 2 (push migrations)Identical — both use supabase db push.No change needed.
§5 Step 3 (gen types)Identical.No change needed.
§6 Step 4 (seed users)Identical — bun run seed:e2e-users.No change needed.
§8 Step 6 (seed app data)Partial overlap. The runbook’s “For Phew re-ingest” subsection points at ingest_markdown.py only. The restore matrix adds EP1 URL replay, EP8 Q&A import, EP11 RSS re-ingest, EP9 guide recreation, chunk backfill, and quality protocol.Recommend: Add a sentence to §8 “For Phew re-ingest” pointing to the restore matrix and two-stage runbook as the authoritative procedure. Do not duplicate the full restore order in the runbook.
§12 Quality gatePoints at re-ingestion-quality-protocol.md. The restore matrix’s Step 20 (decision gate) invokes the same protocol.No change needed — cross-reference is already correct.

Gap identified: The runbook does not mention the new-project-ID placeholder or storage bucket migration. These are covered exclusively by the restore matrix and two-stage runbook. The runbook should add a cross-reference line:

For the Phew re-ingest into a new Supabase project, follow the Blank-DB Restore Matrix and the Two-Stage Re-Ingestion Runbook.


Before deleting or decommissioning the old project, extract these artefacts:

  • URL inventory: SELECT source_url FROM content_items WHERE source_url IS NOT NULL AND source_file IS NULL AND file_path IS NULL AND metadata->>'source' IS NULLdata/url-inventory-pre-reingest.txt
  • RSS-promoted URLs: SELECT fa.external_url FROM feed_articles fa WHERE fa.content_item_id IS NOT NULLdata/rss-promoted-urls.txt
  • Feed config dump: feed_sources (25 rows) + feed_prompts (3 rows) → SQL dump
  • Feed articles snapshot (promoted only, 75 rows) → SQL dump (with content_item_id set to NULL)
  • Static config dump: entity_aliases, layer_vocabulary, company_profiles, template_requirements, workspaces → SQL dump with UUIDs
  • Storage bucket files: download all 20 files from documents (13), tender-documents (1), templates (6)
  • Pre-reingest quality snapshot: bun run scripts/snapshot-content-state.tsdata/snapshots/pre-reingest-YYYY-MM-DD.jsonl
  • Guides + guide_sections SQL dump: guides (9 rows) + guide_sections (117 rows) → SQL backup (fallback if prompts unrecoverable)
  • MCP-created items inventory: list of 13 content_items + 9 guides for prompt recovery (see WP3 doc)

  • S174 WP5: Skeleton (all entry points + side tables categorised; open questions flagged).
  • S175 WP1: DRAFT — inventory queries populated; open questions resolved or escalated; restore order locked; reconciliation with rebuild runbook documented; pre-export checklist added; missing side tables added (17 tables not in skeleton).
  • Post-provisioning (S176 — DONE): Project ID mgrmucazfiibsomdmndh, URL https://mgrmucazfiibsomdmndh.supabase.co. Placeholders updated in runbook and matrix.
  • Post-Stage-1 execution: Mark cells with actual restore behaviour; promote to VALIDATED.