Personaggio sorridente di cotone dal logo originale di Cotton, senza sfondo e scritta
Torna alla sala

Cotton

Translation workflow

Trasformare traduzioni generate in risultati verificabili.

Un workflow di traduzione per i dialoghi di gioco.

2026.05.06 — 2026.05.26

Progetto di lavoro · elaborazione delle traduzioni, giudizio e percorso di revisione

  • App webImplementato · sviluppo

Cotton vocabulary

Lens
Refinement Loop
Translation
Quality Estimation
Workflow
Job Control
Human Review
  1. prompt layers
  2. glossary
  3. generation
  4. revision
  1. judge
  2. hard gate
  3. score
  1. intake
  2. checkpoint
  3. spend control
  4. stale sweep
  1. approval
  2. correction
  3. 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

Punteggi, nuovi tentativi e revisione umana, ciascuno al proprio confine.

Generazione e giudizio condividono il glossario, e un fallimento di hard gate riportato dal modello giudice non può essere compensato dalla media. Gli stati intermedi di traduzione e giudizio vengono registrati, i limiti di tentativi e di costo restano separati dalle credenziali esaurite, e i job bloccati tornano in coda o in revisione a seconda della causa.

Questo progetto di lavoro collega generazione delle traduzioni, giudizio di qualità riportato dal modello, nuovi tentativi e revisione umana in un unico flusso.

Dall’avvio del repository al lavoro confermato durante l’incarico

Una app web con schermate di modifica e approvazione delle traduzioni, un’API e un worker dei job, in esecuzione nell’ambiente di sviluppo.

Mappa del flusso di giudizio · da registri privati di implementazione
Cotton: giudizio delle traduzioni · nuovo tentativo · ripristinoL’API esegue il commit del testo sorgente e delle lingue di destinazione nel database, poi mette in coda un job per ogni lingua di destinazione. Un worker blocca la riga, controlla il tentativo, crea il draft e lo stato di avanzamento, genera una traduzione con il glossario e chiama separatamente un modello giudice con lo stesso glossario. La traduzione (Tx1) e il giudizio con le relative prove (Tx2) sono registrati in transazioni separate. Il codice aggrega il giudizio in modo che un fallimento di hard gate non sia compensato dalla media: un superamento viene finalizzato, un fallimento riceve un altro turn, il limite di turn o di costo manda alla revisione umana, e un segnale di quota o di autenticazione ferma la spesa e attende un controllo delle credenziali. Uno sweep dei job bloccati esamina fino a 200 draft più vecchi di 10 minuti: uno con tentativi residui ma assente dalla coda viene rimesso in coda, e uno con i tentativi esauriti va in revisione o al controllo delle credenziali a seconda che esista un risultato.Sorgente · lingue di destinazioneSegmenti salvatiRevisione umananeeds_review · non è un’approvazioneControllo delle credenzialineeds_credentialAPI · registrazione dei jobIn coda dopo il commitCoda dei jobBullMQ · ID del jobIngresso del jobBlocco della riga · controllo del tentativoGlossario · contestoGlossario del workspaceTurn di traduzioneGenerazione · chiamata al modelloChiamata al modello giudice · parsingRegole del verdettoHard gate · media ponderataNuovo tentativo · spesaTurn · costo · quotaStato della traduzioneDraft · avanzamentoRighe di traduzione · giudizioStato · log delle chiamateFinalizzazioneTransazione finaleControllo della codaConfronto dello stato della codaSweep dei job bloccatiDraft oltre 10 min · max 200Input · codaGenerazione · giudizioStato · accettazioneRipristino · decisione umana1sorgente2 dopo il commit · In coda dopo il commit → BullMQ · ID del job23 consegna del job · BullMQ · ID del job → Blocco della riga · controllo del tentativo34riga di avanzamento5tentativo consentito1glossario2 stesso glossario · Glossario del workspace → Chiamata al modello giudice · parsing23Tx1 · traduzione4Tx2 · giudizio5 punteggi · gate · Chiamata al modello giudice · parsing → Hard gate · media ponderata56verdetto7pass8registrazione finale1verdetto2turn successivo3limite · interruzione4quota · autenticazione5ripresa manuale1draft bloccato2 sotto il limite · Draft oltre 10 min · max 200 → Confronto dello stato della coda23rimessa in coda4 risultato presente · Draft oltre 10 min · max 200 → Revisione umana45nessun risultato

Registrazione → ingresso

