TECHNICAL CASE STUDY / BUILD YOUR HOME

How I used LLMs to turn 219 construction notes into 14 localized books.

Language models helped draft and localize a 227-page book. Stable source IDs, hashes, checkpoints, and validation kept the work traceable and recoverable.

01 / RESULT AND CONSTRAINT

219 notes became one source book and fourteen localized editions.

The delivered system produced a 227-page Croatian book with 88 illustrations, then generated fourteen localized books and storefronts. Every source note had a recorded destination when the source edition was released.

219SOURCE NOTES TRACKED
227PAGES IN THE SOURCE BOOK
14LOCALIZED EDITIONS
0UNMAPPED NOTES AT RELEASE

The input was a client’s collection of construction notes: explanations, decisions, warnings, comparisons, personal stories, tables, image requests, prices, and local procedures. LLMs helped turn this material into prose and later into other languages.

The notes did not stop changing when the first book was finished. The client could send a correction, a new lesson from the building site, or a replacement recommendation as another note. That note had to enter the same system, update the relevant part of the Croatian book, and then flow into every affected localization. The notes therefore remained the source of truth; the manuscript and PDFs were derived outputs.

The main constraint was completeness. A model could produce a convincing chapter while silently dropping a requested comparison, safety qualification, or illustration. Reading the prose was insufficient because fluency gives no indication that an input was omitted.

ACCEPTANCE CRITERIA

Every note needed a recorded destination. A new or edited note had to invalidate the affected output without forcing a complete rebuild.

The source notes and content cards remain authoritative before and after publication.

The solution was to treat publishing as a build: structure the source, generate prose from controlled units, validate the result, and version every released artifact.

02 / NOTE-TO-CHAPTER TRACE

Each request received an identity before drafting began.

Each source note received a stable ID such as N-0219. I converted it into a content card that recorded the author’s intent, the outputs it requested, its destination chapter, claims that needed verification, and the state of any requested visual.

Related cards became a chapter brief before a model drafted or revised prose. One note could request several outputs in different chapters, so each requested output was tracked separately. The simplified example below shows why that distinction matters.

REPRESENTATIVE EXAMPLEOne note contains four separately testable requests
SOURCE NOTE / N-0XX

Compare three wall systems. Explain when each is used, show cost, speed, thermal performance, and trade-offs in a table, record why I chose one, and add a labelled wall section.

N-0XX / D1TECHNICAL EXPLANATIONDefine each system and say when it is used
N-0XX / D2COMPARISON TABLERows: systems. Columns: cost, speed, insulation, trade-offs
N-0XX / D3AUTHOR’S DECISIONState the selected option and preserve the first-hand reason
N-0XX / D4ILLUSTRATIONA labelled wall section, tracked in the image manifest
CHAPTER BRIEF

Definitions → evaluation criteria → comparison table → author’s decision → diagram

All four deliverable IDs remain attached when the prose is drafted.
MANUSCRIPTReadable chapterSource IDs remain embedded
COMPLETENESS AUDIT4 of 4 mappedA missing D4 fails the audit
LOCKED RELEASEVersioned PDFFixed source and checksum
This is a representative example, not a verbatim client note. The intermediate cards separate completeness from writing quality: a fluent chapter cannot pass while one requested output remains unmapped.

03 / LLM, CODE, AND HUMAN ROLES

The LLM was one component of the system.

The brief controls reading order while the deliverable IDs preserve the link to the note. In the example above, the explanation can move before the comparison and the author’s decision can move after it. If the illustration is missing, the audit still reports N-0XX / D4 as incomplete.

LLMs

Drafted and revised prose, translated content units, and performed a separate target-language copy-edit.

DETERMINISTIC CODE

Tracked IDs and hashes, validated returned units, saved checkpoints, rendered PDFs, and built release manifests.

HUMANS

Set the structure, checked claims and sources, judged voice and usefulness, reviewed pages, and approved releases.

This division matters because the three kinds of work fail differently. An LLM can omit or alter content. Code can enforce structure but cannot judge whether a story belongs in the book. A human can judge the result but should not have to compare fourteen books with 219 notes by hand.

By source version 0.10.75, every note had a destination and the Croatian edition was locked for release. “Locked” describes that build, not the end of the source. When a note changes later, its hash changes; the system marks the dependent card, chapter, and localized units as stale while reusing everything whose hash still matches.

04 / FAILURE RECOVERY

Every batch had to be safe to reject and rerun.

Long runs timed out or returned malformed JSON. Some responses omitted a key, changed an ID, reformatted a table, or returned 19 units after receiving 20. Good prose inside a response was irrelevant if the batch was incomplete.

Each unit carried an ID and a SHA-256 hash of its exact source, both of which the model had to return. The runner followed the same sequence for every batch:

01 / SELECTLoad only units whose current source hash has no verified output.

02 / REQUESTSend the units with a strict response schema and protected values.

03 / VALIDATECheck the complete ID set, hashes, numbers, protected strings, Markdown shape, and omit rules.

04 / COMMITWrite the verified batch to a temporary file and rename it atomically.

05 / RECOVERReturn the exact validation error, retry, and split a repeatedly failing batch into smaller halves.

A session cost ceiling stopped unattended work. After a timeout or manual stop, the next run skipped every verified unit and resumed at the first missing or stale hash.

Accepted output is cached by source hash; rejected output never enters the build.

05 / LOCALIZATION AS A BUILD

The localization rules had to cover local advice.

The source contained Balkan prices, procedures, public services, and examples. A literal translation could present them as advice for a German, French, or British reader. The international edition profile removed these local units and retained the construction principles that applied across markets. Readers are directed to local authorities or professionals for current regulations.

