Skip to content

fix(ops): C-locale CJK rg crash wiping health-round SYNTH — argv direct pass + LANG bridge - #222

Draft
steponeerror wants to merge 1 commit into
masterfrom
feature/synth-cjk-locale
Draft

steponeerror wants to merge 1 commit into
masterfrom
feature/synth-cjk-locale

Conversation

@steponeerror

Copy link
Copy Markdown
Owner

问题

线上 v1.4.2-721 起每个健康轮 SYNTH 步必炸 inject_precedents: rg 检索失败(rc=2)——基础设施故障,整轮 failed(回归起点 2026-10-25-1900-health;10-24-1800 及之前全绿)。

触发链:#196 C4 spawn env 白名单剔掉 LANG → 轮子进程 bash 退 C locale → lib.sh 的 $(printf -- '-e %q ' …) 命令替换在 C locale 下给 CJK 检索词(锚词表 19 词含 7 个中文)包 $'\351\…' ANSI-C 字面量,且命令替换输出不再经词法解析 → rg 模式含 $'/八进制转义被解析为反向引用 → regex parse error rc=2。线上探针抓到实锤:error: backreferences are not supported(模式内可见 (?:$'\351\231\220\346\265\201')=「限流」)。

修复(两层)

  • 根治层 ops/agent/lib.sh inject_precedents:弃 printf %q 命令替换拼参,改 argv 数组直传(rg_args+=(-e "$kw"))——任何 locale 下 CJK 原样字节进 argv,与 locale 彻底解耦;输出块格式零变(t4 golden 三方字节对拍钉死)。
  • 环境层 backend/ipdb/_ops_rounds.py _round_env() 桥注入 "LANG": os.environ.get("LANG") or "C.UTF-8"(继承操作员值,缺省 C.UTF-8)——防 bash 面 locale 敏感行为同类复发;LC_* 永不过白名单,LANG 即主宰,只管 LANG 最小且够。

测试

  • ops/agent/selftest.sh 新增 C-locale 回归钉:env -i 子壳(仅 PATH)带 CJK 词调 inject_precedents,三断言(注入头/fixture 真命中/无「rg 检索失败」且 rc=0);红证=旧 lib.sh 下恰该例 2 断言红(117/2)。
  • backend/tests/test_ops_rounds.py:SPAWN_ENV_EXACT 硬编码对拍集加 LANG;新增 test_round_env_lang_locale_determinism(delenv→C.UTF-8 缺省、setenv→继承原值)。

验证

  • bash ops/agent/selftest.sh → PASS=119 FAIL=0(基 116)
  • node ops/agent/selftest-t4.mjs → PASS=63 FAIL=0(golden 字节对拍=输出零变)
  • cd backend && python -m pytest tests/test_ops_rounds.py tests/test_ops_config.py -q → 81 passed(基 80)
  • 手工钉死复现消亡:env -i PATH=… bash -c '. lib.sh; PRECEDENTS_DIR=… inject_precedents 限流 排他率' → 注入块 9 命中、exit 0(旧码同调用 rc=2)

部署后

线上积压的 failed 轮无需人工处理:修复部署后下一个健康轮起自然恢复;失败期间台账已留 spawn error_code=infra 痕迹。

SDD:实现票 + 独立 task review(Standards/Spec 双轴 PASS,0 P0/P1,2 P2 report-only)+ 整分支终审(主会话亲跑三道门对拍数字一致)。

closes none(线上热修,无对应 issue;根因回归源 #196 已在注释与 CHANGELOG 记账)

…ct pass + LANG bridge injection

线上 v1.4.2-721 起每个 health 轮 SYNTH 步必炸 inject_precedents: rg 检索失败
(rc=2)。根因:#196 C4 spawn env 白名单丢 LANG→轮子进程 bash 退 C locale→
printf %q 给 CJK 检索词输出 $'\\351…' ANSI-C 字面包裹→命令替换输出不再经
词法解析→rg 模式含 $'/八进制转义被解析为反向引用→parse error rc=2。回归
起点 2026-10-25-1900-health。

两层修复:
- 根治层 lib.sh inject_precedents:弃命令替换拼参,argv 数组直传
  (rg_args+=(-e "$kw")),与 locale 彻底解耦;输出块格式零变(t4 golden
  三方对拍钉)。
- 环境层 _round_env():桥注入 LANG(继承操作员值,缺省 C.UTF-8)。

测试:selftest.sh 新 C-locale 回归钉三断言(env -i 子壳 CJK 词必命中不炸);
test_ops_rounds 白名单对拍集同步 LANG + LANG 继承/缺省两断言。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant