Repository navigation
Conversation
- Attribute documents and carry enabled siblings forward without embedding them again. - Refuse stale pgvector promotions and preserve shared engine-switch rebuilds. - Document migration and lifecycle rules, with memory and pgvector regressions.
- Persist dedicated ownership in pgvector and a separate Typesense collection. - Preserve user columns and reject legacy metadata as pipeline provenance. - State the destructive migration sequence and verify source, storage and copy paths.
- Keep Typesense reads and copies unattributed without extra writes or credentials. - Declare provenance support per writer and keep memory and pgvector contracts. - Document the maintenance rebuild after a Typesense copy switch.
Cover all-failed runs with enabled siblings and sibling-copy failures. Assert that both leave the served generation intact, and verify the tests reject broken safeguards.
Record each document embedding model alongside pipeline ownership, including an idempotent nullable pgvector migration. Reject incompatible siblings before ingestion and recheck copies before promotion. Preserve model provenance on compatible engine copies and re-embed unknown or different models. Cover model changes, single-pipeline replacements, matching models, persistence and copy failures with regressions and sabotage checks.
|
The review on #125 asks whether this PR could follow ADR 0042's ownership rules as an interim step on today's tables (0042, Ingestion runs). I agree, and read the code against them. Take a dataset filled by two pipelines, A and B:
One more, which the description doesn't mention: with siblings, a successful run that lists zero documents now promotes ( Could this PR keep a disabled pipeline's documents, remove a deleted pipeline's documents only by an explicit removal, and refuse rather than drop when ownership is unknown? Then 0042 can point to it as the interim step. |
Fixes #107.
What
A normal pipeline run now keeps the documents of the dataset's other enabled pipelines, so a dataset can be filled by several pipelines. Engine switching (ADR 0025) already re-ingests several pipelines into one generation; normal runs now preserve them too.
IndexDocument.pipelineattribute, separate from source metadata.kn_docs.pipelinecolumn, added by an idempotent migration. Existing rows stay NULL.ingestion_pipeline, or anything else, is ordinary metadata. It is never read as ownership, and fresh attribution never overwrites it.runIndexIngestwrites the run's fresh documents into a new generation. It then streams the active generation and copies the documents owned by enabled siblings, with their stored vectors, chunks and phrases. No sibling source is fetched and nothing is embedded again. If a sibling has the same document id, the fresh document wins.IndexWriter.promoteIfActive(dataset, generation, expected), promotes only if the active generation is still the one the run read.kn_activeadvisory lock.readorpromoteIfActiverefuse a multi-pipeline run before preparing or embedding anything, with an explicitunsupportederror, rather than losing data. That includes Typesense today. Single-pipeline runs on them are unchanged.pipelineattribute.preservesPipeline: false), so a copy from Typesense yields unattributed documents.Upgrade note
On an existing dataset with several pipelines, stored documents have no ownership yet. The first promotion after upgrade therefore drops the other sources' documents until each pipeline has run once. Every source must be available. The sequence, documented in
docs/api/datasets.mdand ADR 0025:Datasets with one pipeline are not affected. Today such datasets already show only the last pipeline's documents, so this is not a regression. But it is destructive for whatever happens to be in the active generation.
Open questions
Tests
IngestionService→indexIngestionBackend→runIndexIngest→ writer:rowMapping→databaseSource→runIndexIngest):ingestion_pipelinesurvives as metadata;Both run on memory and pgvector, and are skipped only where an adapter declares no support.
tsc -b,tsc -p tsconfig.test.json, lint, format and boundaries are clean. Vitest over apps/api, packages/ingest, packages/providers-* and packages/port-knowledge: 1,854 passed, 12 skipped.Draft, for review.
Independent verification
A separate verifier found three issues.
kn_docs.embedding_modelcolumn). A carry-forward over a sibling with a different or unknown model is refused with a 'run a combined rebuild' error. Copy switches re-embed when the models differ. This answers open question 6.