Skip to content
ferrumanPublic

About

Codicora · 6. Translator. Literary EPUB translation pipeline: translate, edit, keep terminology consistent, critique, repair, validate.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

46 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pixel-art EPUB translation pipeline running through a retro terminal

Trucheman

Translate books, not just strings.
An open-source literary translation pipeline for EPUB books, not an LLM wrapper:
translation → literary editing → book-wide consistency → independent critique → selective repair → validated EPUB.
Local-first and resumable.

CI status Container status MIT license Node.js 24 or newer Docker Compose

Important

Trucheman is pre-1.0 and under active development. Keep backups of source books and local job data when upgrading.

See it in action

Trucheman importing, translating, validating, and reporting usage for an EPUB

The demo uses the deterministic local provider: no API key, network request, or staged mockup. It runs the same import, translation, editing, build, validation, and reporting flow used by a live provider. It was recorded in the dark workbench theme; the app now opens in the light field theme, and the switch at the foot of the rail flips between the two (remembered per browser).

What the pipeline changes

One paragraph from H. P. Lovecraft's The Call of Cthulhu (1928, public domain), taken from a real Trucheman job. Both stages ran deepseek-v4-flash; nothing was hand-edited.

Then the men, having reached a spot where the trees were thinner, came suddenly in sight of the spectacle itself. Four of them reeled, one fainted, and two were shaken into a frantic cry which the mad cacophony of the orgy fortunately deadened. Legrasse dashed swamp water on the face of the fainting man, and all stood trembling and nearly hypnotized with horror.

After translation — accurate, but reads like a translation:

Затем люди, достигнув места, где деревья становились реже, внезапно увидели само зрелище. Четверо из них пошатнулись, один упал в обморок, а двое разразились неистовым криком, который, к счастью, заглушила безумная какофония оргии. Леграсс плеснул болотной водой в лицо упавшему в обморок, и все стояли, дрожа и почти загипнотизированные ужасом.

After literary editing — same meaning, native prose:

Затем люди, добравшись до места, где деревья росли реже, внезапно увидели само зрелище. Четверо из них пошатнулись, один лишился чувств, а двое исторгли безумный крик, который, к счастью, заглушила дикая какофония оргии. Леграсс плеснул болотной водой в лицо потерявшему сознание, и все стояли, дрожа и едва не загипнотизированные ужасом.

The editor removed the repeated clinical "упал в обморок", replaced the "reached a spot where the trees became thinner" calque with how a Russian narrator would put it, and fixed the awkward "почти загипнотизированные". The consistency stage then keeps names such as Леграсс identical across chapters, and the optional critic audits every edited segment and repairs only validated findings. Run npm run trace:segment on any job to see the same source → draft → edit → audit → repair chain for any paragraph.

For a whole book rather than a paragraph, see examples/call-of-cthulhu: the complete v0.2.0 run on Lovecraft's The Call of Cthulhu — source and output EPUBs, every critic finding and repair, the consistency and usage reports, five blocks traced stage by stage, and an honest list of what the run got wrong.

Why Trucheman?

EPUB-aware Preserves book structure and formatting instead of treating an EPUB as one giant text file.
Literary pipeline Separates translation, editing, consistency, optional critique, and targeted repair.
Local-first Keeps source books, checkpoints, reports, and generated EPUBs on your machine.
Safe to interrupt Resumes durable jobs without paying for completed provider calls twice.
Standard or Batch Runs immediately through Chat Completions or asynchronously through the OpenAI Batch API.
Validated output Checks archive safety, rebuilt structure, untranslated fragments, consistency, and EPUB conformance.
Visible model usage Reports request and token totals for every pipeline stage and exact model.

Quick start

You need Docker Desktop or Docker Engine with the Compose plugin.

git clone https://github.com/ferruman/Trucheman.git
cd Trucheman
cp .env.example .env
docker compose up -d

