Source docs/autopilot.md · 1de96aa

Autopilot

This page is for anyone who launches translations, in the interface or through the automation API, and for administrators who tune how Libris behaves when something goes wrong. It explains what happens between “Translate” and the finished book, how Libris recovers from failures, what “kept in the original” means, where every automatic decision is logged, and how to turn the autopilot off.

With autopilot, a book reaches an exportable output. Every point where a person used to decide (a refused passage, an invalid model answer, a review remark, a proposed glossary term, a provider outage) is decided by Libris or by the model, within fixed limits, and logged with its reason. Only model unavailability stops stage progression; invalid answers remain visible in the report. You can still correct any passage at any time.

When it applies

The autopilot is on by default. It applies to every job that covers a whole book:

  • an import started with its pipeline, in the import assistant;
  • an automation API request;
  • the Analyze and Translate actions on a whole book.

Targeted work stays under your control and keeps its normal behaviour: translating one chapter or one passage, retrying a selection from Summary & recovery, or applying accepted proposals.

Whether a book uses it is decided in this order:

  1. the launch itself ("autopilot": false in POST /api/projects/{id}/jobs);
  2. the book’s own choice: Settings tab of the book › Autopilot (On, Off: decisions wait for a person, or Installation setting);
  3. the installation’s choice: Settings › Autopilot › Run books on autopilot, or the AUTOPILOT_ENABLED environment variable (see configuration).

The stages of a book

  1. Import. The source (EPUB, text chapters, Markdown, HTML, DOCX, or a JSON request) is cut into passages, the unit of every model call. See architecture.

  2. Analysis. Libris reads each passage to build chapter summaries, characters, relations and a narrative state, then consolidates them into the Book Bible. By default the passages are analysed side by side, then each is reconciled with what the passages before it established (parallel analysis); translation starts once the whole volume is analysed. Under the autopilot, a passage whose analysis is refused or keeps coming back invalid is skipped for now, and so is a failed Book Bible batch; both are logged. A chapter with a failed batch stays to consolidate (in the parallel mode too: a synthesis or a merge given up no longer counts its section as consolidated). Before translation, the job asks again for the passages and batches given up, and for passages that arrived meanwhile — once on its own provider, then once on each of its fallback providers (analysis_catch_up in the decision log). Then the proposed glossary terms, series identity links and the Book Bible are decided (see Memory decisions); the Book Bible is validated only when no section is left to consolidate. Last, when the volume’s style sheet leaves fields open, one call proposes values for them from the book (style_proposal, once per volume) and the confident ones are applied (see Memory decisions). Under autopilot, if analysis is still incomplete after those retries, the decision log records it and translation continues. The final report counts missing analyses. Outside autopilot, the analysis_incomplete and analysis_unusable checks still block translation. A translation launched on its own (the Translate button, a batch action, the MCP, the API) first analyses the passages that have none — chapters added since the analysis, a copy for another language taken while the original was being analysed — before it translates a single one.

  3. Translation. Each passage is translated, then improved according to the book’s quality level (see below). Several passages of a book are translated at once, within the provider’s capacity and the book’s Passages worked on at once. Under autopilot, an optional context plan that fails falls back to standard context. A required review, revision or polish tries configured fallback providers, then keeps the available translation if every answer remains invalid. A failed translation enters the recovery ladder.

  4. Convergence rounds. At most AUTOPILOT_MAX_ROUNDS rounds (3 by default), each made of:

    1. the recovery ladder for every failed or untranslated passage;
    2. on the first round, at high or maximum quality, a global consistency check across the book;
    3. the final review: the whole book on the first round (only the new chapters when the job follows up a volume), then only the passages still open and those recovered during the round;
    4. AI arbitration of everything still open.

    Every stage finishes its attempts before the next starts. The loop stops when no passage is failed or open; points still open after the last round remain visible in the report.

  5. Settling. Passages that could not be translated keep their source text and are listed in the report.

  6. Export. The book can be exported (EPUB, text, Markdown…) from the interface, or the API request builds its result and report (see the API guide).

