
Cotton
Translation workflow
Des traductions générées aux résultats révisables.
Un workflow de traduction pour les dialogues de jeux vidéo.
Cotton vocabulary
- prompt layers
- glossary
- generation
- revision
- judge
- hard gate
- score
- intake
- checkpoint
- spend control
- stale sweep
- approval
- correction
- audit trail
Prompt Layers: SYSTEM_PROMPT_L0 · buildTranslateUserMessage · L1 CONTRACT · L3 SPEAKER · L6 SOURCE · L7 INSTRUCTION · ICU PLACEHOLDER · INLINE TAG · TARGET TEXT ONLY · FORCED MAPPING · L2 GLOSSARY · speaker_keyGlossary: glossary_term · fetchGlossaryHits · canonical_form · forbidden_translations · SUBSTRING MATCH · FORCED MAPPING · FORBIDDEN ALTERNATIVE · L2 GLOSSARY · glossary_hits · glossary_complianceGeneration: AdapterRegistry · anthropic-sdk · openai-sdk · claude-local · codex-local · llm_plan · PIVOT_VIA · shouldPivot · COTTON_ADAPTER_CONCURRENCY · NODE_OPTIONS · pivot_register_carry · translation.refinedRevision: buildTranslateUserMessage · L7 INSTRUCTION · runRefinementLoop · priorAttempt · priorCritique · REJECTED BY THE JUDGE · maxTurns · willRetry · RefinementHooks · HOOK ABORT · turn_count_to_final · critique_for_retry · failingDimensions · cost_ceiling_usd · needs_reviewJudge: glossary_hits · runJudge · JUDGE_SYSTEM_PROMPT · judgeModel · TEMPERATURE 0 · parseJudgeResponse · FOUR-SECTION XML · VERBATIM CHUNKS · severity · critique_for_retry · judge_citation · missingHardGates · TRIGGER ABSENT = PASS · judge.scoredHard Gate: ICU PLACEHOLDER · INLINE TAG · FORBIDDEN ALTERNATIVE · hard_gate_fail · hardGatePassed · glossary_compliance · cps_budget_compliant · icu_validity · inline_tag_preserved · length_constraint · HARD GATE FIRST · missingHardGates · TRIGGER ABSENT = PASSScore: HARD GATE FIRST · computeVerdict · cottonEvalScore · WEIGHTED AVERAGE · tone_register · personality_consistent · emotional_state_match · cultural_marker_preserved · accuracy · pivot_register_carry · auto_approve_threshold · failingDimensions · approval_gate · judge.scoredIntake: processXlsxBytes · classifySheetName · parseGoogleSheetsUrl · source_file · content_sha256 · extractStageDirection · speaker_key · ingest_session · segment.ingested · github.push.receivedCheckpoint: translation_progress · last_completed_step · turn_translated · turn_judged · finalized · jobEntryGuard · SELECT FOR UPDATE · attempt_count · DEFAULT_MAX_RESUME_ATTEMPTS · TWO-TX SPLIT · ON CONFLICT DO NOTHINGSpend Control: llm_plan · costCap · cost_ceiling_usd · rateLimit · FailoverDispatcher · haltOnQuota · detectQuotaFromStream · quota_daily_exhausted · auth_revoked · NO AUTO-SWAP · needs_credential · POST /:id/resumeStale Sweep: COTTON_ADAPTER_CONCURRENCY · NODE_OPTIONS · attempt_count · runStaleSweep · STALE_THRESHOLD_INTERVAL · DLQ_ATTEMPT_CAP · LIMIT 200 · re_enqueued · dead_lettered · ORPHAN RE-ENQUEUE · IN-FLIGHT SET · /health/queues · maxStalledCount · needs_reviewApproval: auto_approve_threshold · ingest_session · SELECT FOR UPDATE · needs_credential · POST /:id/resume · POST /:id/approve · POST /:id/unapprove · POST /:id/reject · APPROVE_FROM · REJECT_FROM · needs_review · reviewer_id · HITL · approval_gate · translation.approved · EDIT & APPROVE · actor_idCorrection: POST /:id/correct · corrected_text · CORRECT_FROM · EDIT & APPROVE · human_corrected_segments · human-corrected-after-mt · translation.human_corrected · supersedes · NEW REVISION · IMMUTABLE HISTORYAudit Trail: turn_count_to_final · severity · judge_citation · content_sha256 · segment.ingested · github.push.received · translation.approved · human_corrected_segments · translation.human_corrected · IMMUTABLE HISTORY · event_log · appendNextEvent · ULID · AGGREGATE VERSION · translation_state_log · actor_id · llm_call_log · telemetryHook · judge.scored · translation.refined
Scores, nouvelles tentatives et revue humaine, chacun à sa frontière.
Génération et jugement partagent le glossaire, et l’échec d’une hard gate rapporté par le modèle juge ne peut pas être compensé par le score moyen. Les états intermédiaires de traduction et de jugement sont consignés, les limites de tentatives et de coût sont distinguées des identifiants épuisés, et les jobs bloqués retournent à la file ou à la revue selon la cause.
Ce projet professionnel relie dans un même flux la génération de traductions, le jugement de qualité rapporté par le modèle, les nouvelles tentatives et la revue humaine.
Du début du dépôt au travail confirmé pendant la mission
Une application web composée d’écrans d’édition et d’approbation des traductions, d’une API et d’un worker de jobs, qui tourne dans l’environnement de développement.
Enregistrement → entrée
Mis en file après le commit en base ; un worker verrouille la ligne, vérifie la tentative et crée le brouillon.
Source · locales ciblesDonnées: sourceMise en file après commit
API · enregistrement des jobsLes segments source et les locales cibles du projet sont stockés en base de données. Les données clients ne sont pas montrées.
Mise en file après commit
API · enregistrement des jobsDonnées: après commitBullMQ · ID de jobFile de jobsAprès le commit en base, un job avec un ID propre à la requête est mis en file pour chaque locale cible active. Si la mise en file échoue, seul un avertissement est journalisé et le commit n’est pas annulé (pas d’outbox atomique) ; c’est pourquoi le balayage des inactifs existe.
BullMQ · ID de job
File de jobsExécution · jugement: transmettre le jobVerrou de ligne · vérification de la tentativeEntrée du jobBullMQ transmet le job à un worker de façon asynchrone.
Verrou de ligne · vérification de la tentative
Entrée du jobDonnées: ligne d’avancementBrouillon · avancementÉtat de la traductionDans une transaction, la ligne d’avancement est verrouillée et une traduction brouillon est créée. Les nouvelles tentatives automatiques des jobs finalisés ou suspendus pour identifiants sont ignorées ; les demandes manuelles sont traitées à part.
Verrou de ligne · vérification de la tentative
Entrée du jobExécution · jugement: tentative autoriséeGénérer · appel au modèleTour de traductionLe compteur de tentatives augmente d’un dans sa limite, puis le tour de traduction commence.
Générer → juger → finaliser
Génération et jugement utilisent le même glossaire ; la traduction et le jugement sont consignés séparément, et le code agrège le jugement avant de finaliser.
Glossaire de l’espace de travail
Glossaire · contexteDonnées: glossaireGénérer · appel au modèleTour de traductionLe glossaire et le contexte de l’espace de travail sont recherchés et transmis à la génération.
Glossaire de l’espace de travail
Glossaire · contexteDonnées: même glossaireAppel au modèle juge · analyseTour de traductionLe jugement reçoit les mêmes contraintes de glossaire.
Générer · appel au modèle
Tour de traductionDonnées: Tx1 · traductionLignes de traduction · de jugementÉtat de la traductionLe modèle est appelé directement ou via un pivot en-US, et l’appel, l’événement et l’avancement sont écrits dans une seule transaction. Si le job est relancé après un crash, l’appel de traduction et son coût peuvent se répéter.
Appel au modèle juge · analyse
Tour de traductionDonnées: Tx2 · jugementLignes de traduction · de jugementÉtat de la traductionLes scores et les preuves du juge sont insérés une fois par traduction et par tour ; un doublon retrouve la ligne existante, et les citations ne sont écrites qu’à la première insertion. Ce n’est pas la même transaction que la traduction.
Appel au modèle juge · analyse
Tour de traductionDonnées: scores · gatesHard gate · moyenne pondéréeRègles de verdictLa réponse du modèle juge est analysée en scores par dimension et en résultats de gates. Le passage du glossaire est ce que rapporte le modèle juge.
Hard gate · moyenne pondérée
Règles de verdictExécution · jugement: verdictTours · coût · quotaNouvelle tentative · dépensesTout échec de hard gate rapporté donne un zéro et un échec ; ce n’est qu’ensuite que s’appliquent la moyenne pondérée et les seuils par dimension. Le seuil global de 8.0 est une valeur de configuration par défaut, pas une qualité de traduction observée.
Tours · coût · quota
Nouvelle tentative · dépensesExécution · jugement: passTransaction finaleFinalisationUn succès est finalisé comme translated.
Transaction finale
FinalisationDonnées: enregistrement finalÉtat · journal des appelsÉtat de la traductionCandidat, état, score et tours sont finalisés, et l’avancement finalized et le journal d’état sont écrits dans une seule transaction. Un événement de traduction terminée n’est émis que pour translated.
Nouvelles tentatives · limites de dépenses
Pas de succès : un nouveau tour ; une limite : la revue humaine ; quota ou authentification : arrêt des dépenses en attendant la reprise par un opérateur.
Hard gate · moyenne pondérée
Règles de verdictExécution · jugement: verdictTours · coût · quotaNouvelle tentative · dépensesTout échec de hard gate rapporté donne un zéro et un échec ; ce n’est qu’ensuite que s’appliquent la moyenne pondérée et les seuils par dimension. Le seuil global de 8.0 est une valeur de configuration par défaut, pas une qualité de traduction observée.
Tours · coût · quota
Nouvelle tentative · dépensesExécution · jugement: tour suivantGénérer · appel au modèleTour de traductionUne traduction qui ne passe pas est générée à nouveau avec la traduction précédente et la critique. Même un échec de hard gate peut d’abord être retenté au lieu d’aller directement à une personne.
Tours · coût · quota
Nouvelle tentative · dépensesExécution · jugement: limite · abandonRevue humaineQuand les tours sont épuisés ou que le plafond de coût est atteint, le job est finalisé comme needs_review. Finalisé signifie que le traitement est terminé, pas qu’une personne l’a approuvé.
Tours · coût · quota
Nouvelle tentative · dépensesÉchec · limite: quota · authentificationContrôle des identifiantsUn signal de quota ou d’authentification arrête les dépenses et pose needs_credential. Il n’y a pas de bascule automatique vers un autre compte ou fournisseur. Les erreurs de transport sans signal d’arrêt repartent vers les nouvelles tentatives de BullMQ.
Contrôle des identifiantsExécution · jugement: reprise manuelleBullMQ · ID de job
File de jobsUn opérateur qui a vérifié les identifiants relance explicitement.
Reprise des jobs inactifs
Les vieux brouillons sont triés par cause : absent de la file, remise en file ; tentatives épuisées, décision humaine.
Brouillon · avancement
État de la traductionObservation · rapport: brouillon inactifBrouillons de plus de 10 min · max 200Balayage des inactifsJusqu’à 200 candidats restés brouillons plus de 10 minutes sont lus, les plus anciens d’abord. La requête ne prend aucun verrou et les mises à jour et journaux sont des instructions séparées ; ce n’est donc pas décrit comme un lot sans course.
Brouillons de plus de 10 min · max 200
Balayage des inactifsExécution · jugement: sous la limiteComparer l’état de la fileContrôle de la fileAvec moins de tentatives que la limite (3), le job est comparé aux états de file active, waiting, delayed et prioritized. Dans le code, la branche des tentatives épuisées précède ce contrôle de la file.
Comparer l’état de la file
Contrôle de la fileExécution · jugement: remise en fileBullMQ · ID de jobFile de jobsSi le job n’est pas dans la file, il y est remis. L’API utilise des ID avec un suffixe de requête alors que le balayage cherche l’ID de segment et de locale ; ce n’est donc pas décrit comme couvrant toutes les requêtes en cours.
Brouillons de plus de 10 min · max 200
Balayage des inactifsExécution · jugement: résultat présentRevue humaineAvec les 3 tentatives utilisées et un résultat de traduction présent, le job passe à needs_review.
Brouillons de plus de 10 min · max 200
Balayage des inactifsExécution · jugement: aucun résultatContrôle des identifiantsAvec les 3 tentatives utilisées et aucun résultat, le job passe à needs_credential.
Toutes les connexions avec la même épaisseur. Choisissez un flux pour ne mettre en évidence que son chemin, avec des étapes numérotées.
- Trait plein · sens des entrées, résultats et enregistrements
- Tirets · exécution, jugement, requête
- Pointillés longs · observation et rapport, hors jugement
- Tirets courts · échec, arrêt, limite
- Trait noir épais · le flux sélectionné ; les numéros donnent l’ordre
- Cadre · frontière de code ou d’état, nommée dans l’en-tête
- Pastille intérieure · composant de cette frontière
- Cadre pointillé · hors de cette frontière
- Contour orange · là où un modèle décide
- Génération · dépenses · finalisation
- Entrée · règles de verdict · balayage
- File · état · enregistrements
- Enregistrement · contrôle de la file
Tracé d’après des enregistrements privés d’implémentation et de développement. Les données clients et les chemins de code ne sont pas montrés.
- Un balayage
- May 26, 2026, un cycle de balayage dans l’environnement de développement : 200 contrôlés, 106 transitions d’état, 2 remis en file. Une transition d’état n’est pas une traduction réussie, et la répartition des 106 par état de destination n’est pas consignée.
- Pourquoi pas exactement une fois
- Les enregistrements sont écrits sans doublons, mais si un job est relancé après un crash, les appels au modèle et leur coût peuvent se répéter. La limite de concurrence est par processus, pas à l’échelle du cluster.
- Portée du verdict
- Empêcher une moyenne de masquer un échec de glossaire est une règle d’agrégation sur les gates rapportées. Cela ne prouve pas que chaque terme interdit est trouvé ni que la qualité est celle d’un natif.