3.9 KB · updated 2026-07-31 · md

v0.25.1.zh.md

docs/i18n/release-notes/v0.25.1.zh.md

Tesserae v0.25.1 — 编译不再卡死,降级的文档可以恢复

<!-- translations:start -->

English · 한국어 · 日本語 · Русский · Español · Français · Deutsch

<!-- translations:end -->

Released 2026-07-25 · PyPI · GitHub release · pip install --upgrade tesserae==0.25.1

这是一个 bugfix 版本。没有 API 变动 — 可以直接升级到 v0.25.0,但有一处行为 默认值被翻转了(见*升级*)。

这里的所有修复都来自一次调查。在一个真实项目上,编译卡在 0% CPU 长达 5 小时 43 分钟,后面跟着一个闲置了 4 小时 6 分钟codex exec 子进程。它已经在内存中生成了 32 个 COMMUNITY_SUMMARY 节点,但没有持久化,所以 graph.json 最后一无所有。 拉起这条线索后,浮出了三个更多的缺陷。

修复

  • 提取卡顿防护现在默认启用。 v0.25.0 发布了按文件提取超时,但是可选的 — 所以它保持关闭,它要防止的故障一直在发生。_run_cli 的进程组 killpg 一直连接正确;它就是从未触发,因为 communicate(timeout=None) 从不抛异常。 现在界限是每次尝试 1800 秒作为默认值。杀死卡死子进程的进程组让父编译 在*几秒内*恢复 — 它在 communicate() 中停留了四小时。

打字错误不能无声地解除安全阀门,所以无法使用的值(10m600s、负数、 inf)现在会警告并保留默认值而非回退到"无限制"。TESSERAE_EXTRACT_TIMEOUT=0 是显式逃生舱。

  • compile --retry-fallbacks 恢复降级为确定性的文档。 提取失败时,文档由确定性基线提供 — 但其清单条目与干净提取字节相同,所以 --changed-only 在随后每次编译中都跳过它,降级永久存在直到文件自身内容改变。 恢复少数文档需要手工编辑 manifest.json,带着摧毁数小时输入工作、 确定性填充整个语料库的风险。这些条目现在被标记并按需重试,镜像 distill --retry-fallbacks
  • graph_map 卡片上的 live_member_count sizeleaf_member_count 都来自编译中期写入的 hierarchy.json 边车。当 graph.json 之后被重写时, 两者发散,卡片可以宣传数百个成员实则无法解决 — 客户端无法通过重读 graph.json 本身区别于健康卡片。来自图的卡片(kind=community|node)现在也报告 *当前*图有多少成员。0 表示作用域已死:跳过它而非下潜。

在一个真实的 7,133 节点图上,这立刻浮出 2 个死根卡片和 42 个部分解决的卡片没人注意到。

  • _CLIENT_FACTORY 测试接缝遵从调用者的超时。 build_default_json_client 丢弃了它,给注入的假对象一个 30 秒默认值 无论如何 — 所以一个固定超时的测试无声地证明了什么。仅接缝; 生产构成已经正确了。

从 v0.25.0 升级

可以直接升级,有一点要知道:提取现在默认有时间界限 (每次尝试 1800 秒)。如果你故意想要无限制运行,设置 TESSERAE_EXTRACT_TIMEOUT=0

限制是每*次尝试*,不是每个文档 — 超时时客户端轮转到下一个 CODEX_HOME / claude 配置目录,所以文档的最坏情况是 timeout × 配置的 profiles 数。

如果过去的编译在确定性提取上留下了卡住的文档,用以下方式恢复:

tesserae compile --changed-only --retry-fallbacks

只有输入提取实际失败的文档才被重试;干净的保持跳过。