Passages a person corrected or validated are never changed by any of these steps, even while they are still marked “to check”. The round and phase are saved as the job goes: a paused or interrupted job resumes where it stopped, without redoing what is settled.

What each quality level does

QualityPer passageWhole book
fastTranslationFinal review
normalTranslation, then a review that can flag the passageFinal review
highTranslation, review, and a revision when the review found somethingGlobal consistency, final review
maximumTranslation, a polishing pass, then review and revision as highGlobal consistency, final review

At maximum quality the polish comes right after the translation, so that the review reads the polished text and its revision can put back a meaning the polish changed. A polished paragraph that lost more than a quarter of its words (paragraphs of four words or more) keeps its previous text, and a polish that adds an error of the automatic checks (a locked term lost, text left in the source’s script) is refused whole. Each refusal is in the decision log (translation stage, polishing, rejected). A passage whose review had already begun when Libris was updated to this order is finished without a polish; it is not polished and reviewed again.

At high and maximum quality, the book’s Review mode can be Review and revision in one call (REVIEW_MODE=fused for the installation): one model call returns the problems and, if needed, the corrected text, instead of two calls. It applies only to the first review of a machine translation; if the call cannot fit the model’s window or keeps failing, Libris falls back to the two separate calls and logs why.

The recovery ladder

A passage the translation gave up on climbs these steps, cheapest first, until one works:

  1. Informed retry. The same provider is asked again and told why the previous answer failed.
  2. Batch repair. A passage of several paragraphs is translated in groups of four paragraphs, then reassembled.
  3. Sentence split. Each paragraph is cut at sentence boundaries, translated piece by piece, then reassembled.
  4. Reduced context. Only the passage, its mandatory rules (instructions, the job’s instruction, style sheet, locked glossary, confirmed identities, series conventions) and a compact memory of what the passage names (a minimal sheet of each character, with what a reader decided, and the unlocked glossary), with no neighbours, book context or retrieved memory. On a short window the memory gives way first.
  5. The stronger model. The escalation provider of the volume, else of its series, else of the installation: an informed retry, then the sentence split.
  6. Fallback providers. On each fallback provider: an informed retry, then the sentence split. A provider already climbed as the stronger model is not climbed again — it would only spend twice.
  7. Last resort. An existing translation is kept. Otherwise, when answers were refused for their locked glossary terms alone, the one that missed the fewest is kept, checked for fidelity, marked to check and reported (recovery_kept_translation): a missing term does not block the book. In every other case the source text is retained with the list of attempts and shown in the report. The job continues to the next stages.

Rungs 5 and 6 are in that order on purpose. An answer that will not parse, a refusal, a translation that loses its paragraphs: that is a model failing at the work, and the answer to it is a better model. A provider that does not answer at all is an outage, and the answer to that is another provider. Reaching for a stand-in when the first model simply is not good enough at this passage only produces the same failure somewhere else.

Every answer goes through the usual checks (same paragraphs, markers intact, locked glossary respected). Each step is bounded (one call, or one per group), and every outcome is logged.

Kept in the original

“Kept in the original” (source_retained) appears when every translation attempt fails or a person chooses it. The source text then replaces the translation:

  • the passage carries a warning with the reason, and appears in the book’s Autopilot tab under Passages kept in the original;
  • job reports and API results count it as a residual;
  • exports write the source text for it.

Autopilot keeps the original when no model returns a valid translation. The passage remains visible and can be corrected later without blocking the rest of the book.

Left in the source language

A paragraph of more than five words that the model gives back word for word in the source language (the unchanged check), or text left in the source’s script (untranslated), is saved as it is: a name, a quotation or a line kept in the original on purpose are legitimate, and the translation is never refused for it. It is not counted as translated, though. While its alert is open and the text still deserves it, the arbitration cannot close the alert without changing the text, and the passage is a residual like a passage kept in the original: listed under Passages kept in the original with the check’s reason, counted by job reports and API results (completed_with_residuals), and its chapter is not complete in the text exports. Translating the passage, resolving its alert or validating the passage settles it.

The stronger model

