TM and SQLite guide¶
中文 | English
Concepts¶
Translation Memory (TM) stores translations for reuse in future versions. SQLite is used instead of a simple source-to-translation dictionary because the framework also records:
- a stable coordinate composed from project, adapter, relative path, and logical key;
- a source fingerprint that prevents reuse after source changes;
- machine, human, or legacy origin;
- review, quality, formal state, and run identity;
- legacy synchronization evidence and authority state.
Declare only the database path and policy:
tm:
database: ../../var/my-project/localizer.sqlite
global_exact_match: reviewed_only
commit_policy: quality_gate
The path is resolved from project.yaml.
Initialize a new SQLite TM¶
Do not install a SQLite CLI or create tables manually. Any write workflow creates the parent directory, file, schema, and indexes, including:
localizer build ...;localizer tm-sync-legacy ...;- a Dashboard build or actual human write.
Recommended initialization:
localizer validate-config projects/my-project/project.yaml
localizer scan projects/my-project/project.yaml
localizer build projects/my-project/project.yaml --mode preview --run-id tm-init
The first two commands are read-only. The build opens a write connection and creates SQLite even when the preview produces no formal translations.
On Windows, check the configured path with:
Test-Path var\my-project\localizer.sqlite
Dashboard overview also shows the resolved path, schema, and statistics.
Schema creation versus formal TM content¶
An existing .sqlite file does not imply reusable translations exist:
previewcreates candidates, reports, and checkpoints; it does not automatically make machine candidates formal truth.- After a successful QualityGate,
releasecan promote eligible machine results to formal TM. - Dashboard human approval writes audited formal records with priority over machine output.
- Legacy JSON rows enter with legacy classifications and are reusable only when their classification, review state, and
global_exact_matchpolicy allow it.
Build from existing translated resources¶
If there is no old TM JSON and only translated resources are available, use Build TM from existing translations. It documents direct adapter ingestion and the neutral TM Seed format for unknown structures.
Convert legacy JSON TM to SQLite¶
Scope¶
tm-sync-legacy accepts the history_tm.json compatibility shape produced by the earlier script workflow. It is not an arbitrary JSON importer:
{
"relative/path/to/catalog": {
"logical_key": {
"ru": "source text",
"zh": "translated text"
}
}
}
The outer key becomes relative path and the second-level key becomes logical key. ru/zh are fixed legacy field names; actual SQLite locale metadata still comes from current languages.source and languages.target. Convert other structures to this exact compatibility shape or, preferably, to the neutral Seed format—renaming the extension is not enough.
1. Back up migration inputs¶
Keep the original legacy TM, current project/glossary/rules, any existing SQLite, and a representative accepted artifact or behavioral baseline. Never overwrite the original JSON. The importer reads it without modification and writes a separate guard marker.
2. Validate the project¶
localizer validate-config projects/my-project/project.yaml
Legacy records are classified with the current project ID, locales, glossary, and QA rules. Finalize these first; changing project.id later changes stable coordinates.
3. Synchronize¶
localizer tm-sync-legacy `
projects/my-project/project.yaml `
path/to/history_tm.json
The command:
- creates or opens configured SQLite;
- creates stable coordinates and source fingerprints;
- classifies old translations with placeholder, language, and glossary checks;
- writes legacy shadow rows;
- writes
<workspace>/reports/legacy-tm-migration.json; - creates a
.shadow-sync.locknext to the old JSON.
An identical file hash is skipped on repeat. Use --force only to deliberately reclassify/resynchronize:
localizer tm-sync-legacy projects/my-project/project.yaml path/to/history_tm.json --force
Synchronization replaces that project's legacy shadow rows but cannot overwrite protected human/formal SQLite rows.
4. Review the report¶
Verify total, imported, clean/suspect/quarantined classification distribution, reasons such as empty/untranslated/placeholder/rule/glossary failure, and whether skipped_unchanged is expected. Quarantined rows are not silently reused.
Establish a baseline from an accepted artifact¶
If no trustworthy TM exists but an accepted release artifact does, analyze it first:
localizer tm-adopt-artifact `
projects/my-project/project.yaml `
path/to/artifact-manifest.json
Then attest and apply:
localizer tm-adopt-artifact `
projects/my-project/project.yaml `
path/to/artifact-manifest.json `
--apply `
--accepted-by project-owner
Application creates a SQLite backup and data-baseline report. Use a real, traceable operator identity. Verify rebuild behavior:
localizer tm-verify-artifact `
projects/my-project/project.yaml `
path/to/artifact-manifest.json `
--run-id verify-001
When to switch SQLite authority¶
New projects do not need legacy governance commands. In a migration where an old program still writes history_tm.json, synchronization only builds a shadow. Switch authority only after the old writer is frozen and data/behavior are verified:
localizer tm-switch-authority projects/my-project/project.yaml `
--behavior-baseline path/to/behavior-baseline.json `
--data-baseline path/to/data-baseline.json `
--legacy-tm path/to/history_tm.json
Prerequisites include: SQLite is not already authoritative, at least one legacy sync exists, the final-sync hash still matches the old JSON, legacy row counts match evidence, and the behavior/data baseline files are valid independent evidence. This is a one-way governance action, not routine initialization; repeat switching is rejected.
Export SQLite back to legacy JSON¶
For rollback, use the explicit exporter rather than manually querying tables:
localizer tm-export-legacy `
projects/my-project/project.yaml `
path/to/exported-history-tm.json
By default it does not overwrite existing files, omits quarantined/unknown rows, and writes a provenance sidecar for human/formal/review attributes the old format cannot represent. --overwrite permits replacement; --include-quarantined enables row-for-row transport but may expose unmarked problematic rows to the old program, so inspect the report first.
Backup and concurrency¶
- Do not modify SQLite externally while Dashboard tasks run.
- The task queue serializes writers, including variants that share TM.
- Use application backup workflows or the SQLite backup API; copying only the main file may omit WAL data.
.sqlite-waland.sqlite-shmare not standalone backups.- Back up both the human-decision log and its usable TM projection.
Troubleshooting¶
Low hit counts usually mean path/key mismatch, changed source fingerprints, or quarantined history. Inspect reports and scan coordinates instead of weakening fingerprint checks.
Do not edit translations with SQLite Browser: that bypasses decision logs, protection rules, and audit fields. Use Dashboard or a tested migration/import command.
Deleting SQLite starts over but destroys translations, review state, and migration evidence. A safer trial uses a new tm.database path and switches only after verification.