Saltar al contenido
Saltar al contenido

Docs / Conceptos

Página traducida automáticamente

Esta página se tradujo automáticamente, así que puede contener errores o sonar un poco rara. La versión en inglés es la fuente de la verdad. Leer el original en inglés.

El archivo de bloqueo y la procedencia

Qué registran verbatra.lock.json y verbatra.provenance.json, cómo se detecta el desfase y por qué debes confirmar ambos archivos.

verbatra.lock.json es la línea base con la que compara cada ejecución, así que una ejecución puede saltarse lo que está al día y volver a traducir lo que se desfasó. A su lado, verbatra.provenance.json registra quién o qué escribió cada valor.

Qué registra

Para cada locale de destino, un hash por clave traducida de la entrada de origen detrás de la traducción actual, más un campo version: ni traducciones ni secretos. El hash cubre el valor de origen junto con su descripción, su significado, su indicador de plural y sus marcadores, así que una descripción cambiada también deja la clave desfasada. Normaliza Unicode a NFC y los finales de línea a LF, así que volver a guardar un archivo de origen con finales CRLF no cambia nada.

Cómo se detecta el desfase

Una clave de origen que el destino no tiene está ausente (missing). Para una que sí tiene, el hash de origen actual se compara con el registrado: una diferencia significa que el origen cambió y la clave se vuelve a traducir; una coincidencia significa que nunca se envía, así que una segunda ejecución sin cambios en el origen no cuesta nada. La canalización completa está en Cómo funciona una ejecución.

Claves protegidas

La excepción es una clave cambiada cuyo valor escribió o importó una persona: por defecto está protegida y sigue desactualizada en lugar de volver a traducirse.

Adoptar un proyecto existente

Los archivos de locale que ya contienen traducciones revisadas no se vuelven a traducir. En la primera ejecución no hay archivo de bloqueo, así que nada puede estar desfasado: una clave que el destino tiene conserva su valor, solo se traducen las que le faltan, y la ejecución registra cada hash de origen como línea base sin coste de proveedor.

La adopción se basa en la presencia de la clave, nunca en su valor, lo que tiene dos consecuencias:

  • Un valor vacío o sin traducir cuenta como traducido. Borra la clave (vaciarla no basta) y la siguiente ejecución la traduce.
  • Una traducción desfasada se registra como actual. Corrígela o bórrala antes de la primera ejecución.

La misma regla conserva las formas de plural escritas a mano, así que generatePlurals es seguro durante la adopción. Para ver todo esto de antemano, ejecuta verbatra diff o verbatra translate --dry-run.

Cómo se actualiza

  • Una ejecución completa (translate, watch o una importación) sustituye las entradas de un locale por el resultado de la ejecución.
  • Una acción de una sola clave, como volver a traducir desde Studio, fusiona solo la entrada de esa clave.

En ambos casos, una clave retenida en esta ejecución (una comprobación de integridad o llamada al proveedor fallida, un origen con ICU no válido) conserva su hash anterior, así que la siguiente ejecución la reintenta. Las claves huérfanas no tienen entrada, y las claves ordenadas mantienen pequeños los diffs.

El bloqueo de escritura

Dos ejecuciones que tocan el mismo locale a la vez podrían comparar con una línea base desfasada y pagar dos veces, así que cada escritura toma un bloqueo entre procesos para ese locale en .verbatra-local/. Un segundo escritor espera y luego compara con una línea base que incluye el resultado del primero. Locales distintos nunca se bloquean entre sí.

Lo que garantiza el bloqueo:

  • Un tiempo de espera agotado no cuesta nada. --lock-timeout acota solo la espera previa a cualquier llamada al proveedor, así que un locale que se rinde no ha gastado ni escrito nada; registrar un archivo ya escrito espera los diez minutos por defecto.
  • Los bloqueos abandonados no te frenan. Un bloqueo cuyo proceso ya no existe en esta máquina se recupera al instante, y uno sin refrescar durante 30 segundos (quien lo tiene lo refresca cada 10) se trata como abandonado.
  • Una interrupción libera los bloqueos. Ctrl-C o SIGTERM durante translate o import, y la segunda interrupción que detiene watch a la fuerza, liberan cada bloqueo antes de que el proceso termine.
  • Un bloqueo perdido detiene la escritura. Cada bloqueo lleva un token aleatorio, que se comprueba antes de cada escritura; cuando otra ejecución se ha quedado con el bloqueo, la escritura se detiene con LOCK_CONTENDED y no se escribe nada.

Lo que no cubre:

  • Un bloqueo de otra máquina (una unidad de red compartida) o de un verbatra anterior a 0.12.0 nunca se recupera automáticamente; Solución de problemas tiene los pasos para quitarlo.
  • Una pausa larga entre la comprobación y la escritura. Una ejecución pausada justo después de comprobar el token (una máquina que se duerme, un proceso detenido) todavía puede escribir una vez al reanudarse.
  • Hosts que comparten nombre. Fuera de Linux, el nombre de host es la única identidad de máquina, así que dos contenedores con un mismo nombre de host que comparten .verbatra-local/ pueden tomar el bloqueo vivo del otro por abandonado. Da a cada uno su propio nombre de host o su propia copia de trabajo.

Un código de locale reescrito