The provider kept for the hard cases, and for them only:

  • a passage that comes back to the AI arbitration: an earlier round of the same job arbitrated it and it has open points again (an answer that never validated, an error its text still carries, a remark on its correction). Its next arbitration goes to the stronger model; a first arbitration is always the book’s model’s;
  • a passage no rung of the recovery ladder could translate on the book’s model;
  • a passage the book’s model failed five times in the job (refusals, answers that never validate, errors; a call interrupted by a pause does not count): its next calls go to the stronger model, two of them at most, then the passage is back on the book’s model. The passages around it never leave the book’s model.

No step of the book moves to it: translation, analysis and review stay on the book’s model whatever fails, so the stronger model’s price is paid only where the book’s model gave up. Each use is logged (kind escalation, action upgraded, with the passage). If the stronger model is down, the passage goes back to the book’s model. It is read from the volume (Settings › Autopilot › Modèle supérieur), else from its series (Paramètres de la série › Quand un modèle échoue), else from the installation (Settings › Autopilot, AUTOPILOT_ESCALATION_PROVIDER); changing it takes effect at the next passage. It is never the provider already in use, and naming it as a fallback too does not make it be tried twice.

Fallback providers and outages

When a provider stops answering, Libris moves along a chain of providers, in this order:

  1. the provider the job is using;
  2. the book’s provider;
  3. the book’s own fallback providers (book Settings › Autopilot › Fallback providers);
  4. the installation’s fallback providers (Settings › Autopilot, or AUTOPILOT_FALLBACK_PROVIDERS, names or ids separated by commas).

An outage is first waited out as usual, with growing delays (see Settings › Automatic recovery in configuration), at most AUTOPILOT_OUTAGE_MAX_RETRIES times (5) and AUTOPILOT_OUTAGE_MAX_WAIT_SECONDS in total (3600). After that, or at once when the provider refuses its credentials, the job switches to the next provider in the chain and logs it. The book’s own provider setting is not changed.

When no provider in the chain answers, the job ends failed with the reason (stop_reason = providers_exhausted): it never waits forever.

The same chain serves the cost budgets, with or without the autopilot: when a book’s or an API token’s spending reaches the switch threshold (BUDGET_SWITCH_THRESHOLD, 90 % by default), the job moves to the first provider of the chain that is cheaper than its own (compared on a typical call of 14 000 input and 1 000 output tokens) and logs it (stage budget, action fallback_provider, stop_reason = budget_fallback). With no cheaper provider at the threshold, the job pauses (stop_reason = budget_exceeded, action paused); a job that already moved once goes on with its new provider up to the cap. At the cap itself, only a provider without a price may go on; otherwise the job pauses and resumes once the budget is raised.

AI arbitration

Open points are what a person used to arbitrate: the reviewers’ remarks, the model’s doubts (uncertainties), global consistency remarks, warnings from the automatic checks, and any other unresolved issue on the passage.

  • One model call per passage decides all of its points at once, and only passages with open points are sent, each with its severity and, when it has one, its paragraph. The model returns a decision for each point and only the paragraphs it changes.
  • A remark nothing supports is not sent: one naming a paragraph the passage does not have, one quoting, for its replacement, words found nowhere in the passage, or one whose replacement is the text already there (”?” replaced by ”?”). It is closed and written to the decision log with its motive, in every review as well (the review, the quality judge, the final review, the consistency check). A remark with no replacement stays a warning. The model itself marks a point it rejects because the context contradicts its reasoning.
  • An answer is used only if it decides every point once, if every accepted correction changes the paragraph it is about (only a doubt can be settled as it is), if it rewrites no paragraph that no accepted point is about (unless one is about the whole passage), if no corrected paragraph lost more than 40 % of its text or became an instruction (“Replace X with Y”), and if the resulting text passes the same checks as a translation. A locked glossary term refuses the answer only when the correction loses it: a term the text already missed is no reason to refuse the correction of another point.
  • An answer that fails these conditions after its attempts, like a call that fails (a refusal, an error), decides nothing: the points stay open for the next round, and the last round settles them.
  • After arbitration, the automatic checks run again on the new text; a warning already decided is not raised a second time, but an error the text still carries (a locked term missing, text left in the source’s script) is, and so is a paragraph still identical to the source: rejecting that alert decides nothing about a text that was never translated.

