Generated from folio-assistant-core/processes/library/ingest-l1-completeness-gate.bpmn by gen-processes-viz.ts — do not edit here. All processes

Ingestion subprocess — the L1 completeness gate

Process_L1Gate · advisory · 4 step(s)

Decide whether the derived content is complete enough to promote to the L1 graph, and who says so. folio-assistant — Ingestion subprocess — the L1 completeness gate.

Source of truth: this file. Open it in bpmn.io, Camunda Modeler, or any other BPMN 2.0 tool. The SVG under docs/assets/img/workflows/ is generated from it by bun run cat render:bpmn — never hand-edit the SVG.

The extension on an activity names the folio-assistant skill that implements it; marks a step that reads or writes the shared work plan in beans/.

BPMN diagram: Ingestion subprocess — the L1 completeness gate

How it connects

Lanes — who acts

lanerolewhat it does here
Ingestion Engine (agent, runs unattended)ingestion-agentRuns both QA checks unattended and hands off exactly where the role’s persona says it must: Gateway_Drift’s ‘drift’ branch leaves this lane the moment a passage needs a judgement about which of two readings is right, rather than guessing — but Task_Verdict, which records the outcome either way, stays in this lane, so Lane_1 adjudicates a single passage while this lane still owns the completeness verdict as a whole.
Reviewer (SME or editor)reviewerThe only human involvement anywhere in this subprocess: Lane_0 runs both checks and records the verdict unattended, so this lane exists solely for the single case machine QA cannot resolve on its own — a flagged passage where round-trip translation produced two different readings and somebody has to say which is right.

Steps

Every one of the 4 step(s) is documented.

steplaneskill / sub-processwhat it does
Is every derived artefact present?
Task_CheckDerived
Ingestion Engine (agent, runs unattended)document-intakeL1 source to L1 KG is NOT complete while a required derived artefact is missing. This is the gate that makes the derivation steps obligatory rather than aspirational.
Round-trip translation QA
Task_RoundTrip
Ingestion Engine (agent, runs unattended)translation-manager
untainted-verification
Back-translate each localized narrative into its source language and compare the meaning, to catch semantic drift and bad terminology that a forward-only check cannot see. Agentic, by the owner’s ruling of 2026-10-06 (bean ktt2). Two parties are kept apart under untainted-verification: a back-translator that sees ONLY the target-language text, and an adjudicator that sees the original and the back-translation and rules. The verdict is recorded per block, under criterion translation-semantic-roundtrip in the block’s <block>.<locale>.translation-qa.json sidecar, by the translation-roundtrip-record Tool (translation-manager §5). A terminology miss is a different criterion, translation-terms-preserved (acronyms, numbers, URLs that must survive), so Gateway_Drift can tell the two apart. Never close this step by reversing the PO’s msgid→msgstr map: that returns the source exactly and scores 1.0 always. An empty translation-semantic-roundtrip entry list means “not yet run”, which is never a pass.
Adjudicate the flagged passage
Task_FlagDrift
Reviewer (SME or editor)calls Adjudication
document-intake
adjudication
A machine can detect that two readings differ. Which one is right is a human call.
Record the L1 completeness verdict
Task_Verdict
Ingestion Engine (agent, runs unattended)document-intakeRecord the completeness verdict in three states — met, unmet, or not yet derivable — as bun run cat check:l1-complete reports it. Not-yet-derivable is never a pass. An unmet verdict opens a bean and returns to derivation; only a met one lets the entry into library/.

Decisions

Every one of the 2 decision(s) is documented.

decisionwhat decides itbranches
Drift or bad terminology?
Gateway_Drift
Answered by the round-trip translation QA: did it flag semantic drift or a terminology miss? drift sends the passage to a person to adjudicate, since which reading is right is a human call; clean records the verdict directly.drift → Adjudicate the flagged passage
clean → Record the L1 completeness verdict
Which reading was right?
GW_DriftOutcome
All three converge on Task_Verdict, and that is deliberate rather than the codes being decoration: this lane adjudicates ONE passage while Lane_0 still owns the completeness verdict as a whole, so the outcome of a passage is a REASON recorded against that verdict, never a different next step. The same shape criterion-adjudication uses, where three outcomes converge on one write because what makes an outcome legitimate is that its reason was recorded.
What differs is what gets written and what it obliges. real is drift to fix in the translation. spurious is a false positive, and recording it is what stops the same passage being re-flagged every run. source-wrong points at the SOURCE rather than the translation — the one answer that sends work out of this process entirely, because no amount of re-translating a wrong source produces a right target.
the drift is real → Record the L1 completeness verdict
false positive → Record the L1 completeness verdict
the SOURCE is wrong → Record the L1 completeness verdict

folio-assistant — code under the Apache License 2.0, documentation under CC BY 3.0. Generated schema and API references are rebuilt from source on every push to main.

deployed b08c961 · 2026-10-23T23:11:09Z