fix(i18n): recover translated markup before validation - #153
Conversation
Full-translation shards keep failing at packaging when translated pages contain JSX-looking damage (fabricated <id> elements, stray closers, bad attribute characters) that the strict MDX parsers in the repair chain reject while check-docs-mdx passes .md pages as plain Markdown. Add a parser-guided syntax repair stage that runs before the existing protected-attribute repair: - acceptance equals the downstream chain's tolerant parser, so valid Markdown constructs (HTML comments, prose less-than) pass untouched - fabricated elements absent from the source are removed with prose kept; missing or stray closing tags are resynced; void elements are self-closed; unquoted attribute values are quoted; unterminated comments are closed - deterministic bounded loop (64 patches) keyed to the parser's own diagnostics; unresolvable damage still fails the shard fail-closed Also validate --locale as a single safe path segment in both repair writers (the Python-side manifest validation runs only after the Node process has already written), and preserve UTF-16 length when masking comments so astral characters cannot shift diagnostic offsets. Artifacts record mdx_syntax_repair_outcome; failed shards keep the existing empty-artifact contract for the weekly reconciliation.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
- 冻结真实失败 fixture×2(run 27629404260 产物树:anthropic-vertex HTML comment 29:2、taxonomy Accordion/div 错配 1075:5),provenance 至翻译提交 fe5cb01 - strict-mdx-oracle.mjs(@mdx-js/mdx@3.1.1)回放可重复:worker 两次与 validator 独立重放字节级一致;historical-scan 696 页 6 失败 - experiment-schema.json 四类实验记录契约 + 无辅助基线(双 fixture final_failure exit 1) - 计划状态:STORY-01 done(validator=pi 结论 CONTINUE,策略 SHA-256 fddfca19…);解锁 STORY-02 - 未决留档:逐 shard 映射不可证、超时/重试阈值留给 STORY-03/03.1
- contract.md:唯一 Codex action 启动/修复/checker/同会话反馈/日志/可注入参数契约;AUXILIARY_MODE 仅 none/prettier/pr153(临时副本、hash 幂等、失败回同一 action) - fixture-map.json:2 真实 fixture 五入口映射 + 4 类 fail-closed 边界 + 3 类运行时故障 - validator=pi 逐条核实 4 条验收通过;结论 PATCH_PROMPT 处置为 STORY-03 补充要求(日志 repair_mode+顶层 error 三元组双写、checker 两条行为断言),冻结稿不回改 - 计划状态:STORY-02 done;解锁 STORY-03
- tools/mdx-fallback-lab/:六阶段本地实验闭环(npm test 7/7;checker 行为断言;辅助臂 fail-closed;参数全注入缺省 fail-closed) - 真实 opt-in(CODEX_HOME=/root/.codex,gpt-5.6-sol/high):plugin-html-comment enhanced=success(2 轮/210s,strict oracle 独立复核 compile_success)——AC-03 达成;taxonomy final_failure 诚实留档(1416:339 既有二次错误 → STORY-03.1 输入) - 参数演化 120s→300s 实测授权留档;三轮环境诊断归档;experiment.ndjson 含 repair_mode+顶层 error 三元组双写 - validator=delegate/economy 结论 CONTINUE(独立复核 npm test+oracle+ndjson+边界零越界) - 计划:非破坏迁移 v1→v2(plan-v2/,v1 保留审计);STORY-03 done,六项 AC passed=true - 依赖路径调整:CODEX_HOME personal 账号不支持 sol 且配额受限 → 默认账号;worker 沙箱禁网 → 宿主原生 subagent(用户授权 full access)
- D-09(owner=user):方案 A 仅增强现有 Codex action;多轮接力;300s 单轮实测;MAX_ATTEMPTS 注入默认 4;辅助不接入 - 接力实测:双 fixture enhanced=success(plugin 1 轮 70.7s;taxonomy 1 轮 166.6s 修复 1061/1075+1417 既有双错误,strict oracle 独立复核 exit 0,内容保留 3789/3790 行) - 实验记录追加至 8 条+三轮归档链;parameter-evolution 补 300s×4 条目;npm test 9/9 - 决策包 story03.1-decision-package-2026-09-04/(validator PATCH 修正后复核通过) - STORY-03.1 done:AC-01..05 passed;STORY-04 解锁(授权条件=D-09)
- translate-locale-reusable.yml:单入口 ≤4 轮有界接力(Repair→Enforce scope→Recheck,三重门控),env 注入 MDX_REPAIR_MAX_ATTEMPTS=4 / HARD_TIMEOUT_MS=600000(D-10)/ AUXILIARY_MODE=none(非 none fail-closed) - 新增 mdx_repair_relay.py decide/report:契约 §1 启动条件、预算与辅助 fail-closed、内容快照、无阈值内容丢失守卫、repair_mode/rounds/顶层 error 三元组、changed paths sha256 - package_artifact 逐页 partial-success(不可救页排除+标记);apply_artifacts finalizer 解释 failed_paths;docs-mdx-repair.md 更新接力措辞(D-09 授权,上游同步遗留已记录) - pytest 119 passed(11 新增+3 修改,含 2 个基线即红诚实修复);validator=delegate CONTINUE - STORY-04 done:AC-01..05 passed
- mdx-repair-validation.yml:workflow_dispatch+workflow_call;offline job 零 secret(工具链/全量测试/lab/oracle gate/单入口断言);real-codex-relay job(opt-in 门控、逐字节复刻生产接力、三态分类 success/agent_failure/environment_failure、artifact 先传后置红) - mdx_repair_validation.py:oracle-gate/single-entry/classify;preflight 复用生产分类 - 权限 contents:read、persist-credentials:false、无 push/发布 - pytest 132 passed(13 新增);validator=delegate CONTINUE - STORY-05 done;runner 实测留待交付推送后触发
- translate-locale-reusable.yml:mdx_repair_enabled(默认 false=原失败路径逐步等价)/canary_locales/canary_paths/canary_gate_failure_policy;mdx-repair-gate 前置作业复用 mdx-repair-validation(real_codex, secrets inherit);15 relay 步骤条件化;发布前 Consume gate(abort 先于发布);发布后 r2-smoke(28273967200 R2 stale 教训)+ release summary - mdx_repair_canary.py:decide/gate/summary/r2-smoke(fail-closed;证据缺失或不一致即拒) - 操作文档 docs/.i18n/mdx-repair-canary-operations.md - pytest 158 passed;validator=delegate CONTINUE(等价性独立复核) - 真实 canary 证据待推送后演练收集(AC-01/02/04 线上项)
- 首轮真实 canary 演练(run 33932528630)实证:--full-auto 被 0.146.1 拒绝,agent 未启动 - 移除 8 处(生产 relay 4 轮 + validation 4 轮);沙箱语义由 sandbox: workspace-write + safety-strategy: drop-sudo 表达 - 重要发现:生产原 Repair 步同写法 + continue-on-error → 上游升 pin 后生产修复链疑似已静默失效(STORY-07 复盘输入) - 版本探针 exports 兼容修复(@mdx-js/mdx、tsx);测试改为负向断言 + sandbox/drop-sudo 计数 - pytest 158 passed
- 源仓库 openclaw/openclaw go.mod 已要求 go>=1.26.0;dispatch 模式演练实测 docs-i18n 因 go 1.25.14+GOTOOLCHAIN=local 失败(5 次尝试全灭) - 预存版本漂移,与 canary 改动无关;生产 translate-full 因 workflow-ref artifact 自带工具链而未暴露
…w-ref 工具链) - check-docs-mdx 经 tsx shim 执行;生产 translate-full 由 workflow-ref artifact 携带 node_modules,dispatch 模式缺 tsx → MODULE_NOT_FOUND - 与 mdx-repair-gate 作业的显式 pin 同模式
- 分类 success(frozen_fixtures_pass_strict_recheck,600s×4/none),三 job success - 证据 story06-live-drill-2026-09-05/:三轮演练迭代(--full-auto 发现、sha 竞态、go/tsx 工具链)+ 分类/逐轮诊断/单入口/oracle gate - AC-01..04 passed;遗留进 STORY-07(live summary、relay 2-4 轮观察、上游 --full-auto 同步)
- GC-01..06 逐条结论:01/02/04/05 pass;03 pass(补字面整篇删除断言,npm test 10/10);06 pass-with-conditions(持续观察窗按 D-08 挂账至 PR 合并后首轮真实发布) - postmortem:--full-auto 静默失效窗取证(08-05 pin 升级→08-27 修复,22 天;生产原 Repair 步同写法+continue-on-error);辅助均不纳入(D-09);上游反哺清单 - 验收 commit=5a6345abb8,全部离线判据 validator 独立复跑通过(oracle sha256 与 runner 修复快照逐字节对齐) - STORY-07 done;8/8 stories、6/6 golden cases
Update: MDX repair fallback chain (Epic I18N-MDX-CODEX-FALLBACK) delivered on this branchThis branch gained 11 commits since TL;DRThe single codex-action entry is now an enhanced bounded relay (≤4 rounds, 600s/round, env-tunable); a read-only CI validation workflow and a canary/rollback mechanism were added (both default-off = byte-equivalent to current behavior); the real-failure fixture repairs pass locally AND on production runners. Bonus finding: the production repair chain had likely been silently failing for 22 days ( What was added (in commit order)
Key findings (postmortem highlights)
Notes for reviewers / maintainer
EvidencePlanning/evidence artifacts live in a local orchestration workspace (untracked as of |
- plans/ (epic/story plan, evidence, orchestration state) is a local working artifact, not part of the published docs mirror - removed from tracking; ignored locally via .git/info/exclude - files remain on disk for continued local development
Handoff: landing this PR, remaining work, and watch itemsHandoff notes for whoever lands this PR (or the next working session). The full golden acceptance lives in the comment above; this comment covers how to land, what remains, and what to watch. Landing procedure
Source-sha drift gotcha (cost us 2 failed drills)The workflow validates Post-merge observation checklist (plan D-08)
Cautions
Evidence index
|
Run bounded deterministic syntax recovery before the existing translation check. Correct known-element markup only, preserve source literal placeholders and element nesting, and keep every pending page unchanged when a repair cannot be established safely. Keep the existing model repair and empty failed-shard publication contracts. Recognize locale directories by their markers so English CI documentation does not break the translation regression suite. Co-authored-by: masonxhuang <masonxhuang@proton.me>
|
Maintainer verification for The final scope is conservative static-markup recovery before the existing checker. The expanded relay, canary, and partial-page publication architecture is excluded; the original branch history and Mason's credit are preserved. The contributor branch was updated by a fast-forward, without force-pushing.
Exact-head CI succeeded: translation checks and CodeQL. The source-owned prompt and generated docs are unchanged. All changelog notes, including thanks to @hxy91819, are consolidated in #169; land this PR first, then #169. No merge or publication has been performed by this worker. |
Update htmlparser2 to 12.0.0, Lucide to 1.41.0, Playwright to 1.63.0, and Wrangler to 4.129.0. Preserve the pinned published-anchor algorithms. Consolidate the complete Unreleased section, including translation-recovery credit from PR #153.
Translated markup damage can require an expensive model repair even when a deterministic correction is available. Run a bounded syntax-recovery step before the existing translated-MDX check, covering source-backed mismatched closing tags, void elements, and unquoted attributes.
The repair preserves literal placeholders, source element nesting, and attribute forms. It leaves unknown components, missing closers, unterminated comments, expression JSX, and ambiguous damage to the existing model repair. All repairs are staged in memory; a failure leaves the whole pending manifest unchanged. Existing protected-attribute checks, failed-shard publication rules, and the source-owned repair prompt remain in place.
Refresh the age-eligible translation runtime pins to Codex CLI 0.153.4 and tsx 4.23.13; both real binaries and the tsx-backed checker were exercised.
Also fix the translation regression suite's directory heuristic: an English
docs/cidirectory is source content, not a locale. The consolidated changelog and contributor credit are in #169, which should land after this PR.Validation: 123 translation tests and 153 Node tests passed; workflow shell and budget checks and actionlint passed. A separate live CLI replay exercised rejection, syntax recovery, revalidation, protected-attribute packaging, and empty failed artifacts. Review-driven regression cases cover literal-placeholder loss, unknown-component normalization, and incorrect element nesting. Final branch review and exact-head CI will be recorded in a proof comment.