Warp 发布审计报告模板详解:report-template.md 的结构、占位符契约与渲染规则
【免费下载链接】warpA Python framework for GPU-accelerated simulation, robotics, and machine learning.项目地址: https://gitcode.com/GitHub_Trending/warp/warp
Warp(NVIDIA 的 GPU 加速仿真、机器人与机器学习 Python 框架)在每次正式发版前后,会用warp-release-audit这个 Claude Code Skill 生成一份 Markdown 审计报告,供发布负责人做 keep/defer 决策。本文以 report-template.md 为主体,逐节拆解这份报告的骨架:头部元信息、bake 分布、New API / Breaking / Changes / Fixed 各章节的占位符契约,以及条件附录的三种渲染形态,并结合 SKILL.md、render-rules.md 与配套脚本说明每个区块的数据从何而来、按什么规则填进模板。
一、模板在发布审计流程中的定位
warp-release-audit技能的工作流程定义在 SKILL.md 中,共 6 个阶段,报告模板在Phase 6b被加载:
- Phase 1 对齐范围:从 VERSION.md 读取版本串(当前为
1.18.0.dev3),并与 warp/config.py 中声明的版本做交叉校验;解析出上一 minor 的 tag 作为 base,探测upstream/release-<target>是否存在以确定 head 与报告模式(版本串含rc为Release Candidate模式,含dev为Pre-Release模式)。 - Phase 2 采集事实:运行 scripts/list_commits.py 生成
<base>..<head>的提交清单 JSON;从<head-ref>(而非工作区)枚举 changelog/ 下的 Towncrier 片段,并用固定版本towncrier==25.8.0在临时 detached worktree 里渲染--draft,得到"待定发布条目"视图;同时读取 docs/user_guide/compatibility.rst 与 design/deprecations.md 作为稳定性边界与弃用计划的权威来源。 - Phase 3 交叉引用:把渲染出的 changelog 条目与提交按 GH ref / 片段来源做 join,无提交背书的片段进入附录。
- Phase 4 API 面分析:判定哪些
Added条目是"真正新增的 API"、提取签名与 docstring、计算 base 与 HEAD 的签名 diff、检查弃用兼容路径与语义级破坏。 - Phase 5 语言审查与 bake 聚合:按 language-review-examples.md 给条目打标记,并按提交在 main 上的"浸泡时间"聚合 bake 分布。
- Phase 6 写报告:6a 撰写定性 highlights,6b 读取模板与 render-rules.md 填充所有
{{PLACEHOLDER}},6c 按 destination-rules.md 写入 secret gist(默认,文件名固定为warp-<version-string>-<prerelease|rc>-report.md,同版本多次运行原地修订同一 gist)或本地 markdown 文件(回退方案)。
模板文件本身只做两件事:定义报告的章节骨架,以及用 HTML 注释给出每个占位符的填充契约。模板内所有{{...}}都必须被替换,不允许原样残留。
二、报告头部:版本、模式、引用与头部计数
模板的前 20 行(report-template.md)构成报告头部:
# Warp {{VERSION_STRING}} {{REPORT_KIND}} Report Generated: {{REPORT_DATE}} - Mode: {{MODE_DESCRIPTION}} - Head: {{HEAD_REF}} @ `{{HEAD_SHA_SHORT}}` - Base: {{BASE_REF}} @ `{{BASE_SHA_SHORT}}` - Commits in range: {{N_COMMITS}}各占位符的填充契约如下:
| 占位符 | 含义 | 填充规则 |
|---|---|---|
{{VERSION_STRING}} | 原始版本串 | 原样保留,如1.13.0dev0或1.13.0rc1 |
{{REPORT_KIND}} | 报告类型 | Pre-Release或Release Candidate,在 Phase 1 由版本串与 head ref 共同确定 |
{{MODE_DESCRIPTION}} | 一句话模式说明 | 预发布固定为 "Pre-release audit of unreleased work on main";RC 固定为 "Release candidate readiness review (release branch cut)" |
{{HEAD_REF}}/{{HEAD_SHA_SHORT}} | 审计上界 | head 通常为upstream/release-<target>(RC 模式)或upstream/main(预发布模式),需记录使用了哪个 fallback |
{{BASE_REF}}/{{BASE_SHA_SHORT}} | 审计下界 | 上一 minor 系列的最高 tag(major 边界回退到上一 major 的最高 tag) |
{{N_COMMITS}} | 区间提交数 | 来自list_commits.py的commits数组长度 |
紧接着是Headline counts区块(模板 L23-L29):
- {{N_NEW_API}} new public APIs (Python: {{N_NEW_PY}}, kernel: {{N_NEW_KERNEL}}) - {{N_BREAKING}} breaking changes - {{N_CHANGED}} changes to existing API - {{N_BEHAVIORAL}} behavioral / support changes - {{N_FIXED}} fixes这里承载报告的定量摘要。与之配套的定性摘要是后文的 Release highlights,二者分工明确:计数块放数字,highlights 放判断。模板注释特别强调 highlights 中不得重复计数("Do NOT include counts"),因为读者刚在头部看到过。
三、Bake 分布表与 main 烘焙异常横幅
模板 L31-L37 是 bake 分布表,衡量"提交在 main 分支上跑了多久才进入本次发布":
| Bucket | Commits | |---|---:| | 🟢 > 14 days in main | {{N_BAKE_GREEN}} | | 🟡 7 to 14 days | {{N_BAKE_YELLOW}} | | 🟠 < 7 days | {{N_BAKE_ORANGE}} |阈值(>14 / 7-14 / <7 天)是固定的三档,对应"已充分浸泡 / 中等 / 风险偏高"。
{{ANOMALY_BANNER_IF_ANY}}(L39)的触发契约是整个模板中条件最精细的部分,模板内注释(L41-L60)规定:
- 横幅只在至少一个提交满足
main_match_state == "missing"时触发(提交主题在main_ref上不存在),格式为:> ⚠️ **N commits in the release have no equivalent on main. Investigate: these shipped without nightly/main-branch bake.**这些提交绕过了 main 分支的 nightly 验证,是真正的 bake 缺口信号。 ambiguous(主题在 main 上出现多次,如 revert 或重放提交)不算缺口:提交确实在 main 上,只是脚本无法选出唯一规范出现位置。它们以独立行⚪ ambiguous main match: K commits出现在 bake 表中,不触发横幅。- 预发布模式下(head 即 main)横幅永不触发,bake 表被替换为基于
days_since_merge的 "Age distribution" 表——head 就是 main 时不存在"没在 main 上跑"的概念。 - 若
resolved.empty_main_index == true(<base>..<main_ref>区间内 main 无提交),则用醒目的头部说明(如 "main_ref had no commits in<base>..<main_ref>; main bake unverifiable")替代常规横幅,避免误报。
底层支撑来自 list_commits.py:脚本为每个提交输出main_match_state(unique/missing/ambiguous)与days_in_main、days_since_merge字段(见 build_commit_entry)。missing与ambiguous两种状态下days_in_main均为null,模板契约因此禁止拿null去比三档数值阈值;脚本对main_ref区间为空的情形也会主动告警(main 函数内的empty_main_index分支)。
四、Release highlights 与目录(TOC)
Release highlights(模板 L63-L67,{{HEADLINE_SUMMARY}})是整份报告中唯一依赖定性判断、而非机械渲染的区块。模板注释(L69-L93)给出了严格写作契约:
- 2-3 句引言段 +4-8 条要点;少于 4 条通常意味着漏了主题,多于 8 条说明在罗列变更而非提炼亮点;
- 每条以加粗的 2-6 词标题开头,冒号后接一句话说明"它是什么、为什么重要";
- 适用时内联风险标记:
🟠 N days bake(该亮点最小浸泡不足 7 天)、Experimental(仅当实验能力本身值得进头条时)、⚠️ Breaking(亮点本身是破坏性变更); - 通用条目形状为
- **<capability headline>** (GH-NNN): <用户现在能做什么、为何重要>,破坏性条目写作- **⚠️ Breaking: <behavior headline>** (GH-NNN): <受影响用户与具体迁移>。
SKILL.md 的 Phase 6a 还补充了取舍规则:纯一行可述的 bugfix、纯 CI/构建变更、已隔离的内部重构、用户无感的参数默认值调整,一律不进 highlights;每条要点"以解锁的能力开头,而不是机制",且所有 GH ref 必须渲染为 issue 超链接、禁止(multiple GHs)之类缩写。
Contents(模板 L96-L128,{{CONTENTS_BULLETS}})要求把正文每个###级标题(不仅是##)都展开为目录子项:New API 下按 Python/Kernel 两个 scope 再列出每个符号,Breaking / Changes 按条目标题列子项。模板给出示例形状并注明"示例符号名只是占位示意,不得照抄交付"。模板注释还解释:GitHub 会渲染浮动大纲面板,但显式 TOC 对纯文本读者仍有价值。
五、New API:Python 与 Kernel 双 scope 的表格和符号级明细
模板 L132-L173 定义 New API 章节,结构为"汇总表格 + 逐符号明细块":
- 汇总表格按 Kind 分组(
{{NEW_PYTHON_TABLES_BY_KIND}},L136)。每个 Kind 一张表(如 "Functions"、"Classes / context managers"、"Scalar types"、"Decorators"、"Enums / flags"),列固定为Symbol | Description | GH | Bake。Symbol 单元格使用短形调用形状:带参数名与默认值、但不带类型标注;枚举、标量类型、装饰器不加括号。 - 逐符号明细块(
{{NEW_PYTHON_DETAIL_BLOCKS}},L146),契约形状为:
### `wp.<symbol>` Links: GH-NNN, commit(s): sha Source: `<public source path>` Bake: <bucket and days> ```python <signature-shaped declaration> """<verbatim docstring, when present>"""契约细节:类要给出类 docstring、构造函数和**每个**额外公共方法;枚举与 flags 要列全每个成员及其文档;内核内建(kernel builtin)不得展示 `add_builtin(...)` 注册调用,而要从其参数**合成**一个 Python 风格的公开签名(内建名做函数名,`input_types`/`inputs` 各项做带类型标注的参数,`value_type`/`output` 做返回标注),docstring 取注册调用的 `doc=` 参数原文。 3. **Kernel scope**(`{{NEW_KERNEL_TABLES_BY_KIND}}` / `{{NEW_KERNEL_DETAIL_BLOCKS}}`,L168-L173)沿用同一分组规则,典型 Kind 为 "Tile operations"、"Queries"、"Types"、"Primitives"。 这些明细块的数据并非手抄:SKILL.md Phase 4b 规定对 Python 符号用 `ast.parse` 定位 `FunctionDef`/`ClassDef`、重新字符串化参数(保留类型标注)、用 `ast.get_docstring(node)` 原样提取 docstring;内核内建则读 HEAD 上的 [warp/_src/builtins.py](https://link.gitcode.com/i/c335355c814751cf4d9c0cc5e860db63) 找到 `add_builtin("<name>", ...)` 调用后合成签名。符号解析失败时(Phase 4c)渲染带 ⚠️ 说明的条目,禁止编造 `wp.*(no symbol)` 这类桩头。 ## 六、Breaking Changes:扁平列表与准入门槛 模板 L175-L200(`{{BREAKING_ENTRIES}}`)规定该章节是**扁平列表**,不按识别方式设子标题,且只收录"对受支持、可触达表面的惊动性变更"。准入/分流规则(模板注释 L181-L184,与 [classification-rules.md](https://link.gitcode.com/i/0fd3e7ff732c47b27eb321697ecb56d9) 的 Surface/Reachability/Deprecation/Action 记录一一对应): - **满足弃用窗口的计划移除**与**实验性变更**不算惊动性 breaking,归入 Changes to Existing API,使用更温和的标签(`Planned removal` / `Experimental`); - 每条条目的渲染格式:`### <符号名或短描述标题>`(标题用冒号分隔,不用破折号),随后是 `Links: GH-NNN, commit(s): sha. 🟢 N days baked in main.`,视情况附 diff 代码块(签名变化时)或自包含的 before/after 示例(行为变化时,优先取自现有测试或文档,否则用已验证的复现及其输出),再跟 1-3 句面向用户的解释文字,若条目源自 CHANGELOG 则原文引用整段。 SKILL.md Phase 4g 进一步规定:每个 Breaking Changes 条目必须有五类证据之一——CHANGELOG 显式 `**Breaking:**` 标注、签名 diff 检测到的形状变化、公共 stub 移除、弃用兼容路径新增异常(Phase 4f),或**助手实际运行 base 与 HEAD 两版构建并比对输出**的语义级验证。"Never punt with 'please verify'":模棱两可的候选要么跑代码验证、要么丢弃,未验证的标记不得进入报告。 ## 七、Changes to Existing API:汇总表与条目契约 该章节(模板 L202-L238)覆盖 CHANGELOG 的 Changed / Removed / Deprecated 三类条目,外加从 New API 分类阶段分流过来的"能力扩展"(例如"Add support for X in existing Y")。 **汇总表格**(`{{CHANGED_SUMMARY_TABLE}}`)列为:`API | Kind | Breaking | Description | GH | Commits | Bake`。其中 Kind 取值为 `signature change`、`new parameter`、`capability extension`、`removed`、`deprecated`、`semantic change`;Description 是不超过 10 个词的短语;Breaking 取值 `Yes`、`No`、`Planned removal` 或 `Experimental`。 **逐条明细块**(`{{CHANGED_DETAIL_BLOCKS}}`)契约: ```text ### `wp.<symbol>`: <change kind> Breaking: **<Yes | No | Planned removal | Experimental>** (<short reason>) Links: GH-NNN, commit(s): sha Bake: <bucket and days> Deprecation window: <when applicable> ```diff - <base signature when applicable> + <HEAD signature when applicable>From CHANGELOG
要点:标题用冒号而非破折号;签名形状变化用围栏 `diff` 块展示 base 与 HEAD 两行,纯语义变化则跳过 diff 块改为给出提交链接与完整 CHANGELOG 文本;移除类条目只保留 `-` 行、省略 `+` 行;移除条目必须附弃用窗口(在 [CHANGELOG.md](https://link.gitcode.com/i/69c9127b8af9622a43268962d74fc77f) 中自 Towncrier 插入标记向下扫描同名符号或同 GH ref 的最早 `Deprecated` 条目,写成 "Deprecated in X.Y.Z; removed here.",找不到先验条目则**不得编造版本**);实验性条目要注明引入实验标记的发布版本。 ## 八、Behavioral & Support Changes 与 Fixed **Behavioral & Support Changes**(模板 L240-L250,`{{BEHAVIORAL_SECTIONS}}`)不逐条罗列,而是**按主题分组**:由条目内容综合出简短描述性小标题(如 "Anisotropic voxel spacing"、"CPU compile performance"、"Build requirements"),相关主题放在一起,每个主题配一段短摘要、链接、提交与 bake。render-rules 同时规定标题需要分隔时同样用冒号。 **Fixed**(模板 L252-L261,`{{FIXED_TABLE}}`)只有一张表,列为 `Fix | GH | Commits | Bake`。两条硬规则:Fix 列保留 CHANGELOG 全文、**禁止截断**;不得提及已发布补丁版本中修复的 bug——提交清单工具的作用域本来就是 `<base>..<head>`,那些内容已被天然排除,报告不得主动制造对比(这与 [render-rules.md](https://link.gitcode.com/i/134ff9ab8ee5ee9923fdeffc98a62a36#L28-L28) 第 3 条呼应)。 ## 九、条件附录:Changelog Review Notes 的三种渲染形态 模板末尾(L263-L317,`{{OPTIONAL_APPENDIX}}`)是最长的条件渲染契约,依据两个输入——"无匹配提交的 changelog 片段列表"与"语言审查标记列表"——分三种情况: 1. **两者皆空**:什么都不渲染,无附录标题、无尾部章节; 2. **恰好一个非空**:不用 "Audit Appendix" 伞形标题,直接把该节渲染为顶级章节(如 `## Changelog Fragments Without Matching Commits`),表体包在 GFM `<details>` 块里默认折叠; 3. **两者皆非空**:渲染伞形章节 `## Audit Appendix`,每个子节各带一个 `<details>`。 两张表的结构分别是: | 表 | 列 | |---|---| | 无匹配提交的片段 | `Source fragments | Entry | GH refs | Suspected reason` | | 语言审查标记 | `Source fragments | Entry | Flag | Why` | 列规则:源片段路径与完整条目文本一律不截断;语言标记符号为 🔗(疑似 GH ref 错误)、🗣️(内部实现语言泄漏)、📝(过于简短或缺上下文);一条条目命中多个标记时**每个标记一行**。标记的判定标准来自 [language-review-examples.md](https://link.gitcode.com/i/829f0758f8753811e4b6936cc64d067b):🔗 分两级(级一纯本地:核对 GH ref 关联提交的 subject 与文件路径是否与条目主题相符,如条目讲 kernel API 而提交只碰 CI 文件即标记;级二需要 `gh` CLI 已认证时比对 issue 标题),🗣️ 针对 `warp._src.*` 内部路径、C++/CUDA 内部类型(如 `launch_bounds_t`)、下划线私有标识符,📝 针对约 10 词以下且无上下文的条目。其哲学是"提出来但不拦截":标记只为给人工复核提问题,不自动改写任何片段,也不修改生成产物 [CHANGELOG.md](https://link.gitcode.com/i/69c9127b8af9622a43268962d74fc77f);宁可误报不可漏报。 模板最后两行注释(L316-L317)是收尾纪律:"报告到此结束"——禁止追加 "end of report"、收尾引语、致谢或任何终结标记,最后一节就是最后一节。 ## 十、渲染层硬约束(与 render-rules.md 配套生效) Phase 6b 填模板时必须同时遵守 [render-rules.md](https://link.gitcode.com/i/134ff9ab8ee5ee9923fdeffc98a62a36) 的全部规则,这里汇总最影响版面的几条: - **URL 形状固定**:提交链接为完整 commit URL(含完整 SHA),issue 链接为完整 issue URL; - **全文禁止破折号(em dash)**:标题、要点、表格单元格一律改用冒号、括号或改写句子; - **禁止出现技能内部术语**:读者不知道 "Phase 4f"、"tier-1 heuristic" 指什么,需要解释时改用面向用户的白话; - **每个 GH ref 必须是 markdown 超链接**:表格单元、标题、正文、CHANGELOG 引用块中出现的 `GH-NNNN` 一律链接化,一行六个 ref 就渲染六个链接,禁止纯文本 `(GH-1287, GH-1298, ...)`; - **签名与 docstring 合并在同一个 python 围栏代码块中**:函数/类/枚举/内核内建各有固定形状(类要列出全部公共方法,枚举要列出全部成员及整数值,内核内建用合成签名而非注册调用),且禁止拆成 "Signature" 与 "Docstring" 两个小节、禁止逐行引用 docstring; - **API 表格列序与短形签名约定**如第五、七节所述; - **附录伞形标题仅双非空时使用**; - **禁止 Phase 名出现在输出中**。 ## 十一、占位符全景速查 | 占位符 | 所在章节 | 数据来源 | |---|---|---| | `{{VERSION_STRING}}` `{{REPORT_KIND}}` `{{REPORT_DATE}}` `{{MODE_DESCRIPTION}}` `{{HEAD_REF}}` `{{HEAD_SHA_SHORT}}` `{{BASE_REF}}` `{{BASE_SHA_SHORT}}` `{{N_COMMITS}}` | 报告头部 | Phase 1 解析 [VERSION.md](https://link.gitcode.com/i/1664e3497c19693d6046f8553f9b21cc) 与 `warp/config.py`、`git tag`/`rev-parse`;提交数来自 [list_commits.py](https://link.gitcode.com/i/dc091afc2591a7b7d71d5f84c8c4bc73) | | `{{N_NEW_API}}` `{{N_NEW_PY}}` `{{N_NEW_KERNEL}}` `{{N_BREAKING}}` `{{N_CHANGED}}` `{{N_BEHAVIORAL}}` `{{N_FIXED}}` | Headline counts | Phase 4 分类结果 | | `{{N_BAKE_GREEN}}` `{{N_BAKE_YELLOW}}` `{{N_BAKE_ORANGE}}` | Bake distribution | `days_in_main` 三档聚合(`null` 不参与比较) | | `{{ANOMALY_BANNER_IF_ANY}}` | 头部横幅 | 是否存在 `main_match_state == "missing"` 的提交 | | `{{HEADLINE_SUMMARY}}` | Release highlights | Phase 6a 定性撰写 | | `{{CONTENTS_BULLETS}}` | Contents | 正文全部 `##`/`###` 标题 | | `{{NEW_PYTHON_TABLES_BY_KIND}}` `{{NEW_PYTHON_DETAIL_BLOCKS}}` `{{NEW_KERNEL_TABLES_BY_KIND}}` `{{NEW_KERNEL_DETAIL_BLOCKS}}` | New API | Phase 4a/4b 的 base/HEAD 符号解析与签名提取 | | `{{BREAKING_ENTRIES}}` | Breaking Changes | Phase 4d-4g 的五类证据 | | `{{CHANGED_SUMMARY_TABLE}}` `{{CHANGED_DETAIL_BLOCKS}}` | Changes to Existing API | Phase 4a/4d 的签名 diff 与弃用窗口查询 | | `{{BEHAVIORAL_SECTIONS}}` | Behavioral & Support | 主题分组综合 | | `{{FIXED_TABLE}}` | Fixed | CHANGELOG Fixed 条目全文 | | `{{OPTIONAL_APPENDIX}}` | 条件附录 | Phase 3 的无提交片段 + Phase 5a 的语言标记 | ## 十二、配套工具与失败模式 模板渲染只是流水线的末端,其可信度依赖上游工具链: - [list_commits.py](https://link.gitcode.com/i/dc091afc2591a7b7d71d5f84c8c4bc73):确定性、纯标准库,枚举 `<base>..<head>` 提交(跳过 merge),提取 `\bGH-(\d+)` 形态的 issue 引用,通过 subject 精确匹配定位 main 侧等价提交并输出三种 `main_match_state`;对歧义 ref 直接报错退出([rev-parse](https://link.gitcode.com/i/dc091afc2591a7b7d71d5f84c8c4bc73#L179-L193) 把任何 stderr 都视为硬错误),拒绝输出负的 `days_since_merge`。 - [diff_public_api.py](https://link.gitcode.com/i/4a88a047e6ee8c48305e95a644c72610):独立于 CHANGELOG 内容,对比 base 与 HEAD 提交的公共 API(含 `.pyi` 公共 stub 的移除),以 JSON 输出供 Phase 4e 消费;模块选择与"破坏性签名形状信号/通常非破坏信号"的判定细则见 [classification-rules.md](https://link.gitcode.com/i/0fd3e7ff732c47b27eb321697ecb56d9)。 - Towncrier 片段渲染:固定 `towncrier==25.8.0`、`--draft` 模式、临时 worktree 用完即删,与 [changelog/README.md](https://link.gitcode.com/i/813df8f434933052ab80e7a209b57ab4) 中的片段规范(六类后缀 `added`/`removed`/`deprecated`/`changed`/`fixed`/`documentation`、issue 数字或 `+slug` 孤儿标识符、`.1` 计数器)及 [design/towncrier-changelog-fragments.md](https://link.gitcode.com/i/42ed09327840498c0bdd87f99e3e6d41) 的设计文档保持一致。 SKILL.md 末尾的 Failure modes 一节定义了渲染异常时的行为:片段查无提交背书时进附录并注明 "no associated commit found, verify";`Added` 条目符号在 HEAD 无法解析时渲染 ⚠️ 提示而非桩名;`upstream/` 远端缺失时替换为 `origin/` 并在头部注明;head 与 main 无差异时视为 head==main 跳过 cherry-pick 检测;无待定片段时渲染空 draft 并告警,**绝不**拿最近的历史发布段顶替;Towncrier draft 失败则原样输出命令错误并停止,不得用手写近似值冒充发布段落。 综合来看,这份模板的价值在于把"发版前该确认什么"固化成了可机械执行的契约:头部五组计数回答"范围多大",bake 分布与横幅回答"风险有多新鲜",四个正文章节回答"具体变了什么、证据是什么",条件附录回答"changelog 本身还有哪些疑点"。配合固定版本的 Towncrier、确定性的提交清单脚本与签名 diff 工具,报告的可复现性与可审计性完全由仓库状态决定,这也是 Warp 以"fragment 驱动 + 审计模板"管理发版沟通的核心机制。【免费下载链接】warpA Python framework for GPU-accelerated simulation, robotics, and machine learning.项目地址: https://gitcode.com/GitHub_Trending/warp/warp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考