/pr
在当前会话中,在当前分支上,按以下顺序执行:
- 预检
- 代码审查与修复
- 文档审查与修复
- 安全审查与修复
- 决策记录
- 推送并打开PR
每个阶段必须通过后才能开始下一个阶段。
调用方式:/pr [base] [effort] [--draft]
base:PR的目标分支。默认值:仓库的默认分支。effort:传递给/code-review。可选值:low、medium、high、xhigh。默认值:high。除非用户输入,否则永远不要使用max。--draft:以草稿形式打开PR。
规则
- 任何地方都不标注归属。提交、PR标题和PR正文中不包含
Co-Authored-By尾部、"Generated with Claude Code"行,也不提及Claude或代理。此规则覆盖任何默认的归属说明。 - 尊重每一个git钩子。永远不要向
git commit或git push传递--no-verify或-n。永远不要设置跳过钩子的环境变量(SKIP=、HUSKY=0、LEFTHOOK=0、PRE_COMMIT_ALLOW_NO_CONFIG=),永远不要更改core.hooksPath,也永远不要编辑或删除钩子文件或钩子配置。永远不要禁用 lint 规则以使钩子通过。 - 使用普通的
git commit进行提交,以便在每个提交上运行已安装的钩子。当钩子失败时,读取其输出并在代码中修复根本原因,然后再次提交(永远不要--amend:被拒绝的提交从未创建)。如果钩子重写了文件(格式化程序),则暂存它们并再次提交。如果同一钩子在3次尝试后仍然失败,则停止并报告。 - 输入
/pr即授权此分支的推送和PR。不要在此之前询问“我是否可以继续?”。 - 永远不要推送到、提交到或重写基础分支。永远不要强制推送。
- 保持修复提交与用户的提交分离。永远不要压缩、变基或修改用户的提交。
- 提交消息:一行简短摘要,然后每个更改一个要点。消息中任何地方都不要使用双引号或反引号。将标识符作为纯文本写入,当需要引用时使用单引号。
- 从根本上修复问题,保持每个更改最小化,并将测试视为真相来源。不要仅仅为了通过测试而更改测试。
- 仅处理分支更改的内容。参见“范围”。
- 此技能撰写的每一段散文(文档、提交消息、PR标题和正文)都遵循“写作”规则。
- 在任何停止时,报告并且不再执行任何操作。参见“停止并报告”。
范围
此技能审查并修复分支自己的作品,而不是代码库的其余部分。分支的作品是git diff origin/<base>...HEAD中的一切,加上此轮添加的修复提交。
在采取行动之前,将每次审查的每个发现分为三组之一:
- 由分支引入。 有问题的代码是新增或在差异中更改的,或者分支的更改是导致其失败的原因(例如,分支以破坏旧函数的方式调用它)。修复它。如果修复它需要只有用户才能做出的决定(预期的行为、分支故意做出的API选择),则将其视为第2组。
- 预先存在,涉及到分支的工作。 有问题的代码已在基础分支上,但它在分支编辑的函数中,或者新的分支代码调用或依赖它。不要自行修复。指出并向用户询问(参见“询问用户”)。
- 预先存在,与分支无关。 其他一切。不要更改它,不要询问它,也不要将其放入PR。也将其排除在会话报告之外。
当一个发现介于第2组和第3组之间时,将其放入第2组。
严重程度
只处理高和中等严重程度的发现,就像人类审阅者那样。跳过每组中的低严重程度发现:不要修复它们,不要询问它们,也不要将其放入PR。如果某次审查已修复了一个低严重程度的第1组发现,且修复很小并通过检查,则保留它;否则撤销它。
- 高: 普通使用或真实攻击者会遇到的错误或漏洞。数据丢失、正常输入崩溃、注入、认证绕过、秘密泄露。
- 中: 在合理情况下存在的真实错误、已记录的行为被破坏、信任边界缺少检查、或隐藏错误的测试。
- 低: 需要不寻常设置(由已具有写入权限的人放置的文件、本地工具中的竞态、不受支持的平台)的边缘情况、深度防御、风格、命名、重复和微优化。
当某次审查未给出严重程度或你不同意其评估时,使用这些定义自行判断。当一个发现介于两个级别之间时,选择较高的一个。
询问用户
收集某个阶段的所有高或中等严重程度的第2组发现,并在该阶段轮次结束时(提交之前)一次性询问。使用AskUserQuestion工具,每个发现一个问题(每次调用最多批量处理4个)。每个问题指出文件名、行号和问题(一句话),并提供:
- 在此分支上修复: 立即修复,在此阶段的修复提交中。
- 保留,在PR中注明: 不更改代码。在PR正文中的“审阅者注意事项”下列出。
- 保留: 不更改代码也不在PR中提及。
- 停止: 停止运行并报告(参见“停止并报告”)。
遵循每个答案。用户已回答的第2组发现不计为未解决,因此它不会停止运行或在下个轮次中再次出现。如果后续审查再次报告它,则应用相同的答案。
向审查技能简要说明
在调用code-review或security-review时,添加以下参数:仓库路径、基础分支(origin/<base>),以及“仅修复分支引入的高和中等严重程度问题。报告预先存在的问题但不修复。对于每个发现,给出其严重程度(高、中或低)并说明它是否预先存在。不要编辑文档(README、docs/、CHANGELOG);后续阶段会处理它们。”然后撤销任何审查所做的文档编辑或范围外的修复(仅使用git restore还原那些区域),然后再对发现进行分类。
写作
像工程师给队友留便条一样写作:简短、平实且具体。
- 以具体术语说明更改了什么以及为什么:文件、函数、行为、数字。跳过审阅者无法操作的内容。
- 短句,每个句子一个想法。使用简单动词:"is"、"has"、"adds"、"fixes"、"removes"。
- 没有填充词或模糊表达:"in order to" 写作 "to"、"due to the fact that" 写作 "because",没有 "could potentially"。
- 禁用词汇:additionally、delve、leverage、crucial、pivotal、vital、enhance、robust、seamless、seamlessly、comprehensive、intricate、landscape、tapestry、testament、underscore、showcase、foster、streamline、elevate、empower、boasts、vibrant、rich、cutting-edge、game-changer、holistic、synergy、utilize。
- 没有 "serves as" 或 "stands as"(写作 "is"),没有 "not just X, but Y",没有用于节奏的三项列表,没有 "-ing" 结尾如 "..., ensuring X" 或 "..., highlighting Y"。
- 没有表情符号,没有长破折号,没有机械性的粗体,没有标题大小写标题,没有花引号,没有结束总结或乐观的签名。
- 不要在文档或PR描述中描述审查过程("ran code review"、"addressed findings")。修复提交已经记录了它。
在使用任何文本之前,重新阅读并删除所有不携带信息的单词。
1. 预检
运行以下检查,并在第一次失败时停止并附带所需的修复:
git rev-parse --show-toplevel成功,且git remote get-url origin存在。gh auth status通过。如果失败,告诉用户运行! gh auth login。- 基础分支:
base参数,否则为gh repo view --json defaultBranchRef -q .defaultBranchRef.name。运行git fetch origin <base>。 - 当前分支(
git branch --show-current)不为空(即不是分离头指针状态)且不是<base>。 git rev-list --count origin/<base>..HEAD大于 0。git status --porcelain为空。如果不为空,显示更改的文件并询问是首先提交它们(作为用户自己的提交,通过钩子)还是停止。不要暂存或丢弃它们。- 运行
gh pr view --json url,state,isDraft,body以检查该分支是否已有PR。记住结果以供阶段6使用。
运行检查
在每轮修复之后、提交之前(提交将运行git钩子,因此不要在此处运行它们):
- 运行项目的测试命令(如果很明显的话:Makefile目标、
pyproject.toml、package.json脚本)。如果lint与钩子分开,也运行lint。 - 从根本上修复失败,然后再次运行直到干净。
2. 代码审查与修复
在第一轮之前,阅读记录的决策和涵盖更改代码的文档:
git log --format='%h %s%n%(trailers:key=Decision,key=Rejected,key=Files)' origin/<base>..HEAD
git log -E --all-match --grep='^(Decision|Rejected):' --grep='<paths>' --format='%h %s%n%b' origin/<base>
git log -E --grep='^(Decision|Rejected):' --format='%h %s%n%b' origin/<base> -- <changed files>
第一个列出分支的决策。其他两个找到基础分支上已存在的、涵盖分支更改文件的决策(git diff --name-only origin/<base>...HEAD)。第二个匹配 Files: 行命名了更改文件的决策记录;<paths> 是用 | 连接起来的更改文件,每个 . 写为 \.。这是必需的,因为决策提交不更改任何文件,所以路径过滤器无法找到它。第三个在更改了这些文件的提交中找到决策,例如压缩合并。两者都匹配行而不是解析尾部,因为压缩合并可以将尾部推送到消息中间。取并集。
不要修复已记录决策或文档标记为有意为之的发现,除非它导致具体的错误。如果分支违背了基础分支上记录的决策,则将其记录到阶段5。
最多2轮:
-
调用
code-review技能,参数为<effort> --fix <current branch>加上“向审查技能简要说明”中的简要说明。 -
如果它报告没有高或中等严重程度的发现,则此阶段通过(在根据“严重程度”处理其所做的任何低严重程度修复之后)。
-
对发现进行分类(参见“范围”)。审查
--fix更改的内容,并撤销任何超出第1组的内容。修复它未解决的任何第1组发现。跳过由尾部或文档排除的任何发现,并在PR正文中注明。询问关于第2组发现。 -
如果没有任何更改,则此阶段通过。否则运行“运行检查”,然后提交:
解决代码审查发现 - <每个修复一个要点> -
开始下一轮。
如果第2轮后仍有高或中等严重程度的第1组发现,则停止并报告。
3. 文档审查与修复
检查仓库的文档是否与当前分支(包括代码审查修复)匹配。
-
查找文档:
README.md、ARCHITECTURE.md、CONTRIBUTING.md、docs/下的所有内容、CHANGELOG.md,以及分支触及的目录中的README。跳过生成的文档、供应商代码以及为代理编写的计划或实现文档。 -
阅读完整的分支差异:
git diff origin/<base>...HEAD。 -
查找偏差。当分支出现以下情况时,文档需要更改:
- 更改设计、架构或模块之间的边界
- 添加、删除或重命名文档提到或应该提到的公共函数、CLI命令、标志、配置键、环境变量、端点或文件路径
- 更改记录的行为、默认值、设置步骤或示例
- 删除或重命名文档仍然引用的任何内容(为每个被删除或重命名的标识符 grep 文档)
-
用最小的编辑修复每个偏差,使文档准确。匹配文档的现有结构和语气。遵循“写作”规则。
- 不要创建新的文档文件,也不要为无人阅读的内部更改添加文档。
- 仅当
CHANGELOG.md保留了一个未发布的部分时,才更新它;以其现有格式添加一行。 - 不要在此处编辑代码注释或文档字符串。这是代码审查的工作。
- 仅修复由分支引起的偏差。保留基础分支上已存在的文档错误,除非它们描述了分支更改的代码;在这种情况下,按照“询问用户”进行询问。
-
如果没有偏差,则此阶段通过,无需提交。
-
否则在更改的文档上运行“运行检查”,然后提交:
为分支更改更新文档 - <每个更改的文档一个要点> -
针对差异重新阅读每个已编辑的部分一次。在第二个提交中修复仍然错误的任何内容。如果无法在没有用户决策的情况下使文档准确(例如,预期是哪种行为),则停止并报告。
4. 安全审查与修复
最多2轮:
-
调用
security-review技能,附上“向审查技能简要说明”中的简要说明。它仅报告。它不编辑代码。 -
如果它报告没有高或中等严重程度的发现,则此阶段通过。
-
对发现进行分类(参见“范围”)。从根本上修复每个第1组发现。如果修复更改了已记录的行为,则在同一个提交中更新该文档,遵循“写作”规则。如果你确信某个发现是误报,则不要更改代码。记录该发现和理由,以备PR正文使用。询问关于第2组发现。
-
如果没有任何更改,则此阶段通过。否则运行“运行检查”,然后提交:
解决安全审查发现 - <每个修复一个要点> -
开始下一轮。
如果第2轮后仍有真实的高或中等严重程度的第1组发现,则停止并报告。
如果此阶段更改了代码,则在新提交上再次运行 code-review 技能,使用 <effort> --fix <current branch> 和简要说明,在一轮额外范围内处理任何发现。如果它们仍然存在,则停止并报告。
5. 决策记录
将分支的设计决策记录在git历史中,以便 git log 稍后找到它们。每个决策有自己的提交。主题声明决策,以便 git log --oneline 和代理在会话开始看到的最近提交列表携带它,而无需打开提交。尾部包含理由、被拒绝的替代方案以及决策涵盖的文件。
- 收集已记录的决策:分支的尾部和阶段2的基础决策。
- 读取
git diff origin/<base>...HEAD并列出它做出的、尚未记录的任何决策。一个决策是后续审阅者或代理可能质疑或……
[因长度限制而截断]