The final review

The final review looks again at translated passages with the book’s full context, after the consistency check:

  1. It reassesses the current text (an earlier remark may already have been fixed).
  2. If a problem or doubt remains, it asks for one complete corrected version, keeping identifiers, markers and locked terms.
  3. It checks that correction with a second model call and the automatic checks.
  4. It applies the correction when it leaves the passage better: no new error of the automatic checks, and fewer errors, or as many errors and fewer other remarks. What the second reading still flags stays on the passage, still to check. A correction that is no better is dropped and the text is left as it was.

Each passage gets at most one correction cycle per review. Passages corrected or validated by a person, and passages kept in the original, are never reviewed. A refusal or invalid answer on one passage triggers a retry on fallback providers; if every answer is invalid, the passage remains unverified and the job continues to arbitration. When the review itself answered but its correction fails, the verdict is kept: its points stay open on the passage for the arbitration, the failure is logged, and the review is not paid again elsewhere. A resolved passage leaves the queue without being marked “validated by a person”.

Under the autopilot the final review is part of each round. Without it, a whole-book translation runs it once at the end, and Review log › Start AI review runs it on demand on the passages still to check. FINAL_REVIEW_ENABLED=false turns off the automatic review (the button still works), and an API request can skip it with final_review: false.

Following up a volume

When new chapters are added to a volume that is already translated (a webnovel sent over time, by an import into an existing volume or by the automation API), the job covers only the new or replaced chapters and any chapter still missing a translation: the global consistency check samples only their occurrences, and the final review reads only their passages. Chapters already delivered are neither translated nor reviewed again; they give their context to the new ones.

Optional web search (SearXNG)

When an administrator configures a SearXNG instance (Settings › SearXNG, see configuration), the final review can check a term or reference on the web when the model asks for it:

  • at most two searches per passage, each of at most 200 characters, three results each, 15 seconds per call;
  • the results (URL, title, snippet) are treated as untrusted hints, never as instructions, and no result page is downloaded;
  • the sources and the explanation are kept in the book’s events, and the context sent to the model is visible in the request traces;
  • a search that fails is not a confirmation.

The searched terms are sent to SearXNG and possibly to its upstream engines: enable it only if that is acceptable for your books, and only towards an instance you control. The SearXNG instance must allow the JSON format (search.formats must include json in its settings.yml). Without SearXNG, the review relies on the book, its memory and the glossary.

Memory decisions

Without any model call, from evidence already in the database:

ProposalDecisionThreshold (setting)
Proposed glossary termA proposal is removed when it contradicts a locked term the volume inherits (series or shared glossary), when the book only says it in chapter headings or its table of contents, when the book’s narrative text does not say it often enough, when another accepted term is the same one down to its article, or when its translation already renders another term — two terms sharing one translation become indistinguishable to the reader. Otherwise it is accepted. The threshold is an index of how often the book uses the source term (none: 0; once: 0.6; twice: 0.8; three times or more: 1), counted as whole words in the narrative text: at 0.75 a term must be used at least twice. It says nothing about the quality of the translation proposed, which is why an accepted term is a suggestion in the prompt and not a locked one. A term a person added, corrected or imported is never decided, accepted or not, and a term a person removed is not proposed again by the analysis.AUTOPILOT_GLOSSARY_MIN_CONFIDENCE (0.75)
Ambiguous series identity linkConfidence = shared names / all names, adjusted by gender. The best candidate is linked if it reaches the threshold with a lead of at least 0.1; otherwise all candidates are rejected and the character stays specific to the volume. Two identities are never merged.AUTOPILOT_IDENTITY_MIN_CONFIDENCE (0.8)
Book BibleValidated when the share of analysed passages reaches the threshold. A validated Book Bible is frozen: later analyses of the volume no longer consolidate anything into it. So chapters added afterwards to the volume reopen a bible the autopilot validated, and the next analysis consolidates them into it; a bible validated by hand is the reader’s and stays as it is.AUTOPILOT_BIBLE_MIN_COVERAGE (0.8)
Chapter whose context is outdated (an earlier chapter’s source changed)The flag is cleared when the job translated or reviewed enough of its passages again.AUTOPILOT_STALE_MIN_COVERAGE (0.5)
Style sheet value proposed from the bookAt the end of the analysis, when the volume’s sheet (its own and its series’) leaves fields open, one call reads the opening of the book, a few passages further on and the Book Bible, and proposes a value for each open field with a confidence and a quotation of the source (honorifics only when the source uses them; a value the sheet does not allow is dropped). A proposal reaching the threshold is written into the volume’s sheet (accepted); below it, it waits for a person in the style sheet screen (rejected). A field a person or the series decided — even while the model was answering (kept) — is never written over. A proposal that fails is logged (skipped) and the translation goes on.AUTOPILOT_STYLE_MIN_CONFIDENCE (0.8)