Messo in coda dopo il commit del database; un worker blocca la riga, controlla il tentativo e crea il draft.

  1. Sorgente · lingue di destinazioneDati: sorgenteIn coda dopo il commitAPI · registrazione dei job

    I segmenti sorgente e le lingue di destinazione del progetto vengono salvati nel database. I dati dei clienti non sono mostrati.

  2. In coda dopo il commitAPI · registrazione dei jobDati: dopo il commitBullMQ · ID del jobCoda dei job

    Dopo il commit del database, per ogni lingua di destinazione attiva viene messo in coda un job con un ID legato alla richiesta. Se la messa in coda fallisce, si registra solo un avviso e il commit non viene annullato (nessuna outbox atomica), ed è per questo che esiste lo sweep dei job bloccati.

  3. BullMQ · ID del jobCoda dei jobEsecuzione · giudizio: consegna del jobBlocco della riga · controllo del tentativoIngresso del job

    BullMQ passa il job a un worker in modo asincrono.

  4. Blocco della riga · controllo del tentativoIngresso del jobDati: riga di avanzamentoDraft · avanzamentoStato della traduzione

    All’interno di una transazione la riga di avanzamento viene bloccata e si crea una traduzione draft. I tentativi automatici di job già finalizzati o sospesi per credenziali vengono saltati; le richieste manuali sono gestite a parte.

  5. Blocco della riga · controllo del tentativoIngresso del jobEsecuzione · giudizio: tentativo consentitoGenerazione · chiamata al modelloTurn di traduzione

    Il conteggio dei tentativi sale di uno entro il limite, poi parte il turn di traduzione.

Generare → giudicare → finalizzare

Generazione e giudizio usano lo stesso glossario; traduzione e giudizio sono registrati separatamente, e il codice aggrega il giudizio prima di finalizzare.

  1. Glossario del workspaceGlossario · contestoDati: glossarioGenerazione · chiamata al modelloTurn di traduzione

    Il glossario e il contesto del workspace vengono recuperati e passati alla generazione.

  2. Glossario del workspaceGlossario · contestoDati: stesso glossarioChiamata al modello giudice · parsingTurn di traduzione

    Il giudizio riceve gli stessi vincoli del glossario.

  3. Generazione · chiamata al modelloTurn di traduzioneDati: Tx1 · traduzioneRighe di traduzione · giudizioStato della traduzione

    Il modello viene chiamato direttamente o tramite un pivot en-US, e chiamata, evento e avanzamento vengono scritti in un’unica transazione. Se il job riparte dopo un crash, la chiamata di traduzione e il suo costo possono ripetersi.

  4. Chiamata al modello giudice · parsingTurn di traduzioneDati: Tx2 · giudizioRighe di traduzione · giudizioStato della traduzione

    Punteggi e prove del giudice vengono inseriti una volta per traduzione e turn; un duplicato trova la riga esistente, e le citazioni vengono scritte solo al primo inserimento. Non è la stessa transazione della traduzione.

  5. Chiamata al modello giudice · parsingTurn di traduzioneDati: punteggi · gateHard gate · media ponderataRegole del verdetto

    La risposta del modello giudice viene scomposta in punteggi per dimensione ed esiti dei gate. Il superamento del glossario è quanto riporta il modello giudice.

  6. Hard gate · media ponderataRegole del verdettoEsecuzione · giudizio: verdettoTurn · costo · quotaNuovo tentativo · spesa

    Qualsiasi fallimento segnalato di un hard gate significa zero e bocciatura; solo allora si applicano la media ponderata e le soglie per dimensione. La soglia complessiva di 8.0 è un valore predefinito di configurazione, non una qualità di traduzione osservata.

  7. Turn · costo · quotaNuovo tentativo · spesaEsecuzione · giudizio: passTransazione finaleFinalizzazione

    Un superamento viene finalizzato come translated.

  8. Transazione finaleFinalizzazioneDati: registrazione finaleStato · log delle chiamateStato della traduzione

    Candidato, stato, punteggio e turn vengono finalizzati, e l’avanzamento finalized insieme al log di stato viene scritto in un’unica transazione. Un evento di traduzione completata viene emesso solo per translated.

Nuovo tentativo · limiti di spesa

