5 Commits

Author SHA1 Message Date
iomgaa 622b17f90c chore(release): 定版 1.0.3
CHANGELOG 的「未发布」段落定成 1.0.3(2026-08-29),上面留一个空段给下一版接着攒;两处版本号
(pyproject.toml 与 polyloop/__init__.py)同步。

发之前跑了一轮完整压测,与 1.0.2 那次验收逐项可比:正常负载 400 次运行、3501 次真实模型调用,
十一条不变量全部通过、零击穿、零无法判定;九类故障注入 58 条判据全部通过、零击穿,剩下那条
无法判定与 1.0.2 是同一条。产物在 tools/soak/runs/v1.0.3/(该目录在 gitignore 里)。

第一次开跑那轮作废:模型中转连返 20 次 503 打开了网关熔断,400 次运行全部快速失败以 llm_error
收尾,整轮 181 秒「跑完」。正常负载那一轮的记分板不开 --allow-undetermined,当场拦下、退出码
非零——一次什么都没验到的跑没有冒充通过,那道闸是对的。产物留在 v1.0.3-aborted-503/。

README 的三条安装命令不用改:约束是 polyloop==1.0.*,1.0.3 落在里面。这意味着钉了那个约束的
下游一次例行升级就会拿到这一版,而这一版有一次破坏性的行为变更(绑定里不带前缀的 session_id
与 parent_call_id 从静默转发变成抛 ValueError)——眼下没有下游在用,所以实际影响为零,
CHANGELOG 那一节把迁移写法写清楚了。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 14:19:30 -04:00
iomgaa d833b7a4d9 chore(release): 定版 1.0.2
CHANGELOG 的「未发布」段落定成 1.0.2(2026-08-27),上面留一个空段给下一版接着攒;
两处版本号(pyproject.toml 与 polyloop/__init__.py)同步。

发之前跑了一轮完整压测,与 1.0.1 那次验收逐项可比:正常负载 197 次运行、1845 次真实模型
调用,十一条不变量全部通过零击穿;九类故障注入 58 条判据全部通过、零 failed。库本身没有被
压出 bug。产物在 tools/soak/runs/v1.0.2/(该目录在 gitignore 里)。

README 的三条安装命令不用改:约束是 polyloop==1.0.*,1.0.2 落在里面。这同时意味着钉了那个
约束的下游一次例行升级就会拿到这一版,而这一版有一处行为变化(参数快照里注入内容的键形状)
——眼下没有下游在用,所以实际影响为零,CHANGELOG 里那一节把失败形态写清楚了。
2026-08-27 05:29:28 -04:00
iomgaa 1fac387e75 feat(testing): 契约套件搬进 polyloop.testing 随包发布,五套全部接上实现
tests/ 不进 wheel,所以那套被 CLAUDE.md §0 称作「任何新适配器的准入标准」的用例,第一个
下游根本拿不到。**接法同时换掉**:pytest 的 conftest 只沿被收集文件的目录链查找,装在
site-packages 里的测试模块看不见下游的 conftest,原来那个「在自己的 conftest 里覆盖同名
fixture」的接法在发布之后走不通。改成继承契约基类,下游的子类定义在自己的目录链上。

**搬的过程中发现这套准入标准从来没被执行过。** test_model_client.py 有四条用例调用
records.model_call(...),而工厂里根本没有这个方法——它没炸是因为那个 fixture 默认 skip。
五个接缝里只有存储那套被真跑过(15 条跳过里有 15 条是这四套)。

所以这个提交的另一半是让它真的跑起来。存储接两个实现(一份契约同时验多个实现,正是换接法
换来的);动作执行接注册表分发器,外加一个有真实等待点的替身,否则那条取消用例的断言半边
永远走不到;模型调用接网关适配器,落在 integration,它连的是真网关;决策解释与事件出口各
接一个测试替身——替身住在 tests/ 里不进 wheel,下游拿不到,所以不违反「库不带默认实现」,
判据是下游拿不拿得到。

