Aller au contenu
Aller au contenu

Docs / Concepts

Page traduite automatiquement

Cette page a été traduite automatiquement, elle peut donc contenir des erreurs ou se lire un peu bizarrement. La version anglaise fait foi. Lire l'original en anglais.

Le fichier de verrouillage et la provenance

Ce que verbatra.lock.json et verbatra.provenance.json enregistrent, comment la dérive est détectée et pourquoi tu commites les deux fichiers.

verbatra.lock.json est la référence avec laquelle chaque exécution compare, pour qu'une exécution saute ce qui est à jour et retraduise ce qui a dérivé. À côté, verbatra.provenance.json enregistre qui ou quoi a écrit chaque valeur.

Ce qu'il enregistre

Pour chaque locale cible, un hash par clé traduite de l'entrée source derrière la traduction actuelle, plus un champ version : aucune traduction, aucun secret. Le hash couvre la valeur source avec sa description, son sens, son indicateur de pluriel et ses placeholders, donc une description modifiée rend aussi la clé obsolète. Il normalise l'Unicode en NFC et les fins de ligne en LF, donc réenregistrer un fichier source en CRLF ne change rien.

Comment la dérive est détectée

Une clé source que la cible n'a pas est manquante. Pour une clé présente, le hash source actuel est comparé à celui enregistré : une différence signifie que la source a changé et la clé est retraduite ; une correspondance signifie qu'elle n'est jamais envoyée, donc une seconde exécution sans modification de la source ne coûte rien. Le pipeline complet est sur Comment se déroule une exécution.

Clés protégées

L'exception est une clé modifiée dont une personne a écrit ou importé la valeur : par défaut elle est protégée et reste obsolète au lieu d'être retraduite.

Adopter un projet existant

Des fichiers de locale qui contiennent déjà des traductions relues ne sont pas retraduits. À la première exécution il n'y a pas de fichier de verrouillage, donc rien ne peut être périmé : une clé que la cible possède garde sa valeur, seules les clés manquantes sont traduites, et l'exécution enregistre chaque hash source comme référence, sans coût fournisseur.

L'adoption se décide par la présence d'une clé, jamais par sa valeur, ce qui a deux conséquences :

  • Une valeur vide ou non traduite compte comme traduite. Supprime la clé (la vider ne suffit pas) et l'exécution suivante la traduit.
  • Une traduction déjà périmée est enregistrée comme à jour. Corrige-la ou supprime-la avant la première exécution.

La même règle garde les formes plurielles écrites à la main, donc generatePlurals est sans risque pendant l'adoption. Pour voir tout cela à l'avance, lance verbatra diff ou verbatra translate --dry-run.

Comment il est mis à jour

  • Une exécution complète (translate, watch, ou un import) remplace les entrées d'une locale par le résultat de l'exécution.
  • Une action sur une seule clé, comme une retraduction depuis Studio, ne fusionne que l'entrée de cette clé.