El archivo de bloqueo, la caché y el archivo de procedencia indexan su estado por el código de locale de tu configuración. Cuando reescribes uno, por ejemplo pt_BR como pt-BR, la siguiente ejecución de translate o watch traslada el estado antiguo una vez e informa LOCALE_STATE_CARRIED_OVER. Un cambio en el origen hecho antes del cambio de nombre se sigue traduciendo, y las traducciones en caché se siguen reutilizando.

El traslado solo ocurre sin ambigüedad: pt-BR no tiene estado propio, y el archivo guarda estado bajo exactamente una grafía con guion bajo (o su grafía de gettext, como sr@latin para sr-Latn), comparada sin distinguir mayúsculas. El estado que pt-BR ya tiene nunca se sobrescribe. Si el traslado no se puede escribir, ese locale no se ejecuta y falla con LOCALE_STATE_NOT_CARRIED_OVER, para que la siguiente ejecución lo intente de nuevo; los demás locales se ejecutan como siempre.

Hasta entonces, cada lectura trata el estado antiguo como el de pt-BR sin escribir, así que una clave desfasada se informa como desfasada. Una escritura de una sola clave (una edición, una nueva traducción, una decisión de revisión) y verbatra import trasladan antes el estado, del mismo modo. La comprobación locale-state de verbatra doctor nombra cualquier estado que quede atrás.

Ausente o corrupto

Un archivo de bloqueo ausente es una primera ejecución, no un error. Uno que no se puede analizar, con una estructura incorrecta, demasiado grande o con una versión no soportada hace fallar la ejecución con LOCK_FILE_INVALID en lugar de sobrescribirse, para que puedas restaurarlo en vez de perder la línea base.

Procedencia: quién escribió cada valor

verbatra.provenance.json registra qué vía de escritura produjo cada valor que hay ahora en el archivo de locale, y si alguien lo revisó. Un verbatra más antiguo, por ejemplo uno fijado en CI, lo ignora.

OrigenLo escribe
machineuna respuesta del proveedor en translate, watch o una nueva traducción de una sola clave, con el id del proveedor y, si se conoce, el modelo
memoryun acierto exacto de la caché, incluido cada valor que rellena una ejecución solo humana (proveedor none)
fuzzyun acierto de la caché difusa
humanla edición de una persona a través de editEntry del SDK, como hace el diálogo de edición de Studio
agentla edición de un agente de IA a través de editEntry con actor: "agent"
importuna fila aceptada de verbatra import
unknownuna decisión de revisión sobre un valor sin registro, o un origen que esta versión no conoce

Al leer se derivan dos más: unrecorded es un valor sin registro, como cada clave tras actualizar; external ya no coincide con el hash de su registro porque algo fuera de verbatra lo cambió, como la pull request de un traductor, un verbatra más antiguo o una fusión. Los campos que devuelve cada lectura están en la referencia del SDK.

Lo que garantiza el archivo:

  • Diffs estables. Sin texto traducido ni marcas de tiempo, un registro ordenado por línea, así que una ejecución que no cambia nada deja el archivo igual. En un conflicto de fusión, quédate con el lado que coincide con el archivo de locale que conservas: un registro que no coincide se lee como external, lo que protege el valor de una nueva traducción.
  • Registros nuevos para valores nuevos. Una escritura que cambia un valor sustituye su registro por uno nuevo y sin revisar; una escritura que deja igual el valor y el origen lo conserva.
  • Ninguna sobrescritura silenciosa. Un archivo corrupto detiene cada escritura con PROVENANCE_FILE_INVALID antes de que cambie ningún archivo de locale; los informes omiten en su lugar sus campos de procedencia. Un archivo de un verbatra más nuevo se deja intacto, y uno que crecería demasiado para volver a leerlo no se escribe (PROVENANCE_FILE_TOO_LARGE).

No es a prueba de manipulaciones; para convertirlo en un informe, consulta Registrar evidencia de traducción automática.

Decisiones de revisión

Un registro puede llevar una decisión de revisión, approved o rejected, con un nombre de reviewer opcional. Las escriben la página Review de Studio, las funciones de revisión del SDK y las herramientas MCP de revisión; las herramientas MCP transmiten la decisión de una persona y exigen su nombre. Una decisión se aplica al valor exacto que vio el revisor y se rechaza si cambió.

  • Una aprobación solo cambia el archivo de procedencia, y vuelve a leerse como sin revisar en cuanto cambia el texto de origen.
  • Un rechazo quita el valor y su entrada del bloqueo, así que la clave se lee como ausente hasta la siguiente ejecución de translate o hasta que una persona escribe un valor nuevo. El registro guarda un hash del texto quitado y la entrada de caché se descarta, para que una ejecución no vuelva a poner el mismo texto. XLIFF no puede quitar una sola traducción, así que ahí un rechazo se deniega con REVIEW_REJECT_UNSUPPORTED.

Solo los valores de clase máquina entran en la cola de revisión y en la puerta --require-reviewed. Los contadores byReviewState de check y lock.state cubren cada valor según su decisión registrada, sea cual sea su origen, así que un valor escrito o importado por una persona sin decisión cuenta como unreviewed ahí sin estar en la cola; léelos junto con byOrigin.

Las decisiones viven en este archivo confirmado, así que la cola de revisión y verbatra check --require-reviewed ven el mismo estado en todas partes, y el nombre de reviewer es público; verbatra nunca lo rellena.

Confírmalo

Confirma verbatra.lock.json y verbatra.provenance.json junto a tus archivos de locale, y nunca los edites a mano: son la línea base con la que comparan tu equipo y tu CI, y lo que restaura una reversión.

Editar en GitHub

En esta página