docs: 回写全仓库对契约套件的指向,以及 README、架构与 CHANGELOG

套件从 tests/contract/ 搬进 polyloop.testing 之后,全仓库 28 处引用要重新指过。修了 12 处,
其余在 design/(只增不改)与 scratch/(由人清理)里。

**CLAUDE.md 改了四处事实**:§0 权威表里行为契约的权威、§0 那句依赖规则的条数、§5 目录树与
模块数、§1.8 那句「谁断言公共 Protocol 的签名」。§1 的其余硬约束与 §2 的人类门一条没动。

**architecture.md**:分层图第 4 层加一格,装配层从三个变四个;代码地图加一行;第十节按代码
逐项重写——那笔「工具段渲染样式」的欠账**没有被数字对上盖掉**,加了 fingerprints 之后请求
的字段数恰好还是十一,而组成已经换过,所以那一节正面写着它仍然欠着;新增第十条依赖规则
(pytest 只在 testing 那个 extra 里,别处 import 它会让下游的生产环境一 import 本库就
ModuleNotFoundError),带静态与运行时两半;删掉「src/ 下一行代码都没有」那段过期状态说明;
决策索引补齐 0008 到 0016,其中四行原描述说的不是那份文档真正定的东西。

**migrations/dissect.md** 那笔「内存实现不存在」的欠账还掉了。

**压测那边**三条测试守的是一条已经撤销的公共契约,改名并写清它们现在守的是场景自己的选择。
AppWorld 那处刻意的偏离(不补三个反引号)留着不恢复——那条路径要模型输出被 stop 序列截断才
触发,而压测不配 stop 序列,恢复的收益不抵重跑一次压测的成本。但注释的理由改对了:它现在是
一笔有出处的欠账,不是一个决定。

CHANGELOG 攒在「未发布」段,版本号不提前写(§1.10)。
This commit is contained in:
2026-08-27 03:59:39 -04:00
parent 1fac387e75
commit c4e5732587
12 changed files with 246 additions and 80 deletions
+12 -8
View File
@@ -2,9 +2,11 @@
分三块:解析器、提示词装配、动作执行器。
解析器那块的前五条是 `tests/contract/test_decision_parser.py` 那份公共契约的逐条复刻。契约
套件本身是给下游接自己的实现用的(在自己的 `conftest.py` 里覆盖 fixture,压测这边不接那
套装配、只把五条断言照着写一遍——它是任何新适配器的准入标准,压测的适配器也是适配器。
解析器那块的前五条照着 `polyloop.testing.DecisionParserContract` 那份公共契约。契约套件
本身是给下游继承基类、在自己的子类里覆盖必需 fixture 用的,压测这边不接那套装配、只把五条
断言照着写一遍——它是任何新适配器的准入标准,压测的适配器也是适配器。其中一条另外多守了一件
公共契约没要求的事:`history_text` 不长于模型原文。公共契约不断言长度(解析器有权改写那段
文本,改写既可能截短也可能补写),那条断言守的是压测这一侧自己的选择——解析器一律只截不补。
执行器那块用一个假会话,不起容器:这里要验的是「环境返回什么 → 结果对象怎么填」这个映射,
而那个映射与容器里发生了什么无关。真起容器的那条链路由 `tools/soak/check_appworld.py` 走。
@@ -68,11 +70,13 @@ def test_parse_is_synchronous():
"什么代码都没有", # 一个围栏都没有
],
)
def test_history_text_never_grows(content):
"""`history_text` 不会比模型原文长(契约二)
def test_scenario_parser_only_trims_history_text(content):
"""`history_text` 不会比模型原文长。这守的是这个场景自己的实现选择,不是公共契约
这一条正是我们与被复刻的 dissect 实现分道的地方:dissect 在「未闭合围栏兜底」那一支给
历史文本补回结尾的三反引号,补一个字符就会让这条断言失败。
公共契约不断言长度:解析器有权改写回填历史的那段文本,改写既可能截短也可能补写
`polyloop.testing.DecisionParserContract`)。这个场景的解析器一律只截不补,所以长度
不会涨。它也正是我们与被复刻的 dissect 实现分道的地方:dissect 在「未闭合围栏兜底」那一
支给历史文本补回结尾的三反引号,补一个字符就会让这条断言失败。
"""
parsed = AppWorldParser().parse(_reply(content))
@@ -213,7 +217,7 @@ def test_empty_fence_is_a_failure_with_its_own_explanation():
def test_unclosed_fence_still_yields_code():
"""未闭合的围栏仍然抽得出代码,且历史文本不比原文长。
dissect 在这一支补回结尾的三反引号,我们不补——公共契约要求 history_text 不长于原文
dissect 在这一支补回结尾的三反引号,我们不补——压测的解析器一律只截不补
"""
content = "我来查一下。\n\n```python\nprint(apis.api_docs.show_app_descriptions())"