Decisions a person already took are never revisited. A link rejected by the autopilot is not proposed again when the series is refreshed. The style sheet is the one row that rests on a model’s answer: the proposal asked once at the end of the analysis (stage analysis, kind style_sheet in the decision log); it is not asked again for the same volume, except from Suggest from the book in its style sheet.

The decision log and the report

Every decision is logged with its stage, kind, action, reason, the provider and model involved, and the job and passage concerned. In the interface, the book’s Autopilot tab shows:

  • the current round and phase while a job runs, and any fallback provider in use;
  • the Final report of the last run: outcome, Convergence rounds, Passages kept in the original (each with its reason and links to the passage and its decisions), and the number of logged decisions;
  • the Decision log, most recent first, filterable by stage and by passage.

The same data is available from GET /api/projects/{id}/autopilot?limit=50&offset=0 (optional job_id, segment_id, stage filters; limit up to 500). It returns whether the autopilot is on for the book, the limits in force, the last report (with its job_id, status and finished_at) and the decisions, newest first.

The report stored on the job looks like this:

{
  "outcome": "completed",
  "rounds": 2,
  "residuals": [],
  "reason": null,
  "quality": {"scored": 411, "average": 91.4, "minimum": 40, "to_review": 6, "review_below": 70,
              "bands": {"good": 380, "fair": 25, "weak": 5, "poor": 1}, "histogram": [0, 0, 0, 0, 1, 2, 3, 10, 35, 360]}
}

blocked means the bounded rounds are spent and a passage is still in the source language, a blocking point remains open or a check is inconclusive: the book is not ready to export, and source_passages, unresolved_passages and unverified_checks give the exact counts. A point is blocking when it is an error of an automatic check (text left in the source), or a reviewer’s error that changes what the book says (mistranslation, omission, addition, untranslated text, a locked term) which the arbiter accepted and whose correction could not be applied. Everything else (style, register, grammar, a point no arbiter confirmed) is a point of detail: it is corrected in the round that finds it, never earns another round, and what is left of it is closed on the current text and listed in residual_points. The category is read whatever the reviewer called it (Mistraduction, sens, contresens are a mistranslation, terminologie is terminology), and an error in a category Libris does not know is blocking, with a line in the log, rather than exported as a detail. One accepted error is not blocking either: when the fidelity check refused the arbiter’s rewrite of that very paragraph in two separate rounds, each time quoting the source for the text in place, and no other reason ever kept the correction out, the point is disputed rather than established. It is closed on the text in place and listed in residual_points with "motive": "contested_by_fidelity" ("open_points" for the others). A single such refusal, or one mixed with any other refusal, still blocks. A locked glossary term the text still misses is an error that earns the passage every remaining round, and no longer blocks the book once they are spent: no answer met it, so the passage is closed on its text and listed in residual_points with "motive": "locked_term_unmet" and the term (source → expected translation). Its alert stays open on the quality page until the text has the term or you change the lock. From its second reading of a passage, the review only keeps new points on paragraphs whose text changed. completed_with_residuals means only such points of detail, an analysis, a section or a series decision are left. An API request still ends completed_with_residuals in both cases. Only model unavailability stops automatic stage progression. A blocked report is recounted each time it is read: once you correct or validate the listed passages, the book page shows the new outcome and the Export menu offers the translated EPUB again, without a new run. quality sums up the passage quality scores once the run is settled: the recovery steps, the rejected or deferred arbitrations lower a passage’s score (an applied correction does not), so the book’s Quality tab lists first the passages the autopilot had the most trouble with.

