Skip to content

Latest commit

 

History

History
156 lines (121 loc) · 10.9 KB

File metadata and controls

156 lines (121 loc) · 10.9 KB

规划与交付治理

本文定义 backlog、版本计划、技术提案和 CHANGELOG 的权责边界。目标不是增加文档层级,而是让每个 事实只有一个维护位置,并让 CI 阻止编号、范围和状态漂移。

文档权责

文档 唯一负责 不得维护
backlog 碎片 条目编号、标题、动机、目标版本、实施状态、Proposal 指针 版本优先级、实施顺序、验收条件、技术方案正文
backlog 入口 台账阅读入口、编号前缀与维护规则 条目行本身——它们住在 backlog.d/ 碎片里
当前版本计划 版本目标、P0/P1/P2、依赖与实施顺序、版本验收和退出条件 条目实施状态、重复的条目标题、方案裁决正文
Proposal API / wire、状态机、边界、兼容策略、资源预算、验证方案和设计裁决 排期优先级、实施进度、发布结果
design.md 已接受且跨版本长期有效的设计立场 尚未裁决的方案和单版本排期
根 README、guide、全部包与 example README 当前稳定版的安装、入口、能力与限制 已淘汰安装方式、旧版状态和实施过程
skills/*/SKILL.md / INSTALL.md Agent 发现与任务路由、安全边界、Skill 安装及渐进式披露入口 手写复制 live catalog、descriptor、完整命令表或 guide 正文
docs/assets/*.svg 当前架构与首页能力摘要 已删除组件、接入方业务词和旧版命令示例
changelog.d/<version>/ / CHANGELOG.md 已实现的用户可见变化 待办、设计备选和实施过程
releases/proposals/、CHANGELOG、版本化兼容语料 对应版本的计划、裁决与发布证据 当前版安装入口

同一字段不得在两个文档中维护。为了可读性,版本计划可以多次引用 PB 编号,但范围表只写编号和 验收,不复制 backlog 标题;Proposal 的“状态”只表示设计是否被接受,不代表条目实施进度。

对外当前文档与历史证据严格分区:README、guide、包 README、design 和 SVG 只能描述当前稳定事实; 旧版本号、旧安装源和当时状态只留在版本计划、Proposal、CHANGELOG 与版本化兼容语料。正式版必须在 打 tag 前完成当前文档,不能以“发布后再改 README”制造一个文档已过期的 tag。release_prep 对受管 版本锚点执行精确替换,并对旧安装口径、非中性命令示例和架构 SVG 能力执行 fail-closed 检查。

生命周期

发现问题
  -> backlog 建号(待排期)
  -> 版本范围 MR(目标版本 + P0/P1/P2 + 验收)
  -> 必要时 Proposal(提案中)
  -> design-gate 裁决(Proposal 已接受 / 已否决)
  -> 实现 MR(实现中)
  -> 验证完成(已验证)
  -> 发布 MR 聚合到 CHANGELOG
  -> 发布完成后 finalize 删除该条目的 backlog 碎片

范围、方案和实现允许在同一个 MR 中推进的前提是变更仍可独立评审且没有绕过裁决。存在未决 design-gate 时,实现代码不得先行合入。

backlog 碎片

台账是 docs/backlog.d/一条目一个碎片文件,不是一张入库的大表。理由与 changelog.d/ 相同:写入按条目独占,存储也必须按条目独占,否则并行 MR 改各自的状态行却落在同一文件的相邻行, 三方合并稳定撞成 hunk 冲突。

  • 实现 MR 只改自己条目的碎片。 不顺手整理别人的碎片,不把多个条目的状态合进一次编辑。
  • 不要以任何形式重新引入入库的总表(包括「由工具生成、随 MR 提交」的版本):生成物同样会被每个 实现 MR 重写,冲突原样回来。要看全表用 dart run tool/backlog_render.dart 按需现渲,看完即弃。
  • 编号前缀决定种类(PB / BUG / DOC / DG),文件名必须与 frontmatter 的 id 一致。
  • 字段、状态词表、单行小节约束和链接前缀规则以 backlog.d/README.md 为准, 由 check_planning 机检。

什么时候必须写 Proposal

满足任一条件的条目,在进入实现 MR 前必须有 docs/proposals/<version>/ 下的 Proposal:

  • 新增或修改公共 API、wire 字段、命令 descriptor 或稳定 JSON 输出;
  • 引入状态机、异步 job、超时、重试、取消、租约或资源上限;
  • 横跨 patchbaypatchbay_clipatchbay_flutter 或接入方适配层;
  • 改变默认行为、安全边界、脱敏规则、兼容或降级语义;
  • backlog 标记了 design-gate
  • 同一能力需要 VM Service、direct 或两个接入方共同验证。

纯文案、测试补强、明确的生成物修复和不改变外部行为的重构,可以在 MR 中直接写清契约和验收, 无需为了形式新增 Proposal。

Proposal 必须使用模板,并至少冻结:目标/非目标、公共契约、状态与失败语义、 兼容策略、资源预算、测试矩阵、待裁决问题。Proposal 处于“提案中”时只能做原型验证;合入实现前 必须改为“已接受”,并把长期设计结论同步到 design.md

MR 规则

  1. 范围 MR 同时更新条目碎片和对应版本计划;不改变运行时行为,无需 CHANGELOG 碎片。
  2. Proposal MR 写 Plan: PB-... 和关联的 DG-...,不把“默认建议”当成已裁决事实。
  3. 实现 MR 必须引用已接受 Proposal;实现若偏离,先更新 Proposal 并重新评审。
  4. 范围延期先改版本计划,再把条目碎片的 target 清成 ;禁止只改其中一份。
  5. 发布 MR 聚合 CHANGELOG 并定版版本号,不动 backlog 碎片和版本计划状态,也不回写 Proposal 的 实施状态。
  6. 发布收尾由 tool/release_finalize.dart四包实际发布之后执行:删除已完成条目的碎片、 把版本计划标为已发布。它的产物走一个小 MR 合回 mainmain 受保护,不接受直接推送)。 顺序不能颠倒——finalize 会写下「已发布」,在包还没上 pub.dev 时执行等于替未发生的事实背书; 而四包是按依赖顺序逐个推、可能中途被拒的,先删碎片再发布会留下台账已清空、版本却没发出去 且无处回滚的悬空状态。

交付单元与 MR 颗粒度

MR 的边界按“能否独立评审、验收和回退”决定,不按 PB 数量或文件数量机械切分。以下情况应放进同一个 MR:共同改变一项公共契约、重写同一热点调用链、必须联合验收,或拆开后任一部分不能形成可用结果。 以下情况才适合拆分:依赖方向单一,验收可以独立判定,任一 MR 回退都不会让另一项语义失真。

  • 堆叠 MR 默认不超过三层;共同底座先合入,再让上层 rebase。
  • 三个及以上并行分支会修改同一热点时,改为共同交付分支或串行推进,不能继续扩大兄弟分支数量。
  • 集成候选只用于固定输入 SHA 后的联合验收,不作为功能 MR。候选里发现的语义冲突回到来源 MR 修复。
  • 单个 PB 可以跨多个 MR,但每个 MR 都要给出自己的结果、验收和回退边界;多个 PB 也可在边界不可拆时 合成一个 MR,并在描述中解释原因。

MR 模板必须声明目标分支、依赖链和交付单元类型。评审时先判断边界是否成立,再看代码规模;行数只是 风险信号,不是拆分指标。

分支与版本稳定化

main 只接定版合并:它的每个提交都对应一个已发布版本或 hotfix,因此始终可构建、可测试、可发布, git log main 就是发布史。版本开发使用临时 dev/<SemVer> 分支:

  1. 从稳定 main 创建 dev/<SemVer>,该版本的功能 MR 默认以它为目标;
  2. 堆叠 MR 在父 MR 合入前以父分支为目标,合入后及时 rebase 到版本分支;
  3. 冻结用状态表达而不是再切一条分支:把版本计划的 > 状态: 推进到 RC 即冻结范围,此后只接发布 阻断修复,并在版本分支完成 CI、兼容和接入方真机验收;
  4. 通过退出条件后,用一个发布 MR 把版本分支合回 main,再同步 GitHub、打 tag 和发布。版本号 bump 与 CHANGELOG 聚合属于这个发布 MR,不散落在功能分支里;
  5. 发布完成后回收版本分支。只有明确承担维护线时才长期保留。

分支叫 dev/ 而不是 release/:它从版本周期第一天就在接功能 MR,一生中绝大部分时间并不处于发布 状态;沿用 release/ 会让评审误以为目标分支已经冻结。同理,这里不引入常驻 develop——版本作用域的 分支随版本回收,不会长期分叉,也省掉每次发布和 hotfix 后的回合成本。代价是下一版的工作在当前版本 活跃期间只能留在 backlog 等待,这与 P2「不用低优先级新功能填充补丁版」的口径一致。

紧急修复从 main 创建 hotfix/<SemVer>,验证后先合回 main,再前向合入仍活跃的版本分支。任何 分支都不得绕过 Proposal、CHANGELOG 或测试门禁;版本分支用于稳定化,不是降低质量门槛。

当前活跃版本分支见版本计划目录。各版本发布时的历史做法只记在该版本自己的计划里, 本文只描述当前规则。

自动检查

仓根运行:

$ dart run tool/check_planning.dart      # 结构 + 跨文档一致性,CI 门禁
$ dart run tool/backlog_render.dart      # 按需渲染只读台账总表,不提交

CI 会检查:

  • AGENTS.md 存在,CLAUDE.md 只包含 @AGENTS.md,防止 Agent 指令双真源;
  • 每个 backlog 碎片的文件名与 frontmatter id 一致(编号唯一由此保证),字段与正文小节都在封闭集 内、必填项齐全、小节单行且可渲染成表格单元格、仓内链接带 ../ 前缀;
  • 实施状态与目标版本属于封闭枚举(design-gate 另有自己的状态词表);
  • 目标为当前版本的 PB 条目,在对应版本计划 P0/P1/P2 范围表中恰好出现一次;
  • 版本范围表不引用不存在的 PB,也不复制 backlog 的标题列;
  • 碎片中引用的 Proposal 和 design-gate 文件/编号存在,且 Proposal 声明了该编号;
  • 标记 待裁决 的条目必须同时引用 Proposal 和 design-gate;
  • docs/backlog.md 没有重新长出条目行——入库总表一旦回潮,碎片化消除的冲突会原样回来。
  • release_prep 另行检查当前文档的版本锚点、hosted 安装口径、中性示例与架构 SVG;历史区不参与 当前版本漂移判定。

packages/patchbay_cli/tool/command_docs.dart --check 另行验证 Skill frontmatter、配套 INSTALL.md 与 只读起步命令生成块;Skill 只路由到 live catalog / describe / help,不维护第二份可变命令事实。

检查脚本只验证结构关系,不替代对方案内容和验收质量的评审。