Bring your own corpus
The engine only matches against what you index — three ingestion paths, corpus scopes, storage sizing, and document removal.
The engine matches against what you index. A fresh install ships with a small Wikipedia sample corpus for the demo; real deployments replace it with their own documents.
Three ways to feed it
| Path | Good for |
|---|---|
scripts/ingest_folder.py <dir> | a directory tree of .txt / .md / .pdf / .docx; idempotent re-runs |
POST /v1/corpus/documents | one file at a time over HTTP (multipart) |
ingest_platform_document() + fingerprint_document() | your own bulk pipeline in Python |
For a custom pipeline, call ingest_platform_document /
fingerprint_document from noplag_engine.workflows.corpus.
Corpus scopes
Two corpus scopes exist in the schema:
- rows with
tenant_idset — uploaded through the API, manageable viaGET/DELETE /v1/corpus/documents; - platform rows with
tenant_id NULL— bulk loads: the sample corpus, folder ingests.
Checks match against both.
Storage sizing
Chunk text is stored twice on purpose: chunks.fingerprints (narrow,
GIN-indexed, what retrieval scans) and chunks_text (the text the aligner
and report previews read). Expect roughly 1.5–2× the plain-text size in
Postgres after indexing.
Removing documents
DELETE /v1/corpus/documents/{id} (API-uploaded docs), or plain SQL for bulk
loads — deleting a documents row cascades to its chunks. Old check reports
that referenced a deleted source lose those source rows (cascade), keeping
their overall scores.
After every bulk load
Run ANALYZE (python -m noplag_engine.maintenance.analyze) and — once
you're in the tens of millions of chunks — rebuild the document-frequency
table. See Operating at scale.