Back to docs
Guide 00

The synthesis pipeline — combining documents, surfacing contradictions

The multi-document synthesis pipeline takes a set of an archive's pages/documents and produces combined wiki pages: each synthesized page unites the sources and surfaces where the sources disagree (contradiction detection), respects the per-run budgets o…

2 min read

The multi-document synthesis pipeline takes a set of an archive's pages/documents and produces combined wiki pages: each synthesized page unites the sources and surfaces where the sources disagree (contradiction detection), respects the per-run budgets of tokens/calls/pages, and touches the filesystem only after selective approval of what gets written.

Community feature (the pipeline runs on the same infrastructure as the chat orchestrator; per-run budgets). Sources: docs/SERVICES.md (the Synthesis domain), docs/USAGE.md, README.md:33. Provenance rows: FACT-CENSUS.md F-SYNTH-1.

How the pipeline runs

The pipeline is orchestrated by runSynthesisPipeline (the synthesisService.ts facade; the body in synthesis/synthesisStages.ts — runPipelineStages, callSynthesisLLMStage, …):

StepWhat it does
1. Entity extractionover the selected corpus (synthesisStages.ts:569)
2. Per-archive pagegeneratePageSummary per page (:282)
3-4. Bottom and decisionthe final blocks with the system prompt (the wiki block's injection: Pass 4 only on the SYSTEM role, synthesisStages.ts:784-788)
ContradictionssynthesisContradictionService.ts: the candidate pairing via Jaccard (the threshold 0.15) + the LLM judge per pair (judgePairContradiction) + the contradiction markers on the pages
Orphans and broken wikilinkssynthesisOrphanService.ts (detectOrphanPages, detectBrokenWikilinks)
WritingsynthesisPageWriter.ts: applyApprovedChanges persists the approved modifications; the source frontmatter (buildSourceFrontmatter) carries the provenance

Budget tracking

BudgetTracker (synthesisBudgetService.ts) bounds tokens / LLM calls / pages per run (config via loadBudgetConfig): the pipeline stops when the budget exhausts — the already-written output stays valid. The budget watchdog parallels the chat orchestrator's.

Selective approval

The synthesis's proposed changes do NOT land automatically: they pass through the approval flow (applyApprovedChanges persists only what the user/approver confirmed). The deterministic preview (the same machinery as wikiWriteService) precedes every write; the proposed pages carry the source frontmatter.

Contradiction detection

Candidate pairs form by similarity (Jaccard, the threshold 0.15) and the suspicious pairs pass to the LLM judge (judgePairContradiction): the result = the contradiction markers on the involved pages (buildContradictionMarker) + the claim summary (extractClaimSummary). The process's fidelity samples weekly (runFidelitySample, Sundays 03:00 — synthesisFidelityService.ts).

Triggers and the job queue

  • Post-OCR: the synthesisTriggerService queue (onOcrJobCompleted) enqueues synthesis runs after OCR completes, with a cooldown (isCooldownActive).
  • The reaper: the synthesisReaperJob scheduler (every 15 minutes) flips orphaned PROCESSING runs to FAILED.

This guide covers the operator surface for the synthesis pipeline; the engineering deep dive lives in the twin post:

Provenance

SectionSource
The facade / stages / budget / contradictionsdocs/SERVICES.md (§ Synthesis + the synthesis* modules) — F-SYNTH-1
Triggers / the reaperdocs/SERVICES.md (§ Schedulers & jobs — synthesisTriggerService, synthesisReaperJob)
The README lineREADME.md:33 (the synthesis line) — F-SYNTH-1
The wiki injection / Pass 4docs/WIKI_SCHEMA_LAYER.md (§ Injection seams — synthesisStages.ts:784-788)

---

Operator reference — Simmetric Chat v0.28.1 (docs refreshed 2026-10-02, census SHA `aca5b8ff`).