BLOGE
0.9.8-RC1在线版 · 事实校验 2026-09-15 · English
第 29 章 —— 从报告到 Source-bound Evidence
本章承诺: 区分业务结果和密封目录,把 receipt 保存在目录之外,并用独立 reader 判断 evidence 只是字节完整、已经绑定源码,还是得到外部 attestation。
学习目标
- 解释 report、manifest、seal、receipt 和 reader 各自的职责。
- 区分
LOCAL_INTEGRITY、SOURCE_BOUND和ATTESTED。 - 判断字节、目录位置、Git commit 或 runtime cohort 改变后会丢失什么 claim。
- 通过 typed reader 读取 evidence,不把 JSON 字段直接解释成发布结论。
复制的绿色报告仍只是一份复制品
团队把开发机上的 verification-report.json 复制到发布机。文件仍写着 PASS,但它只保留了某人做过的声明;单独看这份文本,无法识别生成它的源码、toolchain、输入和运行。
橙色断点是刻意设计的:receipt 不能和可修改的 artifact 目录一起搬运。若能改写目录的人也能提供一份新计算的 receipt,这条边界就已经消失。
五个文件形成一份密封投影
发布后的 Suite 目录可以包含:
verification-manifest.json:绑定输入、runtime identity、Git 和 run cohort 事实。verification-report.json:payload-free Suite、Case、Requirement、assurance、coverage 和专用结果。verification-summary.md:供人工审阅的投影。- JUnit XML:相同 verdict 的构建系统投影。
evidence-seal.json:所有发布文件的摘要和关系。
VerificationArtifacts 返回 run directory、run ID 和 sealSha256()。把这份 SHA-256 放进独立受控的 CI 记录;后续 reader 必须从目录之外取得它,作为 original receipt。
完整性与来源是两次不同升级
LOCAL_INTEGRITY 表示目录中的文件与 seal 一致。能改写 目录的人仍能创建一份新的内部一致 seal。
SOURCE_BOUND 进一步绑定精确 tracked inputs、干净 Git commit 和 worktree、execution profile、classpath/runtime、bootstrap 和 Operator identity,以及该 evidence version 支持的 run cohort。
ATTESTED 要求外部受控 provenance system 用明确受信 key 和 domain 对精确 source-bound payload 签名。签名不能补齐缺失的 source binding。
业务 status 始终是另一条轴。可信 FAIL 可以是 source-bound;未绑定的 PASS 仍不适合作为团队门禁。
发布一次,从外部复验
运行前配置发布:
ScenarioVerifier verifier = ScenarioVerifier.builder()
.bootstrap(new LoanVerificationBootstrap())
.projectRoot(projectRoot)
.policy(policyPath)
.outputDirectory(projectRoot.resolve("target/bloge-verification"))
.executionProfile(VerificationExecutionProfile.builder("ci-safe").build())
.sourceBoundEvidence()
.build();
VerificationReport report = verifier.verify(scenarioPath);
VerificationArtifacts artifacts = report.artifacts();
String externalReceipt = artifacts.sealSha256();
之后把三个独立输入交给 reader:
VerificationEvidenceTrustResult trust = VerificationSourceBoundEvidence.verify(
artifacts.directory(), projectRoot, externalReceipt);
reader 重算 report、summary、JUnit、manifest、source 和 receipt 之间的关系,不运行 candidate Operator 或客户 bootstrap。Oracle v10/v11 是狭窄例外:reader 可以重跑显式绑定的 reference-model child JVM。
攻击五条边界,观察 trust 如何移动
每一行都从同一份未修改 artifact 开始:business status 为 PASS,receipt 从目录外提供,reader trust 为 SOURCE_BOUND。每次只改变一个变量。
| 单变量攻击 | 独立 reader observation | 最高可辩护 trust | 丢失的关系 |
|---|---|---|---|
| 替换外部 receipt | EVIDENCE_RECEIPT_MISMATCH | UNVERIFIED | 密封字节快照身份 |
| 修改 summary、更新摘要并重封 | DURABLE_EVIDENCE_PROJECTION_MISMATCH | 低于有效本地证据 | 人类投影与机器投影的一致性 |
| 修改 report 语义、重建投影并重封 | DURABLE_EVIDENCE_INVALID | 低于有效本地证据 | verifier 是否可能产生这种状态 |
| 修改 action digest、重建投影并重封 | SOURCE_BINDING_CASE_EVIDENCE_MISMATCH | LOCAL_INTEGRITY | 与 tracked action plan 的关系 |
| 发布后修改 tracked source | SOURCE_BINDING_DRIFT | LOCAL_INTEGRITY | 与当前 source cohort 的关系 |
这些是实际观察到的 RC1 合同,不是假设标签。DurableVerificationEvidenceTest.rejectsAProjectionMutationEvenWhenTheArtifactDigestWasUpdated 证明更新 hash 不能让矛盾 summary 合法;rejectsAContradictoryReportEvenAfterAllFilesAreReprojectedAndResealed 证明完全自洽的伪造仍可能描述 verifier 不可能产生的状态;DurableSourceBoundVerifierTest.rejectsReplacementReceiptBeforeTrustingSourceBoundDocuments 会在信任 source-bound documents 之前先拒绝借来的 receipt。
source-drift 测试还给出一个重要运行观察:artifact 发布后修改 plan,reader 返回 LOCAL_INTEGRITY / SOURCE_BINDING_DRIFT,客户调用计数仍为 1。reader 在没有再次执行客户代码的情况下完成了降级。
为什么重封恢复不了 provenance
artifact owner 本来就能重算 hash,因此新 seal 有时能恢复字节一致性,却恢复不了外置 receipt、原始 run identity 或与 tracked source 的关系。reader 计算当前仍有证据支持的最高等级,不接受目录的自我描述。
移动或复制目录遵循同一原则。文件仍可阅读,但 source-bound 发布要求 bound worktree 内 ignored、non-classpath 的原位置。文件名和 JSON 字段保留下来,不代表副本继承决策权。
reader 返回稳定 diagnostics 并 fail closed。不要用文件名、绿色 status 字段或手工解析的 evidenceTrust 覆盖它的结论。
实验:一次攻击一条边界
- 发布一份 source-bound 贷款 Suite,把
sealSha256()保存在 run directory 之外。 - 用原 project root 和 receipt 复验未修改 artifact,记录
SOURCE_BOUND。 - 按表格完成五次攻击,每次攻击前都恢复未修改 artifact。
- 记录 business status、reader trust、完整 reason codes 和客户调用计数。
- 对重封攻击同时保留 original receipt 与 replacement receipt;分别复验并解释它们回答的问题为何不同。
- 把目录复制到原 worktree 之外,确认可阅读文件不会继承 source-bound authority。
- 最后填写一张卡:
status、trust、receipt custodian、project commit、第一条失败关系和 rerun policy。
现实迁移:薪资证据保管
从另一个 worktree 复制来的薪资报告仍可能是合法 JSON,并显示每位员工计算都为
PASS,但它不能继承原运行的 authority。绑定薪资规则、员工输入摘要、runtime
inventory、commit 和外置 receipt;再逐次移动或重封一个组件,记录第一条失效的
trust 关系。
本章边界
- Seal 证明当前字节间的关系,不识别生成者身份。
SOURCE_BOUND不证明外部账号身份、host 隔离、生产拓扑或 Policy 审批真实性。- 复制 report 便于阅读,但不能继承其 source-bound 决策能力。
- 使用匹配的 reader 和 schema catalog;不要从类名或 JSON shape 猜 evidence version。
实验验收卡
- 预期与观察: 五个文件形成 source-bound evidence,完整性与来源独立升级。
- 失败与恢复: 替换 receipt、修改 source 或重封 identity;恢复原链或重新执行。
- 证明边界: 证明固定 reader 可验证证据链,不证明客户代码从未被篡改。
- 练习合同: 一份密封投影;每次攻击一个文件;交付 trust/reason;五种攻击均可归因即停止。
小结
artifact 文件让结果可检查,外部 receipt 让改写可检测,reader 再把两者接回当前源码事实。下一章先判断一条可信 Case 事实能否贡献给一条精确 Requirement;Project 与 Reactor 聚合留到第 31 章。
下一章:第 30 章——从 Case 事实到精确 Requirement Contribution
Coding Agent: Open the versioned task guide.