Cost

The report of the last run (GET /api/projects/{id}/autopilot) and the completion report of an automation request carry cost: the estimate made when the job started against its real cost, with the book’s budget and the budget switches (see the API reference).

The autopilot only spends calls where something is wrong. The recovery ladder only concerns failed passages; arbitration makes one call per passage that has open points; later rounds only review the passages still open or just recovered. The memory decisions make no call at all.

Settings

Administrators set the installation’s behaviour in Settings › Autopilot. Values saved there apply to the next decision without a restart and win over the environment variables until you choose Go back to the environment values (see settings changed in the interface).

SettingEnvironment variableDefault
Run books on autopilotAUTOPILOT_ENABLEDtrue
Convergence rounds at mostAUTOPILOT_MAX_ROUNDS3 (1–10)
Fallback providersAUTOPILOT_FALLBACK_PROVIDERSnone
Quality judge (quality.md)QUALITY_JUDGE_PROVIDERnone
Waits for an outage at mostAUTOPILOT_OUTAGE_MAX_RETRIES5
Waiting for an outageAUTOPILOT_OUTAGE_MAX_WAIT_SECONDS3600 seconds
Minimum confidence of a glossary termAUTOPILOT_GLOSSARY_MIN_CONFIDENCE0.75
Minimum confidence of a series identity linkAUTOPILOT_IDENTITY_MIN_CONFIDENCE0.8
Minimum coverage of a Book Bible updateAUTOPILOT_BIBLE_MIN_COVERAGE0.8
Minimum coverage of an outdated chapter contextAUTOPILOT_STALE_MIN_COVERAGE0.5
Minimum confidence of a proposed style sheet valueAUTOPILOT_STYLE_MIN_CONFIDENCE0.8

The minimum analysis coverage before translating (ANALYSIS_MIN_COVERAGE, 1) is not on this screen: it is set by its environment variable only (see configuration).

Each book can override the on/off switch and add its own fallback providers in its Settings tab. The same book settings are available as config.autopilot and config.fallback_provider_ids in PUT /api/projects/{id}.

Without the autopilot

