Skip to content

test(composition): 钉住 source_tree_digest 投影的单射性与其载荷约束 - #11

Merged
Go1c merged 1 commit into
mainfrom
fix/source-tree-projection-injectivity-test
Aug 29, 2026
Merged

test(composition): 钉住 source_tree_digest 投影的单射性与其载荷约束#11
Go1c merged 1 commit into
mainfrom
fix/source-tree-projection-injectivity-test

Conversation

@Go1c

@Go1c Go1c commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

来源

canonical 同族自查(TD 指派,起因是架构仓 canonical_object_pairs 拼接式编码可构造指纹碰撞)。自查结论:本仓无可利用暴露面,但发现一处无测试钉住的载荷性前提。

问题

composition 里唯一用字符串拼接构造摘要输入的地方是 source_tree_digest

format!("{}\n{}\n{}\n{}\n",
    native.component.as_str(), native.tree_id,
    voxel.component.as_str(),  voxel.tree_id)

这个格式自己不保证单射。值替换方向的显式碰撞(已实测):

输入 A: native_tree='X'                        voxel_tree='Y\nLumioVoxelEngine\nZ'
输入 B: native_tree='X\nLumioVoxelEngine\nY'   voxel_tree='Z'
→ 同一字节串,同一 SHA-256: 9de50127b5bec0946e5b876d50a0b2d7c508dc46fe552ddfd65a8951f8c15b28

挡住它的是 require_git_object_id(tree_id 恒为 40 位 [0-9a-f],换行与标签字符都不在字母表内)。但拼接在 resolve(),约束在 inspect_one(),跨函数,且没有任何测试钉住这条依赖——谁放宽约束或另开路径构造 SourceLock,拼接静默变回可伪造,所有现有测试保持绿。

这正是本项目已入册那条 lesson 的形状:守护的 precondition 锚在别处,且没人盯着那个锚。

补的三条测试:两半各自独立可判

测试 钉住
object_id_constraint_excludes_the_projection_delimiter_and_labels 约束这一半。含换行与含 component 标签的样本刻意取恰好 40 字符,必须被字母表挡住而不是被长度挡住——否则这两条性质其实没验证到
projection_is_injective_under_the_object_id_constraint 投影这一半。4096 组合法输入,每份投影唯一还原出 (native_tree, voxel_tree) 且互不相同
collision_ruled_out_by_the_object_id_constraint 两半的接合点。同时钉住「碰撞确实存在」与「约束确实挡得住」——只钉后者的话,将来有人删约束时没有任何东西提醒他删掉的是什么

失败信息一律点名是哪一半塌了。变异矩阵验证两半确实独立

变异 结果
放宽约束(去掉字母表检查,只留长度) 测试 1、3 FAILED;测试 2 仍绿(其输入本就合法,与约束无关)
改投影(移走 component 标签行) 测试 2、3 FAILED;测试 1 仍绿(不碰格式)

一处生产代码改动:纯抽取,零行为变更

把拼接抽成 source_tree_projection(),为的是让测试绑定真实投影。若测试里复制一份格式字符串,就成了 encode.rs 注释里点名的平行结构反模式——生产格式改了测试还绿。

零行为变更已实测:抽取前后 build_plan_digest = 10b3ebf8…source_tree_digest = f3fa3403… 逐字节相同

验证

just nextest 113/113(原 110 + 本次 3);fmt-check / clippy / deny / about / tool-lock / runtime-deps / check-contracts / check-generated / spec-lint + 17 项自测全部 exit 0。

授权

TD 明确授权的范围外补强,不属夹带;不改任何生产逻辑。

🤖 Generated with Claude Code

canonical 同族自查(TD 指派)发现:composition 里唯一用字符串拼接构造摘要输入的
地方是 source_tree_digest,而它的单射性**不是格式自己保证的**,是载荷在
require_git_object_id 上的——拼接在 resolve(),约束在 inspect_one(),跨函数,
且没有任何测试钉住这条依赖。谁将来放宽约束、或另开路径构造 SourceLock,
拼接就静默变回可伪造,而所有现有测试保持绿。

补三条测试,两半各自独立可判:

- object_id_constraint_excludes_the_projection_delimiter_and_labels(约束这一半)
  含换行与含 component 标签的样本刻意取**恰好 40 字符**,必须被字母表挡住而不是
  被长度挡住——否则「排除分隔符/标签」这两条性质其实没验证到。
- projection_is_injective_under_the_object_id_constraint(投影这一半)
  4096 组合法输入:每份投影都能唯一还原出 (native_tree, voxel_tree),且互不相同。
- collision_ruled_out_by_the_object_id_constraint(两半的接合点)
  值替换方向的显式碰撞对;同时钉住「碰撞确实存在」与「约束确实挡得住」。
  只钉后者的话,将来有人删掉约束时没有任何东西提醒他删掉的是什么。

失败信息一律点名是哪一半塌了,不必重新推导。

为让测试绑定**真实**投影而不是复制一份格式字符串(那正是 encode.rs 注释里点名的
平行结构反模式),把拼接抽成 source_tree_projection()。纯抽取、零行为变更:
抽取前后 build_plan_digest 10b3ebf8… 与 source_tree_digest f3fa3403… 逐字节相同。

授权:TD 明确授权的范围外补强(非夹带),不改任何生产逻辑。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Go1c
Go1c merged commit 980c83f into main Aug 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant