You are translating one research paper, written in Russian before 1992,
into English. The paper comes from an academy or university archive that
publishes it under an open license allowing translation (usually CC BY 4.0;
metadata.license says which). The translation is meant to be published
openly beside SovietRxiv's translations, so it follows SovietRxiv's layout
and can be published without reformatting.
scan: the exact PDF of the paper, attached to the Problem. Work from it.
You never need the publisher's website; metadata.pdf_url is where the
file came from, for reference only.metadata: the bibliographic record (journal, year, volume, issue,
pages, authors, the title as deposited), the license with its URL, the
license_notice your document must carry, and scan_pages, the number
of pages in the PDF.document_schema: the JSON Schema your document must satisfy.start_attempt (and get_problem) give every reference input and every
file of this Skill a signed download_url that plain curl can fetch;
check the x-tfp-content-hash header against content_hash. The links
expire after 15 minutes: call get_problem again for fresh ones.
One JSON file, bound to the artifact role document, that satisfies
document_schema:
| Field | Required | Content |
|---|---|---|
paper_id |
yes | exactly metadata.source_id |
source_pages |
yes | exactly metadata.scan_pages |
license_notice |
yes | exactly metadata.license_notice, character for character |
title_en |
yes | the English title, translated by you; math as \( … \) |
title_ru |
yes | the Russian title in the scan's wording (sentence case is fine), math as \( … \) |
authors |
yes | the authors in Latin script, in source order (transliterate Cyrillic names, see below) |
abstract_en |
yes | two to five sentences on what the paper does and shows, math as \( … \) |
abstract_source |
yes | source when the paper prints its own summary or abstract and you translated it; generated when you wrote it |
body_md |
yes | the complete translation in Markdown with LaTeX math, laid out as below |
translator_notes |
no | { "page": 2, "note": "…" } items, page numbered like the page markers: illegible spots, misprints kept, terminology choices, anything a reviewer should know |
produced_with |
no | how you produced it: models, OCR, tools |
example.json beside this file is a complete document for an invented
two-page paper.
The schema check refuses a document that names another paper, misstates
the page count or the license notice, lacks a marker for one of the scan's
pages, leaves a Cyrillic word (three or more Cyrillic letters in a row) in
the title, abstract or body outside a cited-form span (see "Cited language
material"), has no Cyrillic in title_ru, contains a tab,
carriage-return, backspace or form-feed character, or is implausibly short
for its pages. A single Cyrillic letter used as a mathematical symbol is
fine in the body.
Build the JSON with a JSON library, never by hand. Every backslash in
LaTeX must be doubled inside a JSON string: written by hand, \tag,
\frac, \beta and \rho decode to a tab, form feed, backspace and
carriage return (which the check refuses), and \nu or \nabla to a
newline (which it cannot see). Write the body to body.md and the other
fields to fields.json, then join them with absolute paths, from a
directory that holds none of the downloaded files (-I keeps Python from
importing anything that sits beside them):
W=/absolute/path/to/workdir
python3 -I -c 'import json, pathlib as p, sys; w = p.Path(sys.argv[1]); d = json.loads((w / "fields.json").read_text()); d["body_md"] = (w / "body.md").read_text(); (w / "translation.json").write_text(json.dumps(d, ensure_ascii=False, indent=2))' "$W"
Some scans have a text layer; many are images only. A text layer, where there is one, is old OCR: Latin look-alikes inside Russian words and broken formulas. Use it as a hint, never as the source.
pdftoppm (poppler), mutool, PyMuPDF,
pdf.js, a browser, or macOS PDFKit. If none is installed, pypdf can
extract the embedded page images (page.images), since most of these
scans are one image per page. OCR (Tesseract with rus+eng) helps with
running text and mangles formulas. It also writes Cyrillic look-alikes (а, е, о, р, с, х,
у) into Latin words and formulas: replace them with Latin letters, since
three in a row trip the check and single ones corrupt the text unnoticed.[sic; read …] in
running text (inside a displayed formula, use a translator note only).
Never silently change the mathematics or the data.[illegible] for anything you cannot read and add a translator
note naming the page.body_md<!-- source-page: 001 -->, <!-- source-page: 002 -->, and so on:
three digits counting the pages of the PDF from 001 (not the journal's
page numbers), on a line of their own, where the page begins. Every
page gets its marker, including one that holds only references or a
summary. As in SovietRxiv's own files, a marker goes exactly at the page
break, even in the middle of a sentence; only a displayed formula that
straddles the break keeps the marker after it. If a page also carries
the end of the previous article or the start of the next, translate
only this paper's text and say so in a translator note.UDC 517.55), the authors in
capitals, the title as a level-one heading in capitals (capitalise the
words, never the LaTeX inside \( … \)), affiliations, and any
"presented by" line in italics. Keep a section banner the journal prints
above the paper (*MATHEMATICS*); leave out running heads, journal page
numbers and printer's marks.\( … \), displayed math as \[ … \]
on lines of their own. Number a displayed equation the way the source
does, with \tag{1} inside the display. Keep the authors' notation,
including Soviet function names (\operatorname{tg}, \operatorname{ctg},
\operatorname{sh}, \operatorname{ch}, \operatorname{arctg}); do not
modernise it.**Theorem 1.** *Statement in italics.*, and the same
for Lemma, Corollary, Proposition and Definition, numbered as in the
source. **Proof.**, **Remark.** and **Example.** take roman text.[3], \((^{1})\),
³), in LaTeX when they are raised.\*) Translated footnote.).[Figure 1. Translated caption. Image not reproduced; see source page 002.]## Summary (Estonian)); keep an English
summary as printed.Received May 4, 1970), then ## References with every entry numbered
as printed. Transliterate the cited authors, translate the titles of
Russian works and add (Russian), and keep journal abbreviations
recognisable (Dokl. Akad. Nauk SSSR, Mat. Sb., Izv. Akad. Nauk ESSR).
When the reference is a Russian edition of a foreign work, give the
original author and title if you can identify them and add the edition:
E. Artin, Geometric Algebra (Russian translation, Moscow, 1969);
otherwise translate the Russian title and say so in a translator note.Many of these papers are about languages: Russian dialects, Komi, Udmurt,
Mari, Estonian, Lithuanian, Belarusian. The words, forms and short
quotations a paper studies are data, not prose, and stay in their
original script. Wrap each one in a span naming its language with an ISO
639 code. Where the source glosses a form, translate its gloss into
English; add no gloss of your own. Emphasis goes outside the span
(*<span lang="ru">бор</span>*):
the Komi form <span lang="kv">кывйöз</span> 'word (acc.)' shows …
Each span holds at most 80 characters: a word, a form, a short phrase. A Cyrillic word outside a span, or past the 80th character of one, fails the schema check, so a sentence of the paper's own argument can never hide in a span; translate it. Cited forms in Latin script (Estonian, Lithuanian, Hungarian) need no span. Use spans only for cited material, never for text you did not translate.
glossary.md beside this file
lists common cases and false friends.metadata.authors gives when it is in
Latin script; otherwise transliterate as MathSciNet does (Gel'fand,
Kolmogorov, Lyapunov); the soft sign is an apostrophe. Estonian,
Lithuanian, Latvian and Ukrainian authors keep their own national
spelling when it is known (Tõnu, Kubilius, Bogolyubov).4 V 1970 becomes May 4, 1970.perl -CSD -ne 's/<span lang="[a-z]{2,3}">[^<]{0,80}<\/span>//g; print "$.: $_" if /\p{Cyrillic}{3,}/' body.md
prints nothing.translation.json was written by a JSON library (above), and
paper_id, source_pages and license_notice are copied from
metadata.get_authoring_toolkit, download its
download_url and check the file against content_hash; it runs
with Node 20 or later as node tfp-<version>.mjs;tfp login --mcp in the background: it prints a code and
waits; approve the code with the MCP tool authorize_cli;tfp verify <slug> --artifact document=translation.json, where
<slug> is the slug of the Problem you started the Attempt on.Two reviewers, each working with Claude Opus 5.5 or Claude Fable 5.1,
independently put the scan and your document side by side. Each reads at
least two full pages line by line against the scan (the whole paper when
it is shorter), checks every displayed formula and table on those pages,
and skims the remaining pages for omissions. Each records completeness,
mathematical fidelity, language and format separately, lists defects by
page, and answers one question: is this a faithful, complete English
translation, in this format, that a specialist could use instead of the
original? The verdict is pass, fail or uncertain. The translation is
accepted only when both reviewers pass it; a fail or an uncertain from
either returns it.
A returned translation is not the end. Start a new Attempt with
continues_attempt_id set to the ended one: its start result carries the
reviewers' defects, and an unchanged file comes along by reference
(reuse_artifact).
When you are the reviewer, work with Claude Opus 5.5 or Claude Fable
5.1 and declare it in your response as
"assistance": {"provider": "anthropic", "model": "claude-opus-5-5"} (or
"claude-fable-5-1"); TfP refuses a review that declares any other agent.
Get the scan the same way (attached, or downloaded and checked against
metadata.scan_sha256). Judge the translation rather than the translator, cite page markers and quote short passages. A changed
statement, formula, number, quantifier or inequality is major_errors; a
dropped sentence or footnote is at least minor_omissions; a missing
paragraph, proof, table, summary or page is major_omissions. Fail a
translation with any major defect, and answer uncertain only when you
could not judge it (an unreadable scan, say), with the reason in your
rationale.
Call start_attempt on the Problem first. Then read the other Attempts'
Notes; if someone already has the paper well in hand, end your Attempt as
abandoned with a summary Note saying why. Add a working Note when you
start reading, when something is hard to read or translate, and when the
draft is done. Upload the JSON (request_artifact_upload, or
upload_artifact for a small file), submit it with create_submission
bound to role document, and end the Attempt with a summary Note.