Turn the autopilot off for a book (or for the installation) when you want to take the decisions yourself. The pipeline then behaves like this:

  • Invalid answers. An answer rejected by the checks (missing paragraphs, broken markers, locked glossary not respected, invalid JSON) is asked again with the reason, up to three times; network errors get up to five attempts. An answer that is not JSON at all is recognised as such: prose is asked again as the JSON object alone, an object cut at the output budget is asked again shorter, and a key Libris did not ask for is simply ignored instead of losing the answer. A translation or revision that still fails is then repaired in groups of four paragraphs (passages of 2 to 128 paragraphs), each group keeping its context, identifiers and markers. Groups already repaired are reused after an interruption, and only the complete, validated result replaces the passage’s translation.
  • Refusals. A content refusal is retried once; after the second refusal the passage is marked refused. A refusal during the analysis blocks the job until you act.
  • Failed passages. A passage still failing after its attempts keeps its existing text, is flagged as an error (or refused) in Quality, and the job goes on with the next passage. Ten failed passages in a row stop a job launched with Translate (a successful passage resets the count, and resuming resets it too); a pipeline started from the import assistant does not stop.
  • Failed improvements. A polish, a review or a revision whose answers are still invalid after their attempts and repair (one that keeps dropping a locked term, for instance) is given up: the valid translation already saved stays, the passage finishes, and it carries the warning « Step not applied after invalid model answers » while the decision log keeps the reason. A provider outage or a refusal during these steps still stops the passage as above.
  • Automatic recovery. A pipeline started from the import assistant retries its failed and untranslated passages once more after the translation. What is left then waits for you.
  • Summary & recovery. This tab separates the last job’s state from the real coverage of the book: translated, missing, retained in original, open, unresolved alerts and protected human choices. Filter the passages to recover (errors, refusals, not started, blocked), select up to 200, choose a Recovery provider and Retry selection. The server checks the selection and skips protected passages; another job on the book must finish or be cancelled first. The book’s own provider does not change.
  • Provider outages are waited out with growing delays for as long as needed, and a provider that refuses its credentials blocks the job until you fix it and resume.
  • Open points wait in the Review log. Each AI remark shows its doubt and proposed correction. Accept this proposal replaces only the paragraph concerned and keeps the EPUB markers; Reject this proposal keeps the current text. Both create a protected human correction; once the last proposal of a passage is decided and nothing else is open, the passage leaves the queue. The queue stays stable while jobs run, so drafts are not lost. Final editorial validation remains a separate action. When you accept a free-form suggestion that did not keep the internal markers, Libris asks the book’s provider for a structured correction of that paragraph only, checks it as it checks a translation (markers, and the locked glossary of the book, its series and the shared glossaries: an answer that drops a locked term the paragraph had is asked again), and keeps the current text if the answer is still invalid or the passage changed meanwhile. That text is the model’s, which nobody has read yet: on a machine passage it is saved as machine text (origin accepted_proposal), which the checks, the final review and the arbitration still look at, not as a protected human correction; a passage you had already corrected stays yours. It is never validated.
  • A refused or failed passage can be resolved in the editor in three ways: type a human translation; give a Human analysis (a summary useful for continuity) in the inspector; or choose Retain source for export. Retaining the source does not replace a missing analysis. When the Book Bible synthesis itself is refused, validating a human Book Bible with a non-empty summary lets the job resume. A job stopped as analysis_unusable or analysis_incomplete is restarted the same way: fix what made the model answer badly, then Resume the job (or launch the analysis again). Resuming asks again for what was given up — the passages left without an analysis, the Book Bible batches that failed — and rebuilds a Book Bible no run managed to write, chapters already marked consolidated included; the passages already analysed are kept, and the translation follows once the memory is there.
  • Exports. A normal EPUB export requires a complete translation. Partial EPUB · originals retained puts the source text where the translation is missing, under a distinct file name. The Coverage report lists passages without analysis, without translation and kept in the original; a retained original is never presented as a validated translation.

When a job stops

SituationWhat happens
You pausepaused; it resumes only when you resume it.
A book or API token budget is reachedThe job moves to a cheaper fallback provider (budget_fallback), else paused with stop_reason = budget_exceeded; resuming is refused until the budget is raised.
You cancelcancelled; saved results are kept, and the book can be launched again.
The worker stops cleanlyCalls in flight are interrupted; the job goes back to pending at its checkpoint.
The worker crashesAnother worker takes the job over once its 60-second lease expires.
Network error, timeout, HTTP 429 or 5xxwaiting, with a retry scheduled after a growing delay (60 seconds up to one hour by default; a provider’s Retry-After is honoured up to 24 hours). Under the autopilot, the next fallback provider takes over after the bounded wait.
The provider refuses its credentialsblocked until you fix the provider and resume. Under the autopilot: the next fallback provider, or failed when none is left.
No provider answers any more (autopilot)failed with stop_reason = providers_exhausted and the reason.
Refusal during the analysisblocked (content_refusal) until you act. Under the autopilot: the passage is skipped and the decision logged.
Refusal during the translationA second attempt, then the passage is marked refused and the book goes on.
Invalid JSON or structureBounded retries with the reason (prose asked again as JSON only, an answer cut at the output budget asked again shorter), repair in groups, then a localized error on the passage.

The worker checks its lease every two seconds, so a pause or cancellation interrupts all the calls in flight for the book almost at once. Every write is protected by the passage revision and the lease holder: a late answer never replaces a human correction or a cancelled state. Passages already finished are skipped when the job resumes, and interrupted passages restart from their last saved step.

EPUBCheck still runs at export time: full coverage is not a certificate of a valid EPUB, and a model review does not guarantee literary fidelity.