oh-my-posh 代码变更工作流的交付阶段:从规范提交、推送策略到最终报告
【免费下载链接】oh-my-poshThe most customisable and low-latency cross platform/shell prompt renderer项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-posh
本指南以 oh-my-posh 仓库内置的code-changesAgent 技能(位于 .agents/skills/code-changes)中Phase 6 — Deliver(交付阶段)参考文档(references/deliver.md)为核心,系统讲解一次代码变更在验证通过之后,如何以规范提交(conventional commits)、克制保守的推送策略和"结论优先、证据随后"的最终报告完成收尾。读完本文,你将掌握 oh-my-posh 仓库对提交粒度、暂存方式、改写分支推送约束的硬性要求,并能按交付阶段的五要素结构撰写一份可审计、可复核的变更报告。
交付阶段在六阶段工作流中的位置
code-changes技能把"从想法到代码落地"编排为六个按序执行的阶段,交付是最后一环:
- Analyze(references/analyze.md):基于代码而非报告本身定位根因与范围;
- Plan(references/plan.md):产出固定规格与任务拆分;
- Delegate(references/delegate.md):为每个任务匹配合适的执行模型;
- Supervise(references/supervise.md):监督、解阻并批判性复核实现产出;
- Verify(references/verify.md):质量门禁加功能实证,在最终合并态上运行;
- Deliver(references/deliver.md):规范提交并输出结论优先的报告。
交付阶段的前提是"变更已验证"(The change is verified; now package it),它的任务是把验证过的成果打包落地。工作流默认由Coordinator(协调者)角色持有全部阶段,交付阶段同样由其负责。阶段边界之间通过具名构件(artifact)衔接——详见 references/artifacts.md——因此交付阶段接收的是 Verify 阶段移交的验证证据,而不是口头上的"应该没问题"。
提交纪律:让每一次 commit 都经得起审查
每个提交都使用 Conventional Commit 规范
交付阶段第一条规则:每条提交信息都必须使用 conventional-commit 技能(.agents/skills/conventional-commit/SKILL.md)。该技能定义了标准的提交信息结构:
<type>(<scope>): <description> [optional body] [optional footer(s)]各部分的填写规则如下:
| 要素 | 规则要点 |
|---|---|
| type(必填) | 从受控枚举中取值:feat(新功能)、fix(缺陷修复)、docs(仅文档)、style(格式化、补分号等不改变逻辑)、refactor(既非修复也非功能的代码变更)、perf(性能改进)、test(新增或修正测试)、ci(CI 配置变更)、chore(依赖与工具链等维护)、revert(回滚此前提交) |
| scope(可选) | 受影响区域名,如segment、cache、config、ui;真正跨切面的变更可省略 |
| description(必填) | 一句祈使句,不加句号;整行头(type+scope+description)不超过72 字符,描述本身建议控制在50 字符以内 |
| body(可选) | 解释"为什么"而不是"是什么"(diff 已展示是什么),每行按 72 字符换行 |
| footer(可选) | 用于BREAKING CHANGE:说明、Issue 引用(Closes #123)、共同作者(Co-Authored-By: Name <email>) |
描述必须使用祈使语气:写add、fix、bump、implement,而不是added、fixed、bumped。不要照搬输入措辞——如果需求文本用了过去时(updated、was removed等),落笔前必须先转换成祈使句。
破坏性变更必须双标记同时出现:类型后追加!(如feat!:或feat(api)!:),并且在 footer 中写BREAKING CHANGE:说明。二者永远成对出现,缺一不可。判断标准是:这个变更是否移除、重命名或改变了调用方依赖的既有行为——是,就是破坏性变更。
技能文档给出的示例:
feat(segment): add Ramadan segment with Aladhan API fix(cache): always store mod time docs(readme): update installation instructions refactor(config): simplify option parsing logic chore(deps): bump github.com/shirou/gopsutil/v4 feat(segment)!: rename template property StartTime to Start BREAKING CHANGE: template strings using .StartTime must be updated to .Start仓库级的提交规范约束:.commitlintrc.yml
oh-my-posh 仓库在根目录的 .commitlintrc.yml 中用 commitlint 把上述规范固化为可机器校验的规则:
- 继承
@commitlint/config-conventional基础配置; type-enum在标准类型之外额外放行theme——这正对应 oh-my-posh 的themes/目录下以 JSON 主题文件为主的变更类型,是仓库对自身业务形态的适配;body-max-line-length放宽为 200 字符(提交正文按 200 字符折行)。
这意味着提交信息不仅要在写作时遵循技能规范,还要能通过.commitlintrc.yml定义的 CI/钩子校验;提交前应核对技能附带的Validation Checklist:类型合法、范围反映真实改动区域、描述为祈使语气且无句尾句号、整行头 ≤72 字符、破坏性变更双标记齐备、且绝不允许暂存.env、凭据等敏感文件。
一个逻辑单元一个提交,显式暂存,提交前复核
deliver.md 对提交粒度和暂存方式有三条硬约束:
- 一个逻辑单元对应一个提交。一个特性与其引发的 lint 修复,如果对应不同的"为什么",可以拆成独立提交——提交的边界由"为什么"决定,而不是由文件的相似度决定。
- 显式暂存文件,绝不使用
git add -A。全量暂存会把无关文件、临时产物甚至敏感信息一并带入提交,破坏提交的可审计性。 - 提交前复核暂存区 diff。尤其是自动修复工具(auto-fixing tools)改写过文件之后,必须先
git diff --cached检查改动是否符合预期,再执行提交。
这与 conventional-commit 技能的工作流(git status→git diff→git diff --cached→ 定 type/scope → 写描述 → 显式暂存 → 多行消息提交)是一一对应的。
推送与 PR 策略:提交就是提交,仅此而已
deliver.md 用一句非常克制的话定义了推送边界:除非用户明确要求,否则不要 push、不要 force-push、也不要开 PR。"Commit" 就意味着提交,不多不少。
这条策略的动机在于:交付阶段默认工作于本地历史之上,任何对远程的写操作都改变了他人可见的状态,属于需要用户明确授权的高影响动作。当用户确实要求推送且目标分支是被改写过的(rewritten branch)时,必须使用--force-with-lease而非--force——--force-with-lease会先校验远程引用是否仍是你基于的版本,避免覆盖他人新推入的提交。
仓库根目录的 AGENTS.md 对 PR 评审场景给出了更细的配套规则,与交付阶段的推送策略互为补充:
- main 历史绝不改写,但 PR 分支可以安全改写;
- 评审反馈若语义上属于 PR 中的某个既有提交,应创建 fixup 提交(
git commit --fixup <sha>),再用git rebase --autosquash折叠回原提交,最后 force-push PR 分支——这保持了 PR 提交的原子性,而不是在其上堆叠评审修复提交; - 仅当改动无法归入 PR 中任何既有提交时,才作为独立提交叠加在 PR 之上。
可以看到,"改写分支"与"main 历史"是两个完全不同的信任域:前者用--force-with-lease是被允许的,后者则被明令禁止。
最终报告:结论优先,证据随后
deliver.md 的核心产出物是一份最终报告(final report),其总原则是:先讲结论(outcome),再给证据(evidence),并用一段话(而非罗列式开头)概括"改了什么、为什么改",且包含可点击的文件引用。
报告必须包含以下五个部分:
- 变更内容与理由:一段概括后,给出具体变更清单(含文件引用)与原因。
- 实现者产出被覆盖之处:哪些由子代理/实现者交付的代码被协调者替换了,为什么。对应 Supervise 阶段的
overrides记录——见 references/artifacts.md。 - 验证证据:运行了哪些质量门禁(gates),观察到了哪些具体的功能性结果(concrete functional results)。
- 明确留给用户的未尽事项(loose ends):需要删除的密钥、需要人工执行的验证步骤、被推迟的决策,每一项都尽量给出精确的命令或检查方式。
- 变更未做到但其标题所暗示的事:如果提交信息写的是"移除 X",要说明 X 中哪些部分仍然保留及原因;如果某项能力被移除或替换,要如实表述为"移除",而不是粉饰成"简化"。
报告还有两条不可妥协的底线:绝不要把未经验证的步骤报告为已完成;绝不要把失败埋藏在成功叙事的中间。失败要么前置说明,要么单独成段,不允许用成功话术稀释。
交付前的证据契约:Verify → Deliver 交接什么
交付报告中的"验证证据"不是口头承诺,而是由 Verify 阶段按具名构件契约移交的。依据 references/artifacts.md,Verify → Deliver 的交接物是verification evidence,含三个字段:
gates_run:构建、测试、lint、格式化结果——必须是 pass/fail 的实况,而不是"应该会通过";functional_proof:走真实流程观察到的实际数值,而不是形容词;retry_count:该任务经历的 Verify 轮次,供交付报告注明修复是否经过多轮才落地。
质量门禁的两半
references/verify.md 规定验证包含两半,缺一不可:
- 质量门禁:构建、完整测试套件、格式化器与 lint 全部零错误通过;按 Phase 2 钉住的语言/框架技能逐行人工复核最终 diff(lint 不覆盖控制流、测试结构、日志与注释约定,绿色 lint 不等于遵循了技能);当平台相关文件变更时,还要为每个目标平台交叉编译或重新 lint——本地工具链会跳过其他平台的规则。
- 功能实证:测试通过是必要不充分条件。要跑通真实流程并确认具体输出——渲染 prompt、执行命令、命中端点,并把实际观察值记录为最终报告的引证。
verify.md 还强调要以用户实际到达该功能的方式去验证:用构建产物而不是开发服务器、用冷启动而不是运行中的进程、从用户真正打开的入口出发;涉及开发服务器或文件监听器时要先重启再评判行为——陈旧的 bundle 会产生"自信的错误验证"。
失败记录与重试上限
Verify 失败时会生成failure record(attempt_number/failure_class/destination/escalation_answer),把计数以文本形式显式写入报告而不是依赖跨轮次记忆。规则是:
- 门禁失败或 diff 不符合规格 → 返回 Phase 4(Supervise)修执行;规格没错,是执行错了;
- 功能实证与根因矛盾、或修复完全没改变观察行为 → 返回 Phase 1(Analyze),并重新武装其停止门禁(stop gate):再次报告修订后的分析并等待用户批准,而不是默许继续;
- 同一任务连续第二次失败 → 停止循环,将具体问题升级(escalate)给最强推理模型;
- 升级答案之后的下一轮仍失败 → 不再升级也不再回送,彻底停止并上报用户,附上此前两次尝试、升级问答与最新失败证据——继续循环意味着工作流本身对该任务不收敛,这个决定权属于用户。
这套重试上限保证了交付阶段拿到的验证证据要么是可信的绿,要么是带完整上下文的失败记录,报告中不会有第三种状态。
在 oh-my-posh 仓库中的落地实践
交付阶段的各项要求在 oh-my-posh 仓库中有直接的落地点:
- 提交规范的可执行载体是根目录 .commitlintrc.yml(
type-enum含theme等 10 类,body-max-line-length为 200),配合 conventional-commit 技能的 Validation Checklist 使用; - 仓库级工作约定见 AGENTS.md:包括 Go 模块根位于
src/、关键命令(cd src/ && go test ./...、golangci-lint run;文档侧cd website/ && npm run build)、PR 评审的 fixup/rebase 流程等; - 验证门禁的默认命令与 AGENTS.md 的 Key Commands 一致,交付报告中的
gates_run应直接引用这些命令的 pass/fail 实况; - 阶段交接的构件契约固化在 references/artifacts.md:除了 Verify → Deliver 的验证证据,还包括 Analyze → Plan 的分析报告(
root_cause/proposed_change/out_of_scope/repro_status/open_questions)、Plan → Delegate 的任务清单、Delegate → Supervise 的委托包、Supervise → Verify 的已评审 diff(merged_diff/overrides/tests_kept/tests_cut)——交付报告的第二部分(覆盖说明)与第三部分(验证证据)正是消费这两个上游构件的字段。
小结:交付阶段的四条底线
回顾 deliver.md 的全部内容,可将其提炼为四条可执行底线,适用于 oh-my-posh 仓库乃至任何遵循该工作流的 Go 项目:
- 提交层面:Conventional Commits 全量覆盖;按"为什么"切分逻辑单元;显式暂存、拒绝
git add -A;提交前必查暂存区 diff。 - 远程层面:未经要求不 push / 不 force-push / 不开 PR;改写分支必须用
--force-with-lease;main 历史永不改写。 - 报告层面:结论优先、证据随后;五要素(变更与理由、覆盖说明、验证证据、未尽事项、标题言过其实之处)缺一不可;不虚报未验证步骤,不埋藏失败。
- 衔接层面:交付只消费 Verify 移交的验证证据(
gates_run、functional_proof、retry_count),任何"应该没问题"都进不了最终报告。
把这四条底线落到每一次提交与每一份报告中,交付就不再是"写完代码点提交",而是一个可以被任何人重新审计、重新验证的工程闭环。
【免费下载链接】oh-my-poshThe most customisable and low-latency cross platform/shell prompt renderer项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-posh
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考