Symphony 的 Codex「commit」技能实战:让编码代理产出规范化 Git 提交
【免费下载链接】symphonySymphony turns project work into isolated, autonomous implementation runs, allowing teams to manage work instead of supervising coding agents.项目地址: https://gitcode.com/gh_mirrors/symphony7/symphony
本文围绕 Symphony 仓库中的.codex/skills/commit/SKILL.md展开,系统讲解这一 Codex Agent 技能如何驱动编码代理从"当前工作区变更 + 会话历史"中生成一条符合惯例(conventional type、短主题行、72 字符换行的正文、Co-authored-by trailer)的 git 提交。读完后,你可以完整复现该技能定义的 12 步提交流程与消息模板,并理解它在 Symphony 代理交付流水线(pull / commit / push / land)中的位置。
一、它是什么:一个面向编码代理的提交工作流定义
在 Symphony 的.codex/skills/目录下,仓库为 Codex 编码代理预置了一组"技能"(skill)文件,包括commit、pull、push、land、release、debug、linear等,每个技能以SKILL.md描述触发条件、目标、步骤与命令。其中 commit 技能 负责"提交"这一环:当用户要求 commit、准备提交信息或收尾已暂存的工作时,代理按该文件定义的流程创建一条"良构"(well-formed)的 git 提交。
文件以 YAML front matter 声明技能元数据,这是 Codex 技能的触发约定:
name: commit description: Create a well-formed git commit from current changes using session history for rationale and summary; use when asked to commit, prepare a commit message, or finalize staged work.description同时承担"何时使用"的判定依据——被要求提交、被要求撰写提交信息、或被要求完成暂存工作时,该技能即被激活。
二、设计目标(Goals)
技能文件开头给出三条目标,界定了"合格提交"的标准:
- 提交必须反映真实的代码变更与会话上下文(reflect the actual code changes and the session context),即提交信息不是凭 diff 猜测,而是来自"人让代理做了什么"的会话证据;
- 遵循通用 git 惯例:类型前缀(type prefix)、短主题行(short subject)、换行包裹的正文(wrapped body);
- 正文同时包含 Summary 与 Rationale,即"改了什么"和"为什么改"都要写进 body。
这第三条在 Symphony 的仓库实践中是一以贯之的——仓库的 PR 模板 同样强制要求 Context、TL;DR、Summary、Alternatives、Test Plan 五个段落,提交信息与 PR 描述共享同一套"变更 + 理由"叙事结构。
三、三类输入(Inputs)
技能明确列出三条输入来源,这也是后续所有步骤的信息基础:
- Codex 会话历史(session history):用于还原意图与理由(intent and rationale)——为什么做这次修改、范围是什么;
- 实际变更:
git status、git diff、git diff --staged三者分别给出工作区状态、未暂存变更与已暂存变更; - 仓库级提交约定(if documented):如果仓库文档中有提交规范(如 conventional commits 的类型集合),优先遵循。对 Symphony 而言,可参考 elixir/AGENTS.md 中的验证与规范要求来校准"Tests"一节应写什么。
四、12 步工作流详解
技能核心是编号 1–12 的步骤清单。下面按逻辑分组完整展开。
4.1 范围确认与暂存卫生(步骤 1–5)
- 读取会话历史,确定本次变更的范围(scope)、意图(intent)与理由(rationale)。
- 检查工作区与暂存区:依次执行
git status、git diff、git diff --staged,确保对"哪些文件改了、改了什么、哪些已进 index"有完整认知。 - 暂存目标变更:确认范围后执行
git add -A(包括新文件)。 - 新增文件体检(sanity-check):对
git add进来的新文件逐一检查——如果某个文件"看起来随机"或明显属于应当被忽略的产物(构建产物 build artifacts、日志 logs、临时文件 temp files),必须先向用户标记(flag)出来再决定是否提交,而不是直接入库。 - 暂存完整性校验:如果暂存不完整(漏文件)或夹带了无关文件,要么修正 index,要么请求用户确认。
这一步的设计意图是把"暂存区 = 本次提交语义边界"当作硬约束:后面第 12 步会用同一把尺子反过来校验提交信息。
4.2 消息构造(步骤 6–8、10)
- 选择 conventional 类型与可选 scope,类型必须与实际变更匹配,例如:
feat(scope): ...新功能fix(scope): ...缺陷修复refactor(scope): ...重构
- 主题行(subject):祈使语气(imperative mood)、长度不超过 72 字符、结尾不加句号。
- 正文(body)必须包含三部分:
- Summary:关键变更摘要(what changed);
- Rationale:变更理由与取舍(why it changed);
- Tests:实际运行过的测试或验证命令;若未运行,必须显式注明("not run (reason)"),不允许留空或含糊其辞。
- 正文按 72 字符换行(wrap body lines at 72 characters),保证
git log、邮件和终端中的可读性。
其中 Tests 一节与 Symphony 仓库自身的验证门禁直接对应:elixir/AGENTS.md 声明主质量门是make all(format 检查、lint、覆盖率、dialyzer),push 技能 在推送前也要求先跑make -C elixir all。因此在该仓库语境下,"Tests" 一行的标准答案通常是`make -C elixir all`(N tests, M failures, X% coverage),这与下文第五节的真实提交实例一致。
4.3 Co-authored-by 署名(步骤 9)
追加 Codex 的 trailer:
Co-authored-by: Codex <codex@openai.com>除非用户明确要求使用其他身份,否则代理生成的提交一律携带该 trailer。这是 Symphony 提交历史中的实际惯例——仓库最近的提交(如 "Scrub GitHub and GitLab authentication token aliases (#119)")正文末尾即为
Co-authored-by: Codex <codex@openai.com>,可以印证该步骤已被落地执行。
4.4 写入与提交(步骤 11–12)
- 用 here-doc 或临时文件承载消息,并以
git commit -F <file>提交。技能特别强调:不要用git commit -m配合\n字符串,因为 shell 中-m的参数处理容易让换行变成字面字符或丢失空行,而-F保证新行是字面的(literal newlines),多段正文、空行分隔的 Summary/Rationale/Tests、以及 trailer 的精确位置都能可靠保留。 - 一致性门禁:只有当消息与暂存变更严格匹配时才允许提交。两个反向检查:
- 暂存的 diff 里如果包含无关文件 → 先修 index;
- 消息描述的工作如果根本没有被暂存(写了 Summary 但 diff 里没有对应改动)→ 先修消息。
第 12 步与第 4/5 步构成闭环:暂存卫生在提交前把关,消息-变更一致性在提交前最后一道把关。
五、提交信息模板
技能文件末尾给出可复制的模板(原文档核心资产,此处完整保留;type 与 scope 仅为示例,应按仓库和实际变更调整):
<type>(<scope>): <short summary> Summary: - <what changed> - <what changed> Rationale: - <why> - <why> Tests: - <command or "not run (reason)"> Co-authored-by: Codex <codex@openai.com>一个符合该模板与 Symphony 实际惯例的成品长这样(取自仓库真实提交的形态):
fix(auth): scrub GitHub and GitLab authentication token aliases Summary: - Scrub GitHub CLI token aliases in the existing GitHub provider client. - Scrub GitLab access-token aliases while preserving distinct CI job credentials. Rationale: - Authentication aliases let coding agents inherit tracker credentials and bypass Symphony's host-side boundary. Tests: - make -C elixir all (296 tests, 0 failures, 100% coverage) Co-authored-by: Codex <codex@openai.com>六、在 Symphony 交付流水线中的位置
从源码结构看,commit不是一个孤立技能,而是代理"交付闭环"中的一个节点。land 技能 的步骤 3 与步骤 8 都显式写有"commit with thecommitskill":工作树有未提交变更时先用commit技能提交、再用 push 技能 推送;CI 检查失败、修复之后同样是commit→push的固定组合。pull 技能 则在合并冲突解决后要求按仓库策略(AGENTS.md)跑项目检查——即 Symphony 中make all/make -C elixir all。
由此可以推断 Symphony 代理的完整交付链路为:
pull(同步 origin/main、解冲突) → commit(本技能:良构提交) → push(验证门 make -C elixir all + PR 创建/更新 + mix pr_body.check) → land(监控 CI、处理评审、squash-merge)值得注意的是 push 技能中对 PR 正文的校验方式与提交信息的叙事要求一脉相承:mix pr_body.check会按 PR 模板 强制 Context/TL;DR/Summary/Alternatives/Test Plan 结构完整,提交信息里的 Summary/Rationale/Tests 正是这套结构在 commit 粒度上的投影。
七、要点小结
- 信息源三分法:会话历史给"为什么",
git status/git diff/git diff --staged给"改了什么",仓库文档给"怎么写"。 - 暂存区即语义边界:新增文件要先体检(构建产物、日志、临时文件必须标记),提交前再做消息-暂存一致性校验。
- 消息三要素:Summary(what)、Rationale(why)、Tests(验证命令或未运行原因),配合 72 字符换行、祈使语气短主题、conventional 类型前缀。
- 用
git commit -F <file>而非-m "\n",保证多行消息字面保真。 - 固定 trailer
Co-authored-by: Codex <codex@openai.com>是 Symphony 代理提交的身份标识,除非用户显式指定其他身份。
对希望在自己仓库复刻这套实践的读者而言,最小可迁移物就是 commit 技能文件 本身:把 12 步清单与模板放入.codex/skills/commit/SKILL.md(或等价的 agent 技能位置),再按本仓库 elixir/AGENTS.md 的模式在AGENTS.md中声明你的验证门禁命令,代理即可产出口径统一的提交历史。
【免费下载链接】symphonySymphony turns project work into isolated, autonomous implementation runs, allowing teams to manage work instead of supervising coding agents.项目地址: https://gitcode.com/gh_mirrors/symphony7/symphony
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考