Dans les deux cas, une clé retenue pendant cette exécution (une vérification d'intégrité ou un appel fournisseur échoué, une source ICU invalide) garde son hash précédent, donc l'exécution suivante la retente. Les clés orphelines n'ont pas d'entrée, et des clés triées gardent les diffs petits.

Le verrou d'écriture

Deux exécutions qui touchent la même locale en même temps pourraient toutes deux comparer avec une référence périmée et payer deux fois, donc chaque écriture prend un verrou inter-processus propre à cette locale sous .verbatra-local/. Un second écrivain attend, puis compare avec une référence qui contient le résultat du premier. Des locales différentes ne se bloquent jamais.

Ce que le verrou garantit :

  • Un délai dépassé ne coûte rien. --lock-timeout ne borne que l'attente avant tout appel fournisseur, donc une locale qui abandonne n'a rien dépensé ni rien écrit ; enregistrer un fichier déjà écrit attend les dix minutes par défaut.
  • Les verrous abandonnés ne te bloquent pas. Un verrou dont le processus a disparu de cette machine est récupéré tout de suite, et un verrou non rafraîchi depuis 30 secondes (les détenteurs rafraîchissent toutes les 10) compte comme abandonné.
  • Une interruption libère les verrous. Ctrl-C ou SIGTERM pendant translate ou import, et la seconde interruption qui force l'arrêt de watch, libèrent tous les verrous avant la fin du processus.
  • Un verrou perdu arrête l'écriture. Chaque verrou porte un jeton aléatoire, vérifié avant chaque écriture ; quand une autre exécution a repris le verrou, l'écriture s'arrête avec LOCK_CONTENDED et rien n'est écrit.

Ce qu'il ne couvre pas :

  • Un verrou d'une autre machine (un lecteur réseau partagé) ou d'un verbatra antérieur à 0.12.0 n'est jamais récupéré automatiquement ; Dépannage donne les étapes pour le retirer.
  • Une longue pause entre vérification et écriture. Une exécution mise en pause juste après la vérification du jeton (une machine en veille, un processus arrêté) peut encore écrire une fois à sa reprise.
  • Des hôtes qui partagent un nom. Hors Linux, le nom d'hôte est la seule identité de machine, donc deux conteneurs au même nom d'hôte qui partagent .verbatra-local/ peuvent prendre le verrou vivant de l'autre pour un verrou abandonné. Donne à chacun son propre nom d'hôte ou sa propre copie de travail.

Un code de locale réécrit

Le fichier de verrouillage, le cache et le fichier de provenance rangent leur état sous le code de locale de ta configuration. Quand tu en réécris un, par exemple pt_BR en pt-BR, la prochaine exécution de translate ou watch reporte l'ancien état une fois et signale LOCALE_STATE_CARRIED_OVER. Une modification de la source faite avant le renommage est toujours retraduite, et les traductions en cache sont toujours réutilisées.

Le report n'a lieu que sans ambiguïté : pt-BR n'a pas d'état à lui, et le fichier contient un état sous exactement une graphie avec tiret bas (ou sa graphie gettext, comme sr@latin pour sr-Latn), comparée sans tenir compte de la casse. Un état que pt-BR a déjà n'est jamais écrasé. Si le report ne peut pas être écrit, cette locale ne tourne pas et échoue avec LOCALE_STATE_NOT_CARRIED_OVER, pour que l'exécution suivante réessaie ; les autres locales tournent normalement.

D'ici là, chaque lecture traite l'ancien état comme celui de pt-BR sans écrire, donc une clé périmée est signalée comme périmée. Une écriture sur une seule clé (une modification, une retraduction, une décision de relecture) et verbatra import déplacent d'abord l'état, de la même façon. Le contrôle locale-state de verbatra doctor nomme tout état resté en arrière.

Absent ou corrompu

Un fichier de verrouillage absent est une première exécution, pas une erreur. Un fichier illisible, mal structuré, trop gros ou dans une version non prise en charge fait échouer l'exécution avec LOCK_FILE_INVALID au lieu d'être écrasé, pour que tu puisses le restaurer plutôt que perdre la référence.

La provenance de chaque valeur

verbatra.provenance.json enregistre quel chemin d'écriture a produit chaque valeur présente dans le fichier de locale, et si quelqu'un l'a relue. Un verbatra plus ancien, par exemple épinglé dans la CI, l'ignore.

OrigineÉcrite par
machineune réponse de fournisseur dans translate, watch ou une retraduction d'une seule clé, avec l'id du fournisseur et, quand il est connu, le modèle
memoryun succès exact du cache, y compris chaque valeur que remplit une exécution sans traduction automatique (fournisseur none)
fuzzyun succès du cache approximatif
humanla modification d'une personne via editEntry du SDK, comme la fait la boîte d'édition de Studio
agentla modification d'un agent IA via editEntry avec actor: "agent"
importune ligne acceptée par verbatra import
unknownune décision de relecture sur une valeur sans enregistrement, ou une origine que cette version ne connaît pas

Deux autres sont déduites à la lecture : unrecorded est une valeur sans enregistrement, comme chaque clé après une mise à jour ; external ne correspond plus au hash de son enregistrement parce que quelque chose hors de verbatra l'a changée, comme la pull request d'un traducteur, un verbatra plus ancien ou une fusion. Les champs que renvoie chaque lecture sont dans la référence du SDK.

Ce que le fichier garantit :

  • Des diffs stables. Aucun texte traduit ni horodatage, un enregistrement trié par ligne, donc une exécution qui ne change rien laisse le fichier inchangé. En cas de conflit de fusion, prends le côté qui correspond au fichier de locale que tu gardes : un enregistrement qui ne correspond pas se lit comme external, ce qui protège la valeur d'une nouvelle traduction.
  • Des enregistrements neufs pour les nouvelles valeurs. Une écriture qui change une valeur remplace son enregistrement par un nouveau, non relu ; une écriture qui laisse valeur et source inchangées le garde.
  • Pas d'écrasement silencieux. Un fichier corrompu arrête chaque écriture avec PROVENANCE_FILE_INVALID avant qu'un fichier de locale ne change ; les rapports omettent plutôt leurs champs de provenance. Un fichier écrit par un verbatra plus récent est laissé intact, et un fichier trop gros pour être relu n'est pas écrit (PROVENANCE_FILE_TOO_LARGE).

Il n'est pas infalsifiable ; pour en faire un rapport, voir Consigner les preuves de traduction automatique.

Décisions de relecture

Un enregistrement peut porter une décision de relecture, approved ou rejected, avec un nom de relecteur reviewer facultatif. La page Review de Studio, les fonctions de revue du SDK et les outils MCP de relecture les écrivent ; les outils MCP relaient la décision d'une personne et exigent son nom. Une décision s'applique à la valeur exacte que le relecteur a vue et est refusée si elle a changé.

  • Une approbation ne change que le fichier de provenance, et se relit comme non relue dès que le texte source change.
  • Un rejet retire la valeur et son entrée de verrouillage, donc la clé se lit comme manquante jusqu'à la prochaine exécution de translate ou jusqu'à ce qu'une personne écrive une nouvelle valeur. L'enregistrement garde un hash du texte retiré et l'entrée du cache est supprimée, pour qu'une exécution ne remette pas le même texte. XLIFF ne peut pas retirer une seule traduction, donc un rejet y est refusé avec REVIEW_REJECT_UNSUPPORTED.

Seules les valeurs de classe machine entrent dans la file de relecture et dans la porte --require-reviewed. Les comptes byReviewState de check et de lock.state couvrent chaque valeur selon sa décision enregistrée, quelle que soit son origine : une valeur écrite ou importée par une personne sans décision y compte comme unreviewed sans figurer dans la file ; lis-les avec byOrigin.

Les décisions vivent dans ce fichier commité, donc la file de relecture et verbatra check --require-reviewed voient le même état partout, et le nom reviewer est public ; verbatra ne le remplit jamais.

Commite-le

Commite verbatra.lock.json et verbatra.provenance.json avec tes fichiers de locale, et ne les modifie jamais à la main : ils sont la référence avec laquelle ton équipe et ta CI comparent, et ce que restaure un retour arrière.

Modifier sur GitHub

Sur cette page