Core Concepts
The rules the rest of the product is built on
LocalizeShip is small on purpose. It does not invent a new localization format, a new runtime, or a new translation memory. It adds four pieces of discipline around the data you already have.

1. Stable line identity
A line is addressed by a StableEntryId — a string key such as dialogue_npc_01. Reordering entries, moving them between tables, or sorting a collection must not change which line is which.
2. Source revision
A line’s source is not just text. It is normalized text plus declared speaker and context, hashed together. The hash is the handle used by approvals, voice takes and merge base records.
3. Explicit review state
Text present in a table is not a review. LocalizeShip keeps six explicit states per line × locale and binds approval to the exact source hash that was reviewed. A source change invalidates approval instead of silently inheriting it.
4. Coverage honesty
“Not checked” is a real answer. A fixture that was never visited is Unknown, not Passed. A screenshot produced in the Editor is labelled an Editor approximation, not player capture. A gate that has not run is not a green gate.
Supporting mechanics
Normalization
Whitespace and line-ending policy is versioned, so trivial formatting churn does not create false invalidations — and a policy change is visible in the hash input.
Audit trail
Every state change is an ApprovalEvent with reviewer, role, rationale, timestamps and the old/new hashes. The history is stored on the approval record.
How the concepts fit together
StableEntryId ──────────────┐
▼
Raw source text ──► NormalizationPolicy ──► normalized text + speaker + context
│
▼
SourceRevisionHash
│
┌────────────────────────────────────┼──────────────────────────────┐
▼ ▼ ▼
ApprovalRecord VoiceEntry binding Merge base hash
(state + history) (source + translation) (stale conflicts)
│
▼
ReleaseGateEvaluator
If you are integrating LocalizeShip into an existing pipeline, read Revision Graph and Review States before writing any glue code. Most integration mistakes come from treating a review state as a property of a string rather than a property of a revision.