Skip to main content

BLOGE 0.9.8-RC1 在线版 · 事实校验 2026-09-15 · English

第 29 章 —— 从报告到 Source-bound Evidence

本章承诺: 区分业务结果和密封目录,把 receipt 保存在目录之外,并用独立 reader 判断 evidence 只是字节完整、已经绑定源码,还是得到外部 attestation。

学习目标

  1. 解释 report、manifest、seal、receipt 和 reader 各自的职责。
  2. 区分 LOCAL_INTEGRITYSOURCE_BOUNDATTESTED
  3. 判断字节、目录位置、Git commit 或 runtime cohort 改变后会丢失什么 claim。
  4. 通过 typed reader 读取 evidence,不把 JSON 字段直接解释成发布结论。

复制的绿色报告仍只是一份复制品

团队把开发机上的 verification-report.json 复制到发布机。文件仍写着 PASS,但它只保留了某人做过的声明;单独看这份文本,无法识别生成它的源码、toolchain、输入和运行。

图 29:Source-bound evidence 把 artifact 与 receipt 放在信任边界两侧

橙色断点是刻意设计的: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。每次只改变一个变量。

图 29.2:五次单变量攻击分别破坏不同 evidence 关系

单变量攻击独立 reader observation最高可辩护 trust丢失的关系
替换外部 receiptEVIDENCE_RECEIPT_MISMATCHUNVERIFIED密封字节快照身份
修改 summary、更新摘要并重封DURABLE_EVIDENCE_PROJECTION_MISMATCH低于有效本地证据人类投影与机器投影的一致性
修改 report 语义、重建投影并重封DURABLE_EVIDENCE_INVALID低于有效本地证据verifier 是否可能产生这种状态
修改 action digest、重建投影并重封SOURCE_BINDING_CASE_EVIDENCE_MISMATCHLOCAL_INTEGRITY与 tracked action plan 的关系
发布后修改 tracked sourceSOURCE_BINDING_DRIFTLOCAL_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 覆盖它的结论。

实验:一次攻击一条边界

  1. 发布一份 source-bound 贷款 Suite,把 sealSha256() 保存在 run directory 之外。
  2. 用原 project root 和 receipt 复验未修改 artifact,记录 SOURCE_BOUND
  3. 按表格完成五次攻击,每次攻击前都恢复未修改 artifact。
  4. 记录 business status、reader trust、完整 reason codes 和客户调用计数。
  5. 对重封攻击同时保留 original receipt 与 replacement receipt;分别复验并解释它们回答的问题为何不同。
  6. 把目录复制到原 worktree 之外,确认可阅读文件不会继承 source-bound authority。
  7. 最后填写一张卡:statustrust、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.