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()中停留了四小时。
打字错误不能无声地解除安全阀门,所以无法使用的值(10m、600s、负数、 inf)现在会警告并保留默认值而非回退到"无限制"。TESSERAE_EXTRACT_TIMEOUT=0 是显式逃生舱。
compile --retry-fallbacks恢复降级为确定性的文档。 提取失败时,文档由确定性基线提供 — 但其清单条目与干净提取字节相同,所以--changed-only在随后每次编译中都跳过它,降级永久存在直到文件自身内容改变。 恢复少数文档需要手工编辑manifest.json,带着摧毁数小时输入工作、 确定性填充整个语料库的风险。这些条目现在被标记并按需重试,镜像distill --retry-fallbacks。graph_map卡片上的live_member_count。size和leaf_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
只有输入提取实际失败的文档才被重试;干净的保持跳过。