oh-my-claudecode Epic 3698 关闭收据体系:面向 Agent 与 CI 的机器可读验证证据设计
本文以 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 的收尾验收面,并被两个脚本消费:
- scripts/verify-epic-3698-closure.mjs:关闭验证器,默认 fail-closed(验证失败即关闭失败);
- scripts/collect-epic-3698-ci-evidence.mjs:只读的 exact-head CI 证据收集器(基于
gh)。
完整的行为契约定义在 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.mjs 中 validateReceipt 的实现,位于该文件约 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.mjs 的 EPIC_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.aliasUses 与 byCanonical 计数,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[],每个元素携带 number、headSha、checks[];每个 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 都带 name、conclusion: "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.json:state: "merged",pullRequest.number: 3721、headSha: 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: 41、commands: 28、hookFiles: 294、workflows: 8、agentDefinitions: 18、promptLikeFiles: 40,并携带 measurementSha256(由文件清单经 SHA-256 计算)与 inventory 图谱校验结论。度量逻辑在验证器 measureSurface(L175-L193):递归遍历仓库(跳过 node_modules/.git/dist/coverage),按 skills/<name>/SKILL.md、commands/<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|critical,status 枚举 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/脚本、.npmrc、package.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 行为变化可以被夹具精确复现。
结合源码可以提炼出这套设计的四点可复用经验:
- 证据与结论分离:收据只负责"如实记录发生了什么"(哪怕是失败),结论由 verifier 依据策略阈值单独推导,杜绝了"为了让 epic 关闭而美化历史"的动机;
- exact-head 绑定:所有 CI/commit/status 证据必须绑定 40 位 SHA 并在验证时回查 live GitHub,防伪造、防陈旧;
- 时间性条件显式化:
PENDING_TEMPORAL是一个一等公民状态,把"算法已就绪但外部条件未到"与"机制缺陷"清楚区分,避免用一个二元 PASS/FAIL 掩盖两者; - 发布权限硬隔离:用正则模式 + package.json 版本 diff 双重把关,让"验证通道"永远不可能退化成"发布通道"。
如果你在维护一个同样拆分为多子 issue 的大规模重构并希望"诚实收尾",可以直接复用该目录的收据形态与两个脚本的 CLI 约定:定义子 issue→PR 映射、为每类证据定义 kind 与 schema、实现一个 fail-closed 且输出机器可读 verdict 的验证器,然后把剩余的不可控因素放进非空的 remaining-risk.json 持续跟踪。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00