Nessun superamento significa un altro turn; un limite significa revisione umana; quota o autenticazione fermano la spesa e attendono la ripresa da parte di un operatore.

  1. Hard gate · media ponderataRegole del verdettoEsecuzione · giudizio: verdettoTurn · costo · quotaNuovo tentativo · spesa

    Qualsiasi fallimento segnalato di un hard gate significa zero e bocciatura; solo allora si applicano la media ponderata e le soglie per dimensione. La soglia complessiva di 8.0 è un valore predefinito di configurazione, non una qualità di traduzione osservata.

  2. Turn · costo · quotaNuovo tentativo · spesaEsecuzione · giudizio: turn successivoGenerazione · chiamata al modelloTurn di traduzione

    Una traduzione che non passa viene generata di nuovo con la traduzione precedente e la critica. Anche un fallimento di hard gate può essere ritentato prima, anziché passare subito a una persona.

  3. Turn · costo · quotaNuovo tentativo · spesaEsecuzione · giudizio: limite · interruzioneRevisione umana

    Quando i turn si esauriscono o si raggiunge il tetto di costo, il job viene finalizzato come needs_review. Finalizzato significa che l’elaborazione è terminata, non che una persona l’abbia approvato.

  4. Turn · costo · quotaNuovo tentativo · spesaFallimento · limite: quota · autenticazioneControllo delle credenziali

    Un segnale di quota o di autenticazione ferma la spesa e imposta needs_credential. Non c’è passaggio automatico a un altro account o provider. Gli errori di trasporto senza segnale di arresto tornano al retry di BullMQ.

  5. Controllo delle credenzialiEsecuzione · giudizio: ripresa manualeBullMQ · ID del jobCoda dei job

    Un operatore che ha verificato le credenziali riavvia esplicitamente.

Ripristino dei job bloccati

I draft vecchi vengono separati per motivo: se mancano dalla coda vengono rimessi in coda, se i tentativi sono esauriti decide una persona.

  1. Draft · avanzamentoStato della traduzioneOsservazione · resoconto: draft bloccatoDraft oltre 10 min · max 200Sweep dei job bloccati

    Vengono letti fino a 200 candidati in stato draft da oltre 10 minuti, a partire dai più vecchi. La query non acquisisce lock e aggiornamenti e log girano come istruzioni separate, quindi non viene descritto come un batch privo di race condition.

  2. Draft oltre 10 min · max 200Sweep dei job bloccatiEsecuzione · giudizio: sotto il limiteConfronto dello stato della codaControllo della coda

    Con meno tentativi del limite (3), il job viene confrontato con gli stati di coda active, waiting, delayed e prioritized. Nel codice il ramo dei tentativi esauriti viene prima di questo controllo della coda.

  3. Confronto dello stato della codaControllo della codaEsecuzione · giudizio: rimessa in codaBullMQ · ID del jobCoda dei job

    Se il job non è in coda, viene rimesso in coda. L’API usa ID con un suffisso di richiesta mentre lo sweep cerca per ID di segmento e di locale, quindi non viene descritto come corrispondente a ogni richiesta in corso.

  4. Draft oltre 10 min · max 200Sweep dei job bloccatiEsecuzione · giudizio: risultato presenteRevisione umana

    Con tutti e 3 i tentativi usati e un risultato di traduzione presente, il job passa a needs_review.

  5. Draft oltre 10 min · max 200Sweep dei job bloccatiEsecuzione · giudizio: nessun risultatoControllo delle credenziali

    Con tutti e 3 i tentativi usati e nessun risultato, il job passa a needs_credential.

Tutte le connessioni con lo stesso peso. Scegliendo un flusso se ne evidenzia solo il percorso, con passi numerati.

  • Continua · direzione di input, risultati e registri
  • Tratteggiata · esecuzione, giudizio, richiesta
  • Punti lunghi · osservazione e resoconto, separati dal giudizio
  • Tratteggio corto · fallimento, arresto, limite
  • Linea nera spessa · il flusso scelto; i numeri danno l’ordine
  • Riquadro · confine di codice o di stato, nominato nell’intestazione
  • Chip interno · un componente di quel confine
  • Riquadro punteggiato · fuori da quel confine
  • Contorno arancione · dove decide un modello
  • Generazione · spesa · finalizzazione
  • Ingresso · regole di verdetto · sweep
  • Coda · stato · registri
  • Registrazione · controllo della coda

Disegnato da registri privati di implementazione e sviluppo. Dati dei clienti e percorsi del codice non sono mostrati.

Un solo sweep
May 26, 2026, un ciclo di sweep nell’ambiente di sviluppo: 200 controllati, 106 transizioni di stato, 2 rimessi in coda. Una transizione di stato non è una traduzione riuscita, e la ripartizione delle 106 per stato di destinazione non è registrata.
Perché non esattamente una volta
I registri vengono scritti senza duplicati, ma se un job riparte dopo un crash, le chiamate al modello e il loro costo possono ripetersi. Il limite di concorrenza vale per processo, non per l’intero cluster.
Portata del verdetto
Impedire che una media copra un fallimento del glossario è una regola di aggregazione sui gate riportati. Non dimostra che ogni termine vietato venga trovato né che la qualità sia di livello madrelingua.