首页
/ oh-my-claudecode Epic 3698 关闭收据体系:面向 Agent 与 CI 的机器可读验证证据设计

oh-my-claudecode Epic 3698 关闭收据体系:面向 Agent 与 CI 的机器可读验证证据设计

2026-09-08 23:16:35作者:鲍丁臣Ursa

本文以 oh-my-claudecode 仓库中 receipts/epic-3698/README.md 为骨架,讲解该仓库如何用一个 "epic 关闭收据(closure receipts)" 目录,把一次跨 10 个子 issue 的大规模重构(Epic #3698)的迁移、CI 验证、发布安装验证和剩余风险显性化为可校验的 JSON 证据。读者读完可以掌握这套 schema 化收据的统一格式、六类 kind 各自的载荷契约与判定阈值、verifier/collector 脚本的使用方式与三态判定语义,以及如何在同类多 issue 工程中复用这套"诚实证据、绝不虚假关闭"的关闭机制。

1. 背景:收据目录为谁服务

receipts/epic-3698/ 是一个为 issue #3712("Release and installation verification and epic closure",发布与安装验证与史诗关闭)而维护的机器可读证据目录。它服务于 Epic #3698 的收尾验收面,并被两个脚本消费:

完整的行为契约定义在 docs/design/ISSUE-3712-RELEASE-VERIFICATION.md,规划契约是 docs/design/ISSUE-3698-LIGHTWEIGHT-WORKFLOW-PLAN.md。这条验证通道有一个硬性非目标(Non-goal):它不执行、也不授权任何 release/tag/publish/main 变更——所有脚本对 GitHub 与 npm 都是只读的,证据只能用来"证明可以关闭",永远不能成为发布后门。这一点在验证器中以 releaseSecurityParity 检查强制落地(见第 5 节)。

从设计哲学上看,这套机制解决的是多子 issue 重构收尾时的经典矛盾:机制可以先行落地,但关闭必须等待真实的时间/版本条件成熟。因此它把"可执行机制"与"时间性前提(temporal prerequisite)"分离——机制现在就可用,而是否关闭由证据说话。

2. 收据统一格式(Receipt format)

目录中每个 *.receipt.json 文件都必须遵循统一的外壳结构:

{
  "schemaVersion": 1,
  "kind": "metrics-snapshot | alias-usage | ci-evidence | child-terminal | remaining-risk | install-verification",
  "issue": 3712,
  "createdAt": "<ISO-8601>",
  "payload": { }
}

各字段含义与校验要点(对照 scripts/verify-epic-3698-closure.mjsvalidateReceipt 的实现,位于该文件约 L1396-L1504):

  • schemaVersion:必须为整数 1;任何未来的格式演进都要升版本而不是破坏既有文件。
  • kind:必须是六种枚举值之一(RECEIPT_KINDS 集合在验证器 L1394 处定义),其余字符串一律判为 schema 错误。
  • issue:正整数,即本收据归属的 issue 编号。
  • createdAt:非空 ISO-8601 时间字符串。
  • payload:必须是对象;具体内容按 kind 逐类强校验(见下节)。

这一外壳的意义在于:收据是可被程序自动读入、自动判定的"契约",而不是给人看的一段叙述。仓库提交了 remaining-risk.json 这类带 schema 的 JSON 也说明——哪怕是"剩余风险"这种偏定性的内容,也要被强制结构化。

3. 六类 kind 的载荷契约与判定阈值

这是目录 README 的核心章节:每一类 kind 都有验证器强制执行的载荷约束。仓库中实际落盘的收据文件都可以在 receipts/epic-3698/ 下逐个对照。

3.1 alias-usage:别名退役政策的输入证据

载荷必须包含:

  • canonicalShare:数值,落在 [0,1] 区间;
  • minorReleases:非负整数;
  • daysSinceDeprecation:非负整数;
  • consecutiveReleasesAtThreshold:非负整数;
  • knownCriticalIntegrations:非负整数。

只有同时满足以下全部条件才被认为满足退役政策(在验证器 scripts/verify-epic-3698-closure.mjsEPIC_CONTRACT.retirementPolicy,约 L93-L99):

minorReleases >= 2
AND daysSinceDeprecation >= 90
AND canonicalShare >= 0.95
AND consecutiveReleasesAtThreshold >= 2
AND knownCriticalIntegrations == 0

值得注意的工程点:只要窗口未满足,验证器只会判 pending,永远不会判 fail——因为"窗口未到"不是机制缺陷,而是时间性条件;别名在窗口满足前禁止移除。数据来源方面,README 指明:#3706 的别名解析器会落地 .omc/state/<project>/state/alias-receipts.json,其内包含 totals.aliasUsesbyCanonical 计数,canonical share 即:

canonicalShare = canonicalUses / (canonicalUses + aliasUses)

release-window 各字段则由 #3711 的收据在版本发布后供给。安装验证收据中还记录了别名解析器的一个真实 smoke:resolveWorkflowInputWithWarning('autopilot','s1') 第一次会告警、第二次抑制,alias-telemetry.jsonl 保留两次事件,并成功落出 alias-receipts.json(见 receipts/epic-3698/install-verification-2026-08-12.receipt.json)。

3.2 ci-evidence:exact-head CI 证据

载荷中核心是 pullRequests[],每个元素携带 numberheadShachecks[];每个 check 通过 sha 绑定精确 head(必须等于 PR 的 headSha),并记录 GitHub 已完成结论(success|skipped|neutral|failure|cancelled|timed_out|action_required|stale|startup_failure 等)。判定要点:

  • exactHeadCi 通过的前提是每个 check 在 exact head 上都是绿色结论(success|skipped|neutral,见验证器 GREEN_CHECK_CONCLUSIONS,L209);
  • 记录下来的非绿色结论是"认证过的真相":它会让该门保持失败,绝不因 PR 已合并或后续有修复而被改写/排除为绿色。

仓库中的实例 receipts/epic-3698/ci-evidence-merged.receipt.json 精确展示了这一诚实性原则:收集器 note 明确说明 PR #3724(对应 #3704)与 #3725(对应 #3707)被排除,因为它们在 exact head 上存在 CI / Test FAILURE(inventory-graph-drift),该漂移是在合并后由 #3711 的收尾 inventory 刷新才解决的。

该文件还展示了一个 exact-head 证据记录的完整形态:每个 check 都带 nameconclusion: "success"sha(40 位十六进制小写 commit SHA),且 sha 与所在 PR 的 headSha 严格相等,如 #3721 的 d780c9d9…、#3729 的 433c13ad…

3.3 child-terminal:子 issue 终结性证据

载荷必须包含 state(取 merged|closed)与结构化 evidence。evidence 内应包含:

  • pullRequest:除直连子 issue #3709 之外,都应有预期 PR(号码、headSha 必须为 40 位小写 hex SHA);
  • commit:携带 sha
  • exact-head status

关键语义:一个非绿色的终结 PR 是可表示的——它能证明"该子 issue 确实终结了",但永远不能用来证明"CI 是绿的"(那是 ci-evidence 的职责)。终结性与绿色 CI 是两条正交的证据线。

对 #3709 特殊规则(对照验证器 L83-L85 注释):它没有专属 PR,是通过协作性工作直接关闭的,因此其终结收据必须携带直接的 commit/status 证据;一个无关的 PR(例如关闭 #3726 的 #3727)不能作为替代。仓库实例 receipts/epic-3698/child-3709-terminal.receipt.json 就是这种形态:state: "closed",evidence 中是 issue.number: 3709 / state: "CLOSED"commit.sha: 02acde93…status.state: "pending"

而带 PR 的子 issue 形态见 receipts/epic-3698/child-3702-terminal.receipt.jsonstate: "merged"pullRequest.number: 3721headSha: d780c9d9…,commit SHA 与 head SHA 分开记录(merge commit 为 a70cf7a3…)。

3.4 metrics-snapshot:可复现的表面度量

README 描述其含"public/internal counts plus measurementSha256"。仓库实例 receipts/epic-3698/metrics-2026-08-12.receipt.json 展示了全貌:在 origin/dev 精确 head 570028b24ede… 测得 skills: 41commands: 28hookFiles: 294workflows: 8agentDefinitions: 18promptLikeFiles: 40,并携带 measurementSha256(由文件清单经 SHA-256 计算)与 inventory 图谱校验结论。度量逻辑在验证器 measureSurface(L175-L193):递归遍历仓库(跳过 node_modules/.git/dist/coverage),按 skills/<name>/SKILL.mdcommands/<name>.md.github/workflows/ 等路径模式统计公开表面,并计算 measurementSha256 保证可复算、可防篡改。

3.5 install-verification:pack/install/smoke 证据

README 概括为 "scoped command/verdict/evidence rows for pack/install/smoke"。实例文件给出了完整的"命令/判定/证据"矩阵,全部针对精确 head 570028b24ede… 在隔离克隆与 scratch HOME 中执行:

命令/动作 判定 证据
npm ci --ignore-scripts passed 干净依赖安装
npm run build passed tsc + 全部 build:* 完成
npm pack passed oh-my-claude-sisyphus-4.15.10.tgz,5169 文件,shasum 记录
全局安装 tarball 到 scratch prefix passed 145 packages,无安装脚本失败
omc --version(scratch HOME) passed 打印 4.15.10,与 package.json 一致
omc doctor conflicts passed exit 0,"No conflicts detected / OMC is properly configured"
inventory 图谱 verify passed public/internal/generated/prompt 计数
别名解析器 smoke passed 首次告警、二次抑制,遥测与迁移收据落盘

文件 note 再次强调:没有执行或尝试任何 release/tag/publish/main 变更,npm pack 产物只安装到 scratch prefix,未发布。

3.6 remaining-risk:显式剩余风险登记册

这是六类中唯一的特例:登记册文件名为 receipts/epic-3698/remaining-risk.json(不是 *.receipt.json),并要求非空risks[] 数组,每个风险条目需含 id/description/severity/mitigation/status 五个非空字符串,其中 severity 枚举 low|medium|high|criticalstatus 枚举 open|monitored|mitigated|accepted(验证器 checkRemainingRisk,L1855-L1888)。实例登记了六条风险 R1-R6,例如:

  • R4-metrics-not-at-target(medium/open):dev 表面度量不达标(commands=28 超过 12-18 目标、workflows=8 超过 5-6 目标),10 个子 issue 都只交付了 registry/SSOT/dispatcher/verifier 而没删表面文件——验证器如实报 FAIL,这是诚实证据而非机制缺陷;
  • R6-release-authority-boundary(critical/mitigated):本验证通道绝不能成为发布后门;
  • R5-receipt-provenance(medium/mitigated):收据是可被仓库提交的 JSON,存在伪造风险,靠 fail-closed 校验、gh 可重采集与 measurementSha256 缓解。

4. verifier 与 collector:两个可执行脚本

4.1 关闭验证器

用法(来自 docs/design/ISSUE-3712-RELEASE-VERIFICATION.md):

node scripts/verify-epic-3698-closure.mjs [--evidence ci.json] [--base origin/dev] [--json-out path]

验证器实际支持的参数更多(源码 parseArgs,L130-L161):--root--receipts-dir--changed-files--emit-metrics-receipt(把当前表面度量直接写为 metrics-snapshot 收据)、--docs(追加待扫描的关闭文档路径)。

4.2 只读 CI 证据收集器

用法(scripts/collect-epic-3698-ci-evidence.mjs L9-L11):

node scripts/collect-epic-3698-ci-evidence.mjs --prs 3715,3716,3719,3720,3721,3723,3724,3725,3729 --out <path>
node scripts/collect-epic-3698-ci-evidence.mjs --all-children --out <path>

其实现通过 gh api精确 PR head SHA 上查询 check-runs,每个 check 的 sha 由 gh 返回的 head OID 认证;验证器随后重新查询 GitHub,凡是记录的 SHA 或结论与 live PR head 不一致的 check 都会被拒绝。同时验证器在 verifyLiveGitHubEvidence(L352-L603)中还会校验:live PR 必须为已 MERGED、headSha/mergeCommitSha 必须与 live 一致、child issue 必须为 live CLOSED、证据中的 check 集合必须与 live check 集合完全一致(不允许增删、不允许重复)。

5. 八项检查与三态判定语义

文档中 verifier 的检查矩阵完整如下(对应源码 runVerification 中的 checks 数组,L1918-L1927):

Check Pass Pending(时间性) Fail
exactHeadCi 每个记录的 PR 在 exact head 全绿 尚未提供证据文件 stale-head、认证的非绿结论、畸形证据
docsLinks 关闭文档内所有相对链接均可解析 尚无关闭文档 断链 / 缺失自有文档
shippedMetrics epic 目标达成 目标未达且其归属子 issue 未终结 目标未达但所有归属子 issue 已终结
migrationReceipts ≥1 个 schema 合法收据 目录缺失或为空 schema 非法收据
aliasRetirementPolicy 全部 alias-usage 收据满足退役窗口 无收据或窗口未满足 (永不 fail:窗口未满足是阻止删除而非判决失败)
releaseSecurityParity 变更集不触碰发布/发布权限 触碰 release workflow/脚本、.npmrcpackage.json 版本
childTerminality 子 issue #3702-#3711 全部有认证终结收据 任一子 issue 缺终结证据 伪造或畸形终结证据
remainingRisk 登记册存在、schema 合法、非空 缺失 / 非法 / 为空

退出码语义(源码 L1931-L1939):

  • 0 = PASS,全部检查通过;
  • 2 = PENDING_TEMPORAL,无任何失败但存在未满足的时间性前提——epic 必须保持开放
  • 1 = FAIL,机制或证据缺陷。

这一三态设计是整套机制的灵魂:pending 是"诚实的未关闭证据",永远不是静默通过。与 README 中记录一致的当前真实判定是:verdict 为 PENDING/FAIL 而非 PASS——因为 (a) 别名退役窗口未满足(≥2 个 minor release 且 ≥90 天等,而自弃用以来没有符合条件的版本发布,删除被禁止);(b) 量化指标不达标(commands=28、workflows=8,而目标是 12-18 与 5-6);(c) 即使 #3711 已交付可执行验证器(src/alias-retirement/),#3704/#3707/#3710 合并时 exact-head 上存在非绿 Test,这些失败以显式 exactHeadCi 失败的形式保留,绝不改写为绿色终结证据。

契约中的硬编码配置集中在 EPIC_CONTRACT(验证器 L63-L108),包括:子 issue 与预期 PR 的固定映射(3702→3721、3703→3720、3704→3724、3705→3716、3706→3715、3707→3725、3708→3729、3709→null、3710→3719、3711→3723)、gate 子 issue 集合 [3705,3708,3709,3710,3711]、Tier-0 workflow/role 名单(plan/execute/review/verify 与 planner/executor/reviewer/verifier),以及禁止触碰的发布权威路径正则:

^\.github\/workflows\/release
^\.github\/workflows\/.*publish
^scripts\/release
^scripts\/sync-version
^\.npmrc$

发布安全校验还有一层精细处理:即便变更集是 .github/workflows/release.yml,只要 diff 恰好等于"被允许的 release smoke 行集合"(ALLOWED_RELEASE_SMOKE_DIFF_LINES,L116-L122,即只改 smoke 阶段检查的 skill 名),仍然放行——只读 smoke 调整不算发布权限变更;而 package.json 的 version 变化会被精确 diff 检查并判为发布变更(L1713-L1739)。

指标检查背后的延迟语义值得单独说明(METRICS 数组与 checkShippedMetrics,L1338-L1392):每个量化目标都声明其"归属子 issue"(owner)。目标未达成时,若 owner 尚未终结则判 pending(仍有可能达成),若 owner 已全部终结仍未达成则判 fail(说明表面削减确实没做成)。四个指标为:Tier-0 workflow 技能齐备(plan/execute/review/verify)、Tier-0 role 智能体齐备、命令入口收敛到 12-18、GitHub workflow 收敛到最小可证集(目标 5、可接受 5-6)。

6. 当前收据清单解读

目录 README 的 "Current receipts" 一节对应 receipts/epic-3698/ 下的实际文件:

  • ci-evidence-merged.receipt.json —— 历史 exact-head 证据;新采集覆盖每个预期子 PR:#3715、#3716、#3719、#3720、#3721、#3723、#3724、#3725、#3729;#3719/#3724/#3725 的不可变非绿结果作为真相保留,从不被排除或提升为绿色证据(注意:仓库内已合并的 ci-evidence-merged.receipt.json 在 note 中说明 #3724/#3725 因 exact-head 非绿而排除,二者表述角度不同但原则一致——非绿结论要么保留为失败、要么显式排除并声明原因,绝不伪装为通过);
  • metrics-2026-08-12.receipt.json —— origin/dev 570028b24ede 处的表面计数;
  • install-verification-2026-08-12.receipt.json —— 同一 head 的 pack/install/smoke 证据;
  • child-3702 ~ child-3711-terminal.receipt.json(共 10 个)—— 10 个子 issue 全部终结;
  • remaining-risk.json —— 显式剩余风险登记册。

这套文件的读取顺序即验收思路:先看终结性(10/10 子 issue),再看 CI 是否在 exact head 上真实为绿,再看安装链路在精确 commit 上是否可复现,最后看还有什么风险被显式承认——全部可机读、可重新采集、可复核。

7. 测试、可复现性与复用启示

验证逻辑本身被大型集成测试覆盖:tests/integration/epic-3698-closure-verifier.test.ts(2042 行)。该测试会以真实仓库为 cwd 调用验证器与收集器脚本,并且支持注入 fake-gh/gh 可执行文件与 gh-fixture.json 来模拟 GitHub API,在断言中关注 verdict/exitCode/checks[].status/checks[].problems 等可机读输出字段(见测试 L22-L60 的 runVerifier 基建)。这意味着验证机制本身具备离线、确定性回归测试能力——CI 行为变化可以被夹具精确复现。

结合源码可以提炼出这套设计的四点可复用经验:

  1. 证据与结论分离:收据只负责"如实记录发生了什么"(哪怕是失败),结论由 verifier 依据策略阈值单独推导,杜绝了"为了让 epic 关闭而美化历史"的动机;
  2. exact-head 绑定:所有 CI/commit/status 证据必须绑定 40 位 SHA 并在验证时回查 live GitHub,防伪造、防陈旧;
  3. 时间性条件显式化PENDING_TEMPORAL 是一个一等公民状态,把"算法已就绪但外部条件未到"与"机制缺陷"清楚区分,避免用一个二元 PASS/FAIL 掩盖两者;
  4. 发布权限硬隔离:用正则模式 + package.json 版本 diff 双重把关,让"验证通道"永远不可能退化成"发布通道"。

如果你在维护一个同样拆分为多子 issue 的大规模重构并希望"诚实收尾",可以直接复用该目录的收据形态与两个脚本的 CLI 约定:定义子 issue→PR 映射、为每类证据定义 kind 与 schema、实现一个 fail-closed 且输出机器可读 verdict 的验证器,然后把剩余的不可控因素放进非空的 remaining-risk.json 持续跟踪。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525