Skip to content

Docs / Guides

Keep human translations

Keep the strings a translator wrote when the source text changes, get a machine suggestion instead of an overwrite, and pin keys no machine may touch.

Available from 0.12.0

Use this when some translations were written by a person: legal, marketing or brand copy that someone was paid for. When its source text changes, the key goes stale, and a plain machine run would translate over it. verbatra keeps it by default; this page shows how to see those keys, resolve them, and tighten or loosen the rule.

You need a project that has run translate at least once, so verbatra.provenance.json exists and records who wrote each value.

What is protected

When a key's source text changes, translate and watch leave its value alone if a person wrote it:

OriginWhere the value came from
humana person's edit, for example in the Studio edit dialog
importa row imported from a translator handoff with verbatra import
externalan edit made outside verbatra, such as a translator changing the locale file in a pull request

Machine output (machine, memory, fuzzy), agent edits (agent) and values with no record yet (unrecorded) are retranslated as usual. A value a reviewer rejected is never protected. See Provenance for how each origin is recorded.

Find the protected keys

A protected key is not sent to the provider, keeps its value, and stays stale, so it stays visible:

verbatra translate --dry-run
Output
verbatra translate (dry run)
  de: 1 would translate, 12 unchanged, 1 protected
    protected:       checkout.terms (import)
1 succeeded, 0 partial, 0 failed (dry run: nothing written)
  • verbatra translate translates everything else, lists the key as protected, and still exits 0.
  • verbatra check counts it as stale and exits 1, so a CI gate shows that a person has work to do.
  • verbatra diff lists it under protected.
  • verbatra export hands it to the translator as changed, like any stale key.

Resolving a protected key

A protected key stops being stale as soon as a person decides what it should say:

  • Edit it in Studio, or save it unchanged to keep the text. Either way the value is recorded as human against the new source text.
  • Export it, let the translator update it, and import the handoff. See Hand off with Excel or CSV.
  • Retranslate it on purpose for one run with verbatra translate --include-human.

Suggestions instead of overwrites

To see what a machine would write without replacing the person's text, set humanEdits to suggest:

verbatra.config.ts
export default defineConfig({
  // ...
  humanEdits: "suggest",
});

A protected key is then still sent to the provider, but the answer is only a suggestion. It appears next to the key in the run summary, with a suggestionStatus saying whether it arrived or why not, and it is kept in the translation memory; it is never written to the locale file. An exact memory entry for the new text can serve as the suggestion, and the next run serves it again without paying. translate --estimate counts these keys, since they are sent. In a human-only project there is no provider to ask, so suggest behaves like protect.

To go back to retranslating everything, set humanEdits to overwrite. See humanEdits and pinnedKeys.

Pinning keys

Some keys must never be machine-touched at all: a trademark, a legal disclaimer. List them in pinnedKeys, where * matches any run of characters:

verbatra.config.ts
export default defineConfig({
  // ...
  pinnedKeys: ["legal.*", "brand.name"],
});

A pinned key is never translated, suggested or retranslated, even when it is missing and even with --include-human. It is listed as protected with the reason pinned until a person fills it.

Agents

An AI agent cannot replace a person's work. The MCP tool translation.retranslateEntry refuses a protected value with KEY_PROTECTED and a pinned key with KEY_PINNED, and offers no override. translation.translatePending leaves protected keys alone and lists them. An agent can still write a value with translation.editEntry unless the key is pinned; that value is recorded as agent, so it never passes for a person's work.

In Studio Available from @verbatra/studio 0.6.0

The Translations page marks a protected key as Protected and lists it in its own group, with the origin of its current value. Open the key to edit it, or save it unchanged to keep the text. Retranslating a protected key from the key drawer asks first and offers Replace anyway. See Review in Studio.

Edge cases

  • A provenance file from a newer verbatra. No origin can be read, so translate protects every stale key with a value until you upgrade, while check and diff list only pinned keys as protected.
  • A corrupt provenance file. translate, including a dry run, fails with PROVENANCE_FILE_INVALID. check and diff keep working and list only pinned keys as protected.
  • Human-only projects. Protected keys count toward exit code 3, like keys the translation memory could not fill: both need a person.
Edit on GitHub

On this page