I benchmarked three models on narrative prose, technical terminology, safety language, tables, and a passage that should be omitted. The production model—openai/gpt-6-luna through OpenRouter—was pinned in configuration after it produced the best terminology and least literal German and French in that test. A runtime flag cannot silently swap it.

INPUT UNITID, source hash, scope, Markdown, protected tokens, numeric and date signatures

MODEL OUTPUTThe same ID and hash, an explicit translated-or-omit status, target text, and notes

VALIDATIONComplete return set, unchanged protected values, matching structure, locale number rules, no Croatian residue

STATERequested and served model, provider, latency, token usage, API cost, and atomic checkpoints

Translation and copy-editing run as separate stages. Translation preserves structure and meaning. Copy-editing adjusts rhythm and target-language terminology while validation protects claims, measurements, warnings, citations, and URLs.

The production state files recorded the following localization costs. These figures cover model calls for the books; they exclude software development, editorial work, image production, PDF review, storefront work, and the earlier model benchmark.

$3.02FIRST TRANSLATION / 14 EDITIONS
$2.69FIRST COPY-EDIT / 14 EDITIONS
$1.13SECOND COPY-EDIT / 6 PRIORITY EDITIONS
$6.83RECORDED PRODUCTION MODEL CALLS

The second copy-edit found incorrect English decimal punctuation, awkward German constructions, French number grouping, and one shift in meaning from “expert” to “artisan.” Low API cost made the extra pass affordable; native-language judgment was still required to decide what needed correction.

06 / VERSIONS, STRIPE, AND TESTS

A new note starts a controlled chain of new versions.

The first wave produced fourteen localized books and storefronts at buildyourho.me. Later notes use the same route as the original 219. A changed note creates a new hash, the affected Croatian content is rebuilt and reviewed, and a new source version becomes the input to localization.

DEPENDENCY CHAINWhat happens after the client sends another note
01 / NOTENew correction or additionReceives a stable ID; an edit changes the existing note’s hash
02 / SOURCEAffected Croatian unit is rebuiltUnchanged cards and chapters keep their verified output
03 / SOURCE VERSIONA reviewed source build is lockedThe exact input for downstream editions is now known
04 / LOCALE FAN-OUTEvery locale compares source hashesEnglish, German, French, and the other locales derive independently from Croatian
05 / LOCALE REVISIONOnly missing or stale units run againTranslation, copy-editing, validation, PDF, sample, and storefront
06 / ACTIVATEThe release manifest points to the new buildEdition metadata and checksums make the change auditable
The localizations do not form a telephone chain: German is not translated from English. Each locale is tied to the same reviewed Croatian source version.

An edition ID makes both parts visible. In en-GB-0.10.75.2, en-GB is the locale, 0.10.75 is the Croatian source version, and 2 is that locale’s second revision. A German copy-edit can therefore create a new German revision without pretending that the Croatian source changed.

Every release manifest records the edition ID, source version, localization revision, checksum, file path, filename, and page count. Full PDFs, samples, localized product copy, and storefront data are generated from that state.

How payment and download access fit into the chain

CHECKOUTThe server resolves the active release for the selected language and puts its locale, edition ID, and SHA-256 checksum into Stripe Checkout metadata.

PAYMENTA signed Stripe webhook creates access only for a completed, paid session. Unpaid events and invalid signatures are rejected.

ACCESSThe buyer receives a short-lived signed download token for the language they purchased.

DOWNLOADThe order keeps the purchase-time edition metadata for audit, while the download serves the current active PDF for that language.

REFUNDA partial refund keeps access; a full refund revokes it. A later out-of-order paid event cannot restore a fully refunded order.

Serving the latest active language edition is a product decision. The system preserves what was sold in the order record, but production does not promise that every later download returns the old binary. Historical releases can remain in the editorial archive without keeping every revision in the download service.

The release gate is backed by automated tests

CONTENT

Tests reject missing IDs, stale source hashes, changed numbers or protected strings, broken Markdown structure, incorrect locale punctuation, and content that should have been omitted.

RELEASE

Verification checks PDF and sample page counts, checksums, required files, and illustration coverage. Rendered pages are still inspected for layout failures.

COMMERCE

Tests cover unpaid sessions, valid and invalid webhook signatures, paid downloads in every locale, purchase metadata, partial refunds, full refunds, and late Stripe events.

The code catches missing units and invalid state. Reviewing rendered pages catches different failures: an isolated heading, a clipped illustration, or a comparison table that no longer fits after German text expands.

VERSIONING RULE

Notes are authoritative. Source releases freeze reviewed input. Locales derive from that source. Stripe records what was active at purchase.

07 / REUSABLE PATTERN

The same design works when one source feeds many documents.

The book is one instance of a broader pattern. Policies feed regional handbooks, product data feeds catalogues, research feeds reports, and course material feeds several formats or languages. In each case, a source change can invalidate several downstream artifacts.

  1. Give source units stable identities. Split the input at boundaries that can be reviewed, transformed, and invalidated independently.
  2. Record intent before generating prose. Store requested outputs, scope, destination, protected values, and verification needs.
  3. Define what the model may change. Separate free prose decisions from invariants such as IDs, numbers, citations, structure, and omit rules.
  4. Validate before caching. Reject an entire unit or batch when the response is incomplete; save only output tied to the current source hash.
  5. Separate history from delivery policy. Give each release a version, checksum, and manifest entry, then decide explicitly whether customers receive the purchased binary or the newest compatible revision.

This structure is useful when the source changes, several outputs depend on it, omissions are expensive, or users need historical versions. A one-off, low-stakes document usually does not need it.

I would make three changes if starting again: define the unit schema and release manifest before drafting, involve native readers before the first localized release, and turn the first observed failure into a regression test. Adding these controls later required migration and repeated review.

Use LLMs for language variation. Use code for state and invariants. Use people for judgment.