Open http://127.0.0.1:4173. Without provider credentials, Trucheman uses its deterministic local provider, so you can safely explore the complete workflow first.

For live translation, add your provider keys and models to .env, then restart:

docker compose restart

Job data survives container replacement in the trucheman-data volume. Keys are mounted through Docker Compose secrets, the service runs as a non-root user, and the port is exposed only on the loopback interface.

docker compose logs -f                 # follow startup and jobs
docker compose pull && docker compose up -d  # update
docker compose down                    # stop without deleting books

Do not run docker compose down -v unless you intend to delete all local Trucheman data. The Docker guide covers installation, updates, backup, and restore.

The pipeline

Import → Inspect → Translate → Literary edit → Consistency → Build → Validate
                               ↘ Critic → selective repair ↗
  • Standard quality translates, edits, and applies book-wide consistency decisions.
  • High quality additionally audits every edited segment and repairs only validated medium- or high-severity findings.
  • Standard processing starts provider requests immediately.
  • Batch processing submits durable asynchronous work to the official OpenAI Batch API, which can reduce provider cost at the expense of latency.

Pausing or restarting Trucheman preserves completed checkpoints and submitted batch identifiers. Changing a quality mode keeps reusable work whenever the pipeline boundary allows it.

Language support

The UI offers English, Russian, German, Polish, and Japanese in any direction. The pipeline itself is language-generic: every stage receives the source and target language and works from the model's own knowledge. Language modules add deterministic rules on top of that:

Module Adds
Russian (target) Typography (ё, «ёлочки», dialogue dashes), name-ending awareness for consistency checks, written-number detection, an EPUB audit, and agreement repair.
Japanese (source) Vertical-to-horizontal layout conversion, furigana-driven readings, honorific and name-order policy, sentence-final particle handling, smaller batches.
Japanese → Russian Polivanov transliteration rules.

English, German, and Polish currently run on the generic pipeline alone. Everything shipped so far has been exercised on English → Russian and Japanese → Russian books, and the regression corpus covers those two pairs; treat other directions as untested and start with a short book. Adding a language is a registry entry plus optional capabilities, described in Language modules.

Provider configuration

Translation, literary editing, critique, and consistency can use independently configured provider profiles. The built-in openai-chat transport speaks the OpenAI-compatible Chat Completions protocol; each profile can select another registered transport independently. A minimal DeepSeek configuration looks like this:

TRUCHEMAN_TRANSLATION_API_KEY=your-key
TRUCHEMAN_EDITING_API_KEY=your-key
TRUCHEMAN_TRANSLATION_TRANSPORT=openai-chat
TRUCHEMAN_EDITING_TRANSPORT=openai-chat
TRUCHEMAN_TRANSLATION_MODEL=deepseek-v4-flash
TRUCHEMAN_EDITING_MODEL=deepseek-v4-flash
TRUCHEMAN_CRITIC_MODEL=deepseek-v4-flash
TRUCHEMAN_CONSISTENCY_MODEL=deepseek-v4-flash

The corresponding *_TRANSPORT variables are also available for critic and consistency. Repair uses the editing transport. Application services call a single provider gateway; a new API protocol is added as a registry adapter without changing the translation pipeline.

Omitted critic settings inherit the editing profile. Omitted consistency settings inherit the translation profile. Restart the service after editing .env.

Using one model for every stage is supported and is the simplest way to start. For stronger production results, configure separate models by role:

  • a faithful, cost-efficient model for translation;
  • a stronger prose model for literary editing and repair;
  • an independent critic model, preferably from a different model family, to reduce correlated blind spots;
  • a consistency model chosen for structured reasoning over terminology and entities.

Validate a model combination on a short representative chapter before committing a whole book; different languages and genres can favor different combinations.

Batch mode requires the official https://api.openai.com/v1/chat/completions endpoint for every configured profile and compatible OpenAI models. Trucheman rejects other endpoints before uploading book text.