**一并清掉两类坏用例。** 五条函数体只有 docstring、一个断言都没有却报 PASSED 的假绿——一个
准入标准里出现假绿比出现跳过糟得多,下游看到全绿会以为验过了。以及一条端口从没承诺过的
长度断言(len(history_text) <= len(reply.content)):压测的 AppWorld 场景为了迁就它,刻意
不补被复刻的实现真的会补的三个反引号,注释里写着「补一个字符就违约」。七条「这一层验不了」
统一成无条件 skip,理由字符串写全「承诺是什么/为什么验不了/你该在哪儿自己验」。

**发一个 pytest11 entry point,只为换回断言重写。** 契约模块不在下游的 python_files 里,
默认不被重写,于是一条契约失败时下游看到的是光秃秃的 AssertionError。不做的话没有任何东西
会报错,纯静默退化。实测过:editable 安装下 entry point 注册了但重写不生效(RECORD 里没有
包文件),要装真 wheel 才验得出来。
2026-08-27 03:59:16 -04:00
iomgaa 303e4ebc1c chore(release): 打包元数据补齐,版本定到 1.0.1
发布前置:readme 与 project.urls 从第一版就写全——缺 readme 的话 registry 包页面正文一片
空白,而 twine 只警告不阻塞上传,三步全绿产物却是坏的(PolyGateway 1.1.2 的教训)。
build 与 twine 钉进 dev extra 而不是靠人手装,PolyGateway 那边它们不在任何 extra 里,
于是发布指南得多写一条「记得先装」,那种步骤迟早有人漏。

README 里那条「项目还没有可用的功能、十个模块是空骨架」的横幅早就过期了,而打包会把当时的
README 固化进 sdist、发布后再改无效,所以在构建之前换成安装说明与现状。顺带修两处与事实
不符的:GovDoc-SaaS 的实现已经在 8 月 3 日整体清空,⑥ 对它的验收标准改成设计级验收。

新建 CHANGELOG.md,写清楚首个版本为什么是 1.0.1 而不是 0.x——「公共类型的字段只增不删不
改名」那条承诺从第一个下游装上它那天起就生效,而 0.x 意味着随时可以破坏兼容。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 00:11:04 -04:00
iomgaa e017160c45 build(repo): 落成工具链、依赖契约与十个模块的空骨架
第 ③ 阶段剩下的那半:架构文档之外,import-linter 契约也落地了。

pyproject.toml 把九条依赖规则里的七条写成五条 import-linter 契约。
分层用一条 layers 契约表达规则 1、2、3、8,`|` 表示同层互不 import;
另外四条 forbidden 分别管下游反向 import、polygateway 的唯一入口、
以及三个纯逻辑模块不碰 asyncio 与 pathlib。
契约不是平凡的绿:故意注入两处违规验证过,都被点名到行号。

先建十个模块的空包,是为了避开 PolyGateway bootstrap 期那段 Makefile 门控——
它当时没有包,lint-imports 报 module not found 而红,只好加一段跳过逻辑。
空包让契约从第一天就真的在跑。

剩下两条规则落不进契约,写成了 tests/unit 下的测试:
规则 6「types 与 ports 不许 import 任何第三方」判据要反过来写(只许标准库和自己),
规则 9「import polyloop 之后 sys.modules 里没有 polygateway」是运行时事实。
另加硬约束 §1.1 零业务假设的黑名单扫描——它第一次跑就抓到 _assembly 的 docstring
里写了 dissect 的业务词,已改。三个扫描类测试都带 fail-closed 守卫,
防止目录搬走之后扫到空列表安静地绿。

工程约定取自实验室已有项目:setuptools + src layout、ruff 十一项 select、
line-length 100 来自 PolyGateway;dev 工具链版本钉死、--strict-markers 与
--import-mode=importlib 来自 CHSAnalyzer 与 dissect 踩过的坑,各自的理由写在配置注释里。
e2e 默认不跑,它打真实网关要花钱。

CLAUDE.md §0 那句「契约还没写,要等 src/ 落地」已过期,改掉;
README 勾掉第 ②③ 阶段,补上本地检查命令与 GovDoc-Editor 那一行。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 21:28:59 -04:00