Σ Scriptorium Press

Open data & replication

Everything that went into these translations, and everything we used to check them, is downloadable here. The goal is not just trust — it is replication. Take the texts, run the checks, copy the pipeline, and put another ancient author back in circulation.

1 · The texts — sources, old translations, ours

The original-language sources we translated from (public domain: Perseus Digital Library, Niese's Josephus, Cohn-Wendland's Philo, the Latin Library), the classic public-domain English translations we measured against (also free — they are monuments, and deserve reading), and our own editions:

WorkOriginal languageClassic translationPlainspoken (ours)
Homer — The IliadTXT · 1.2 MBTXT · 796 KBTXT · EPUB
Homer — The OdysseyTXT · 961 KBTXT · 653 KBTXT · EPUB
HesiodTXT · 169 KBTXT · 145 KBTXT · EPUB
Herodotus — The HistoriesTXT · 2.6 MBTXT · 1.5 MBTXT · EPUB
PlatoTXT · 6.4 MBTXT · 5.2 MBTXT · EPUB
Plutarch — The MoraliaTXT · 14.2 MBTXT · 4.0 MBTXT · EPUB
JosephusTXT · 6.3 MBTXT · 4.2 MBTXT · EPUB
Philo of AlexandriaTXT · 5.7 MBTXT · 4.4 MBTXT · EPUB
Seneca — LettersTXT · 815 KBTXT · EPUB

All source and classic-translation files are public domain. Our translations are free to read and share; see the colophon for the method and disclosure.

2 · The replication notebook

A runnable Jupyter notebook that recomputes the quality-page numbers live against this site — archaism rates, independence scans, completeness gates. Open it in Google Colab and press run.

📋 Download replication.ipynb Open Colab → upload it

Reproducing the Plainspoken Classics quality checks

Every number on the quality page can be recomputed from public files. This notebook does it live against the site — run it in Colab or anywhere with `requests`. The method is the point: we want people to copy this pipeline and revive more classics.

In [ ]:
import requests, re, statistics
BASE = "https://scriptorium-press.pages.dev"
def fetch(path):
    r = requests.get(f"{BASE}/{path}"); r.raise_for_status(); return r.text
def words(t): return re.sub(r"[^a-z0-9 ]", " ", t.lower()).split()

1. Archaism rate — how old does the free English feel?

Count archaic tokens per 10,000 words in the classic public-domain translation vs ours. Expected (from the quality page): Macaulay's Herodotus ≈ 67.6/10k, ours ≈ 0.4/10k.

In [ ]:
ARCH = re.compile(r"(thee|thou|thy|thine|hath|doth|dost|unto|wherefore|thereof|therein|whither|"
                  r"thither|hither|verily|spake|saith|shalt|wilt|ye|nay|forsooth|whosoever|peradventure|"
                  r"howbeit|betwixt|nigh)", re.I)
for label, path in [("Macaulay 1890", "sources/herodotus-old-translation.txt"),
                    ("Plainspoken 2026", "books/herodotus.txt")]:
    t = fetch(path); n = len(t.split())
    print(f"{label}: {len(ARCH.findall(t))/n*10000:.1f} archaisms per 10k words ({n:,} words)")

2. Independence — is the new translation genuinely new?

Scan for runs of 8+ consecutive identical words shared with the public-domain translation of the same text. Calibration matters: two independent human translations of Herodotus Book 1 share 18 such runs — pure convergence, not copying. Ours ships below that baseline.

In [ ]:
def shared_runs(a, b, n=8):
    wa, wb = words(a), words(b)
    grams = set(tuple(wb[i:i+n]) for i in range(len(wb)-n+1))
    runs, i = 0, 0
    while i < len(wa)-n+1:
        if tuple(wa[i:i+n]) in grams:
            j = i+n
            while j < len(wa) and tuple(wa[j-n+1:j+1]) in grams: j += 1
            runs += 1; i = j
        else: i += 1
    return runs
ours = fetch("books/hesiod.txt"); pd_old = fetch("sources/hesiod-old-translation.txt")
print("Hesiod, ours vs Evelyn-White (1914):", shared_runs(ours, pd_old), "shared 8-word runs (site claim: 0)")

3. Completeness — the paragraph-level ratio gate

Silent omission is the deadliest translation defect. Greek→English expands ~1.3–1.5×; any aligned section far below that is a red flag. This exact gate found (and led us to repair) 11 truncated paragraphs in one book's first edition — documented on the quality page.

In [ ]:
import json as _json
man = _json.loads(fetch("browse.json"))
for slug in ["herodotus", "hesiod"]:
    total = sum(w["w"] for w in man[slug])
    print(f"{slug}: {len(man[slug])} works, {total:,} English words — per-work word counts in browse.json")
print("Full per-section source/English alignment data: the sources/*.txt and books/*.txt pairs above.")

4. Do it yourself

The pipeline: batch the source text (~1,500 words, section-aligned) → a fleet of Claude Sonnet agents translates under one shared charter → mechanical gates check aligned counts and ratios → Claude Opus referees samples against the source → Claude Fable 5 arbitrates findings, rewrites flagged text, and handles what the fleet can't. Orchestrated with Claude Code (Anthropic's agent harness) — subagents and workflows are built in. Method details: https://scriptorium-press.pages.dev/colophon.html — take it, improve it, translate something.

3 · The harness — how this was actually built

The whole pipeline runs on Claude Code, Anthropic's agent harness. The pieces you need to replicate it:

The division of labor came from head-to-head trials, not assumption — the full story is in the colophon, and the measured results in the quality page. If you build one of these for another author or another language, we would genuinely love to hear about it.

4 · The audiobooks — how every hour of audio was made

All ~260 hours of audio were generated locally on one consumer GPU (an RTX 3060) with Kokoro-82M, an open-weight text-to-speech model. Nothing here needs a cloud service or a paid API. The full recipe:

Kokoro is Apache-licensed and runs from Python in a few lines (pip install kokoro soundfile, then generate 24 kHz audio and pipe it through ffmpeg -ac 1 -ar 24000 -b:a 48k). One mid-range GPU renders speech at several times real-time, so a full ancient library is a weekend of compute, not a studio budget.

← back to the library