iomgaa
|
3492a2994a
|
feat(session): 参数快照补上配方指纹与注入通道,并写定执行器抛异常的契约
四件事,都来自第一个下游的 issue。
**RunRequest 新增 fingerprints。** 上下文与注入内容刻意不进快照(它们是数据不是参数),
而这条规则把生成它们的提示词模板也一起挡在外面了。具体的失败场景:换一份模板续跑不报错,
前几步用 A 模板、后几步用 B,那次运行的数据已经废了却没有任何提示。键形状
request.fingerprint.<name>,和 model_binding 那个坐标分开——一个是「这次运行属于哪一格」,
一个是「用的配方是哪一版」,混在一个字段里事后分不开。默认空映射时一个键都不写,所以已有
配置算出来的快照逐字节不变。
**注入的通道维度不再拍平。** 一通道一键,于是「声明了通道但一条都没选中」和「压根没有这个
通道」分得开:前者是值为空串的键,后者是键不存在。有一档实验要比较的正是这两种情形。
**ActionExecutor 的 docstring 写定抛异常时会怎样**:环境故障走 ENV_ERROR 返回值,实现方真
抛了库不接管、异常原样穿出。理由在 design 0016;简言之库替它编一个结算结果就是在编造,而
副作用状态在那一刻是未知的。
**三个映射字段在构造期冻成只读。** 对抗审查发现 frozen=True 不禁止改字段里那个 dict,于是
构造期那道「快照取值必须是字符串」的校验能被绕过去:构造完往 fingerprints 里塞一个整数,
它一路进日志,要到续跑读日志时才炸——而那时这次运行已经完整跑过一遍。复用 tools 里已有的
_frozen,没另写一套。
|
2026-08-27 03:58:49 -04:00 |
|
iomgaa
|
6fafd95d6c
|
feat(tools): 落成 executor() 与派生分发器;公共数据类一律只收关键字参数
两个自行调研后决定的问题,各自的证据写进了 design doc:
一、handler 返回 str 而不是带截断计数的小结构(0008 决策三,文末新增一节)。三条实据:
两个真实消费者的执行函数今天就返回纯字符串(GovDoc 的 handler 是 Coroutine[..., str],
dissect 的环境 execute 是 -> str);dissect 的 observation_truncated_chars 唯一的生产写入点
硬编码 0 且全仓零读取点,存在的是名字不是需求;reference/pi 是唯一把截断做完整的,它记的是
totalBytes/outputBytes/maxBytes 这组绝对量而不是一个差值——现在补 truncated_chars 补的
大概率是错形状,正是 scope.md 说的「猜出来的接缝比没有接缝更难拆」。
二、新增 design 0009:src/polyloop/ 下每个数据类都加 kw_only=True,另加一条扫描测试守它。
实验室七个仓库 223 个 dataclass 里 kw_only 出现零次,但那是默认行为不是选择。真正的证据是
PolyGateway:它的 LLMResponse 前 11 个字段顺序被三个下游的测试替身按位置构造锁死,模块
docstring 写着「字段顺序即公共承诺」,还得专门写一条 test_eleven_legacy_fields_positional
守着,从此再也插不进字段。那个约束不是它选的是它继承的,而本库还没有下游装上。
扫描测试查的是构造签名不是那个装饰器参数——要守的承诺是「按位置构造不了」。
executor() 在派生那一刻全查一遍实现,缺一个就报错,不拖到分发时才炸。RegistryExecutor 是
具体类而不是闭包,因为 RunRequest 要用 isinstance 认它。CancelledError 不被那个
except Exception 接住(它继承 BaseException),有测试守着。
|
2026-08-10 01:19:15 -04:00 |
|
iomgaa
|
956d98652d
|
fix(tools): 修掉两个假阳性与一个改得动的内部状态,按两轮独立评审
代码审查(新鲜上下文,只给 diff 与验收标准)报了五条影响正确性的,逐条核实全部成立:
1. spec_for() 交出去的 parameters 就是注册表内部那份真字典。docstring 承诺的快照只挡住了
「调用方改自己那份」,没挡住「从注册表取出来往里伸一层改」——而后者一下同时改掉模型
看见的 schema 和校验用的 schema。改成逐层冻成只读视图,schema_for_model 出口再化回
普通字典与列表。
2. {type: integer} 拒掉 3.0。JSON Schema draft-06 起小数部分为零的浮点数是合法整数,
模型写 1e2 时 json.loads 给的就是 float。这是我自己在注释里点名最怕的那种假阳性。
3. additionalProperties: false 撞上 patternProperties 时拒掉一切匹配 pattern 的键。
那些正是这份 schema 专门要收的键,模型改名也绕不过去。patternProperties 在场就跳过。
4. 工具名不校验类型、纯空白名放行。名字要落进发给模型的 schema,不是字符串会让整个请求
被网关拒掉,报错指向请求体不指向注册表。
5. _by_name 是可变 dict,两条查询路径能被就地改到分岔。换成只读视图。
不可哈希那条不修,改在 docstring 里写明(参数 schema 是映射,注册表放不进 set)。
scope.md 的行号引用换成条目名——行号是最容易漂的一种参数,插一行就静默指错。
0008 按一轮硕士生冷读重写:字段位置那段原来自相矛盾(一边说位置是公共承诺、插在中间会
静默改掉后面字段的含义,一边就插在中间,且没讨论追加在末尾这个同一判据下的显然选项),
改成追加在末尾并说明规则;补上四个名字的就地解释(重放策略、两条完成通路、动作结果五个
字段、restrict_to);决策四那张表原来只有三列却被正文说成填五个字段,恒定的两个单列出来
并各自给了理由;补上 validate 不通过为什么算未执行、executor() 为什么全查、为什么必须是
具体类而不是闭包、异常栈去哪了。
|
2026-08-10 00:57:36 -04:00 |
|
iomgaa
|
30895cd306
|
feat(tools): 落成工具规格与注册表,四者同源由同一个实例驱动
ToolSpec 五个字段加构造期校验(空名字、非映射 parameters),parameters 深拷贝一份存下来
——不拷贝的话调用方在别处改那个字典会连带改掉模型看见的 schema,而那次修改没有任何地方
记录得到。
ToolRegistry 是不可变值对象:注册顺序保留(工具清单要贴进提示词,而 restrict_to 收到的
常常是 set,照集合顺序输出会让同一份配置在不同进程里渲染出不同提示词);相等按内容判
不按身份判,供 RunRequest 那条一致性校验用;restrict_to 遇到不认识的名字直接报错,
不静默丢弃。
validate 校验的是 JSON Schema 的一个子集(必填键、additionalProperties: false 时的多余键、
顶层 type),子集边界写在 docstring 里。完整校验只能靠第三方库,而公共签名上不许出现
第三方类型。剩下那部分由工具自己报错,那是一条正常观察。
executor() 没写,缺口见 design/0008(待确认,要过人类门)。
|
2026-08-10 00:45:53 -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 |
|