
Cotton
Translation workflow
Turning generated translations into reviewable results.
A translation workflow for game dialogue.
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, retries and human review, each at its own boundary.
Generation and judgment share the glossary, and a hard-gate failure reported by the judge model cannot be offset by the mean score. Intermediate translation and judgment states are recorded, retry and cost limits are kept apart from exhausted credentials, and stalled jobs return to the queue or to review depending on the cause.
This work project connects translation generation, model-reported quality judgment, retries and human review in one flow.
From the start of the repository to the work confirmed during the engagement
A web app of translation editing and approval screens, an API and a job worker, running in the development environment.
Registration → entry
Queued after the database commit; a worker locks the row, checks the attempt and creates the draft.
Source · target localesData: sourceQueue after commit
API · job registrationSource segments and the project’s target locales are stored in the database. Customer data is not shown.
Queue after commit
API · job registrationData: after commitBullMQ · job IDJob queueAfter the database commit, a job with a request-scoped ID is queued per active target locale. If queueing fails, only a warning is logged and the commit is not rolled back (no atomic outbox), which is why the stale sweep exists.
BullMQ · job ID
Job queueRun · judgment: deliver jobRow lock · attempt checkJob entryBullMQ hands the job to a worker asynchronously.
Row lock · attempt check
Job entryData: progress rowDraft · progressTranslation stateInside a transaction the progress row is locked and a draft translation is created. Automatic retries of finalized or credential-paused jobs are skipped; manual requests are handled separately.
Row lock · attempt check
Job entryRun · judgment: attempt allowedGenerate · model callTranslation turnThe attempt count goes up by one within its limit, then the translation turn starts.
Generate → judge → finalize
Generation and judgment use the same glossary; the translation and the judgment are recorded separately, and code aggregates the judgment before finalizing.
Workspace glossary
Glossary · contextData: glossaryGenerate · model callTranslation turnThe workspace glossary and context are looked up and passed to generation.
Workspace glossary
Glossary · contextData: same glossaryJudge model call · parseTranslation turnThe judgment gets the same glossary constraints.
Generate · model call
Translation turnData: Tx1 · translationTranslation · judgment rowsTranslation stateThe model is called directly or through an en-US pivot, and the call, event and progress are written in one transaction. If the job runs again after a crash, the translation call and its cost can repeat.
Judge model call · parse
Translation turnData: Tx2 · judgmentTranslation · judgment rowsTranslation stateJudge scores and evidence are inserted once per translation and turn; a duplicate finds the existing row, and citations are written only on the first insert. Not the same transaction as the translation.
Judge model call · parse
Translation turnData: scores · gatesHard gate · weighted meanVerdict rulesThe judge model’s answer is parsed into per-dimension scores and gate results. Whether the glossary passed is what the judge model reports.
Hard gate · weighted mean
Verdict rulesRun · judgment: verdictTurns · cost · quotaRetry · spendingAny reported hard-gate failure means a zero and a fail; only then are the weighted mean and per-dimension thresholds applied. The overall threshold of 8.0 is a configuration default, not an observed translation quality.
Turns · cost · quota
Retry · spendingRun · judgment: passFinal transactionFinalizationA pass is finalized as translated.
Final transaction
FinalizationData: final recordState · call logTranslation stateCandidate, state, score and turns are finalized, and progress finalized plus the state log are written in one transaction. A translation-complete event is emitted only for translated.
Retry · spending limits
No pass means another turn; a limit means human review; quota or auth stops spending and waits for an operator to resume.
Hard gate · weighted mean
Verdict rulesRun · judgment: verdictTurns · cost · quotaRetry · spendingAny reported hard-gate failure means a zero and a fail; only then are the weighted mean and per-dimension thresholds applied. The overall threshold of 8.0 is a configuration default, not an observed translation quality.
Turns · cost · quota
Retry · spendingRun · judgment: next turnGenerate · model callTranslation turnA translation that does not pass is generated again with the previous translation and critique. Even a hard-gate failure can be retried first rather than going straight to a person.
Turns · cost · quota
Retry · spendingRun · judgment: limit · abortHuman reviewWhen the turns run out or the cost ceiling is reached, the job is finalized as needs_review. Finalized means processing ended, not that a person approved it.
Turns · cost · quota
Retry · spendingFailure · limit: quota · authCredential checkA quota or auth signal stops spending and sets needs_credential. There is no automatic switch to another account or provider. Transport errors without a halt signal go back to BullMQ retry.
Credential checkRun · judgment: manual resumeBullMQ · job ID
Job queueAn operator who has checked the credentials restarts explicitly.
Stale job recovery
Old drafts are split by reason: missing from the queue means re-queue, attempts used up means a human decision.
Draft · progress
Translation stateObservation · report: stale draftDrafts over 10 min · max 200Stale sweepUp to 200 candidates that have been drafts for over 10 minutes are read, oldest first. The query takes no lock and updates and logs run as separate statements, so this is not described as a race-free batch.
Drafts over 10 min · max 200
Stale sweepRun · judgment: below limitCompare queue stateQueue checkWith fewer attempts than the limit (3), the job is compared with the active, waiting, delayed and prioritized queue states. In code the attempts-exhausted branch comes before this queue check.
Compare queue state
Queue checkRun · judgment: re-queueBullMQ · job IDJob queueIf the job is not in the queue, it is queued again. The API uses IDs with a request suffix while the sweep looks for the segment and locale ID, so it is not described as matching every in-flight request.
Drafts over 10 min · max 200
Stale sweepRun · judgment: result existsHuman reviewWith all 3 attempts used and a translation result present, the job goes to needs_review.
Drafts over 10 min · max 200
Stale sweepRun · judgment: no resultCredential checkWith all 3 attempts used and no result, the job goes to needs_credential.
Every connection at the same weight. Pick a flow to highlight only its path, with numbered steps.
- Solid · direction of input, results and records
- Dashed · run, judgment, request
- Long dots · observation and reporting, apart from judgment
- Short dashes · failure, stop, limit
- Heavy black line · the selected flow; numbers give the order
- Box · code or state boundary, named in its header
- Inner chip · a component of that boundary
- Dotted box · outside that boundary
- Orange outline · where a model decides
- Generation · spending · finalization
- Entry · verdict rules · sweep
- Queue · state · records
- Registration · queue check
Drawn from private implementation and development records. Customer data and code paths are not shown.
- One sweep
- May 26, 2026, one development-environment sweep cycle: 200 checked, 106 state transitions, 2 re-queued. A state transition is not a successful translation, and the split of the 106 by destination state is not recorded.
- Why not exactly once
- Records are written without duplicates, but if a job runs again after a crash, model calls and their cost can repeat. The concurrency limit is per process, not cluster-wide.
- Scope of the verdict
- Keeping a mean from covering a glossary failure is an aggregation rule over reported gates. It does not prove that every banned term is found or that quality is native-level.