[!NOTE] The live translation pipeline has been tested with OpenAI and DeepSeek APIs. Other OpenAI-compatible providers and models may work, but are not part of the supported compatibility baseline yet; try them on a small book first and keep the source EPUB and job data backed up.

Drive it from an AI assistant

Trucheman ships an MCP server, so Claude Code, Claude Desktop or any MCP client can run the whole pipeline in conversation: "translate this EPUB into Russian, high quality" → the assistant uploads the book, starts the job, waits, and hands back the report and the finished file. The repository's .mcp.json registers it for Claude Code; for other clients, the command is npm run mcp with TRUCHEMAN_URL pointing at a running instance (default http://127.0.0.1:4173).

Tool Does
translate_book create job → upload .epub → set quality and instructions → analyze → start; paid, so it needs confirm: true after the author agreed
translate_workspace workspace mode: a Codicora project's edited/ (else manuscript/) → a job → analyze → start; without confirm or delegation it only describes the run and its worst-case cost
export_workspace write a completed workspace job into localization/<lang>/
wait_for_job block until the job finishes or a timeout passes; call again if it is still running
job_status status, stage, batches done
job_report validation, EPUBCheck, critic findings and repairs, consistency, usage per model
download_output save the translated EPUB to a path
control_job pause, resume, or retry; a retry pays again for failed work, so it needs confirm: true, or delegation + workspace
list_jobs every job on this instance

The MCP server is a client of the same local HTTP API the browser UI uses; it holds no credentials and adds no second way into the pipeline.

Delegated runs (../DELEGATION.md). translate_workspace with delegation: "<id>" runs without a per-run confirmation when the author's authority/delegations.json in that project allows trucheman.translate and its spending limit covers the worst case. Trucheman records tokens but has no price table, so the worst case is the source's characters × TRUCHEMAN_MAX_USD_PER_MILLION_CHARS (USD per million source characters for the whole pipeline, its own internal retries included — set it conservatively); without it a delegation covers no run and the author confirms directly. The worst case is reserved against the shared budget in authority/trucheman.jsonl before the job is created and started (under the suite's budget lock, so two runs cannot together exceed the limit), with the agent as performed_by. The job carries that authority: before every model call — and before a start, resume or retry — Trucheman re-reads the delegation, and a delegation that expired, was revoked or was edited since refuses the next call and says why. resume then needs confirm: true or a current delegation + workspace. A control_job retry re-sends work that may already have been paid for, which the first booking does not provably cover: under a delegation it books the worst case again, against what is left, and is refused when that does not fit.

The web server refuses requests whose Host is not loopback (when bound to loopback, the default) and cross-origin writes, so a web page cannot drive a paid job.

Privacy and boundaries

Trucheman is a single-user local application. It stores books and job state locally, but a live provider run sends eligible book text to the APIs you configure. It does not provide authentication and must not be exposed directly to the public internet.

Use only DRM-free books you have the right to process. Never commit .env, source books, or local job data. Report vulnerabilities privately according to SECURITY.md.

Development

Requirements: Node.js 24 or newer.

npm install
npm run typecheck
npm test
npm run build
npm run dev

The development server listens on 127.0.0.1:4173. Copy .env.example to .env.local for local provider credentials; .env.local takes precedence over .env.

The versioned literary regression corpus uses public-domain passages from Alice's Adventures in Wonderland and Botchan, paired with deliberately flawed repository-authored Russian drafts:

npm run eval:literary:golden -- --limit 5 # inexpensive smoke sample; no gate
npm run eval:literary:golden             # full corpus; enforces the 85% acceptance floor

These commands use the configured editing provider and write ignored reports under eval-results/. Source provenance is recorded in tests/fixtures/NOTICE.md.

Project docs

License

Trucheman is available under the MIT License.

About

Codicora · 6. Translator. Literary EPUB translation pipeline: translate, edit, keep terminology consistent, critique, repair, validate.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages