docs/design/2026-08-18-autofix-handoff-bilingual.md
Date: 2026-08-18 Status: draft — awaiting maintainer sign-off
The autofix loop's failure-path handoff comments (e.g. the round-6
growth-brake escalation on PR #9262, comment 5321766307) are English-only.
Every other static comment the workflow posts — takeover acks, re-arm,
dispatch refusal, milestone, base-updated, review-deferred — is already
bilingual (English first, Chinese in a collapsed
<details><summary>中文说明</summary> block). The handoff comments are the
ones that most need Chinese: they stop the loop and ask a maintainer to make
a decision (split / redesign / accept-residuals), and a Chinese-speaking
maintainer should be able to act on them without translating a wall of
English first.
qwen-autofix.yml, failure path of the Address review feedback job
(~L6660–7050), builds <workdir>/report.md and posts it with gh pr comment:
HEADLINE — one of ~9 bash-generated English templates:
**What I found before stopping:** (or the NOT-pushed
warning) + the first 1500 bytes of DETAIL_FILE — the first non-empty of
failure.md, handoff.md, address-summary.md, no-action.md —
passed through iconv -c and <!-- escaping.**Why it was not pushed:** + up to
3900 bytes of gate-rejection.md (written by reject_fix() in
.github/scripts/run-autofix-review-verification.sh; static reason
sentence + untranslatable log evidence), fenced by
<!-- autofix-gate-rejection-start/end -->.🧠 Handled by Qwen Code signature, and the
autofix-eval / autofix-growth-now / autofix-redcheck markers. The
next scan parses these markers out of the raw comment body.Agent-written failure.md is the content of the decision-relevant part
(options, recommendation). SKILL.md currently mandates failure.md and
handoff.md stay English-only WITHOUT a details block, because the comment
embeds a byte-truncated excerpt: a severed <details> tag would swallow the
rest of the rendered comment.
failure.zh.mdWhenever the agent writes <workdir>/failure.md, it must also write
<workdir>/failure.zh.md — a complete paragraph-by-paragraph Chinese
translation. Constraints encoded in SKILL.md's GitHub Actions Rules:
<details>, no <summary>);<!-- sequences;<details> wrapper.failure.md itself stays English-only (excerpt-safety unchanged).
handoff.md remains run-agent.mjs-owned and English-only.
Every HEADLINE= assignment gains a HEADLINE_ZH= sibling (~23 static
strings total, including the CAUSE / LAST_FIX / GATE_CLAUSE clause
variants). Same composition shape as the English side, e.g. the needs-human
path:
HEADLINE_ZH="🤖 未能为该反馈产生通过验证的修复(第 ${MARK_ROUND}/${MAX_ROUNDS} 轮)${GATE_CLAUSE_ZH}。此项现在需要人工处理;循环保持在线,仍会拾取新反馈与 base 冲突,但不会自行重试此项。"
Precedent for parallel _ZH variables already exists in the workflow
(WIN_DESC_ZH in the milestone comment).
Section labels inside the report block also gain Chinese handling inside
the details block: the two branch-selected labels that open the excerpt
(**What I found before stopping:**, the NOT-pushed warning) are
translated. **Why it was not pushed:** and the stale-base note are NOT —
they open the gate section whose body stays English, and a pointer sentence
inside the details block tells the zh reader the evidence is above. The
no-detail fallback sentence has no counterpart by construction: when
DETAIL_FILE is empty failure.zh.md cannot exist (it is only written
alongside failure.md, itself a DETAIL_FILE candidate), so the details
block degrades to the headline translation alone, which already carries
that state (see §5).
English body unchanged. Immediately before the Run log: line, insert:
<details>
<summary>中文说明</summary>
${HEADLINE_ZH}
**停止前我了解到的情况:**
[excerpt of failure.zh.md — only when the file exists]
[one line: gate-rejection evidence stays English, see above — only when
gate-rejection.md is present]
</details>
Markers stay last and ASCII-untouched, so the next scan's parsing is unaffected. The wrapper tags are emitted by the workflow, so a truncated translation can lose content but can never swallow the comment tail.
head -c 3000 (Chinese is ~3 bytes/char, so ≈1000 chars — roughly the same
information as the 1500-byte English excerpt), then iconv -f utf-8 -t utf-8 -c, then sed escaping: <!-- (as today) plus <details,
</details, <summary → full-width < forms, so a pathological
translation quoting markup cannot break the wrapper. <workdir> style
angle-bracket prose stays intact.
Budget knobs live next to the existing 1500/3900 constants with a comment.
failure.zh.md missing (run-agent.mjs wrote failure.md itself on crash
/ loop-guard / missing-output paths; or the agent skipped it) → the
details block still renders HEADLINE_ZH alone. Never fail the round
over a missing translation.DETAIL_FILE = address-summary.md / no-action.md (already bilingual
by SKILL contract) → those files have no failure.zh.md sibling;
headline-only details block is correct for them too. (Their mandated
<details> tail can still be severed by the 1500-byte cut — the excerpt
site neutralizes the tag forms so the severed opener is inert.)REASON (REASON_ZH sibling per branch), mirroring
the PR-lane headline floor; the sanitized failure.zh.md excerpt joins the
block only when present. Crash shapes (run-agent.mjs wrote failure.md
itself, no companion) therefore still show the Chinese withdraw sentence.In GitHub Actions Rules, extend the bilingual-outputs rule: keep the
English-only requirement for failure.md/handoff.md, add the
failure.zh.md companion requirement with the constraints above. The
growth-brake handoff directive (workflow feedback.md text and SKILL's
defer-to-human item) relies on the general rule — no per-mode repetition.
scripts/tests/qwen-autofix-workflow.test.js)Extend the existing handoff-comment describe block (~L13086):
中文说明 details block and the Chinese
headline;failure.zh.md companion rule present; failure.md
remains English-only.gate-rejection.md body translation — evidence is log output; the
translated GATE_CLAUSE already tells a Chinese reader the gate rejected
the attempt. (Maintainer default; veto before sign-off if wanted.)qwen-fleet-shepherd.yml escalation comments — separate workflow.handoff.md preface lines (rare fallback path).failure.zh.md under budget pressure → degraded but
functional (headline-only details). No round outcome changes.