关于 reply-and-review-discipline
reply-and-review-discipline 是一项用于撰写议题回复和审查他人拉取请求的技能,内容会以用户身份发布。它强调通俗易读、便于浏览,并将 PR 评论放入一条待处理审查,供用户编辑和发布。
主要功能
- 01依据报告证据组织议题回复
- 02仅针对缺失信息提问
- 03引用日志并添加说明
- 04将 PR 评论暂存于一条待处理审查
- 05根据仓库归属调整审查标准
适用场景
- 01回复外部议题报告者
- 02审查贡献者提交的拉取请求
- 03发布前准备待用户确认的评论
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vivswan/ skills --skill reply-and-review-discipline安装后在 Claude Code 中输入/reply-and-review-discipline确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.mdREADME.md.codex-plugin/plugin.jsonagents/openai.yamlreferences/issue-replies.md详细介绍
回复与评审规范
别人的讨论串:读者只是快速浏览,并不了解代码;其中写下的内容都会以用户的名义发布。先用通俗的话说明,附上读者自己的日志行并添加箭头注释,只有报告未回答的问题才提问;在 PR 上,用户发布一份待处理的评审。
这些规则适用于在自己并不拥有的讨论串中发言的任何会话:回复 issue,或评审别人的 PR。用户自己的 PR 或 issue 属于 /pr-and-issue-discipline 技能的适用场景。该技能中的可读性规则和脱敏规则在此处同样适用,且保持不变;规则只在该处说明一次。
如果已安装 /unslop,则应在最后对每条回复和暂存评论运行该技能:内容会以用户的名义发布,因此不能留下 AI 腔。
何时适用
- 回复 issue 报告者或外部贡献者
- 使用用户的账户评审别人的 PR
回复问题报告者:先用通俗语言
回复外部贡献者的问题时,读者往往只是浏览讨论串,并不了解代码。先写一段可以独立阅读的通俗说明。只有在技术部分包含通俗说明无法涵盖的信息时,才添加可折叠的技术部分,让读者可以轻松跳过;如果通俗语言足以说明一切,那么整条回复就只需通俗说明。
在他人的 PR 上暂存的发现评论遵循下方“每条评论”规则,只借用本节的语气;暂存摘要在该处有自己的格式。
报告决定开头怎么写:动笔前先读报告者的日志。只有当报告没有给出答案时才提问,因此两种情形的开头不同:原因明确时,说明诊断结果和操作步骤;原因不明时,提出问题。默认先提问正是这些范例旨在纠正的问题。
cause visible in the log cause not in the log
------------------------------------ ------------------------------------
## What the report shows ## Questions (3 at most; say which helps most)
their log lines, with arrow notes ## What the report shows
## What to do their log lines, with arrow notes
1. ... 2. ... 3. ... a guess, labeled a guess, last
one fallback line: what to paste next <details> Technical details </details> (only when it adds something)
两种格式的完整范例,以及双语排版方式:references/issue-replies.md。
- 原因明确:先写
## 报告显示的情况,再写编号列表形式的## 处理方法。 引用读者自己的日志行并附上箭头说明,给出诊断结果;每个编号步骤都附上准确的点击路径或命令(如有)。第一部分最后用一行说明:如果这些步骤无法解决问题,请粘贴哪些内容;不出现## 问题标题。 - 原因不明:先写
## 问题。 只有当诊断结果确实取决于答案时,才使用## 问题标题。以问题形式提问:使用编号列表,最多三个问题,并说明哪个答案最有帮助。- 如果有准确的点击路径或命令,就一并给出。
- 用“哪些信息会有帮助”,而不是“我们需要什么”:报告者是在帮忙。读者可能看完列表就不再继续。
- 第一部分使用通俗语言,但绝不刻意说明这一点(标题规则由“可读性规则”规定)。
- 说明读者做了什么、看到了什么:用“你移除的服务”,而不是“已标记为墓碑状态的服务条目”。如果某种机制没有通俗说法,就描述它造成的效果,而不要说出机制名称。
- 引用读者自己的日志行,并附上箭头说明,不要转述。
- 第二部分是可折叠的技术解读,且只有在补充信息时才添加。 它与
/pr-and-issue-discipline技能中 PR 正文的第二部分使用相同的折叠格式;摘要行使用对应语言(Technical details、Détails techniques)。- 在
<details>块中说明机制名称、日志行与代码路径的对应关系、文档链接,以及未来维护者重读讨论串时会需要的信息。第一部分的内容不依赖第二部分。 - 如果通俗语言已经说清一切,就不添加第二部分。原因明确的范例没有第二部分;请求进行到一半时的范例则有,因为缓冲区大小和超时设置解释了日志为何在此处停止。
- 在
- 猜测放在第一部分末尾,并明确标注为猜测。 这样既能少一次往返,又不会在读者回答前引导他们。
- 先使用报告者的语言,再使用英语。 如果报告者使用其他语言,或粘贴的内容表明他们使用其他语言(例如本地化的错误消息、界面标签),回复就应包含两种语言:先写完整的报告者语言回复,再写完整的英语回复。
- 每种语言的部分都应完整独立;如果回复包含详情块,每部分也都应有自己的详情块。两部分互不充当对方的摘要。
- 两部分放在同一条评论中,中间用分隔线隔开;排版方式见
references/issue-replies.md。
- 仓库惯例决定标题和语气,不决定回复的内容安排。 如果维护者规定“散文优先于模板”,就省略标题并让语气更柔和;回复仍须按相同顺序包含相同内容,并保持便于浏览。可读性按每条回复单独判断,绝不能写成一大段文字。
- “可读性规则”和脱敏规则同样适用于双语回复的两部分。
审查他人的 PR:仅进行一轮待提交审查
Agent 在用户的账号下进行审查,因此发布属于用户的操作:用户自行发布暂存的审查,或指示 Agent 发布自己已决定的结论。所有评论都放入用户可编辑并发布的同一份待处理审查中。绝不能在别人的 PR 上发布独立评论:那会立即以用户的名义发布,且未经编辑。
每个 PR 只在开始阅读前选择一次审查视角。 推荐内容由仓库所有者决定,而非 PR 作者:
- **用户自己的仓库,或用户拥有的组织中的仓库:**采用这些技能的全部标准,就像审查用户自己的 PR 一样;此时
/rubber-duck-review技能会纳入所有已安装技能的## Review Criteria部分,无需询问。推荐采用全部标准。 - **用户不拥有的仓库:**优先遵循该仓库的惯例;是否要求同事的 PR 遵循这些标准,由用户决定。推荐采用正确性视角,并提供其余视角供选择。
-
**收集候选视角:**找到所有声明了
## Review Criteria部分的已安装技能,查找方式与/rubber-duck-review技能的伴随技能步骤相同;还包括该技能本身,用于对 PR 差异进行只读的跨模型审查;如果 PR 涉及工作文本(页面、评论、描述),还包括/working-text。 -
**先阅读记忆:**阅读会话可用的记忆(索引,若记忆系统设有索引;以及本项目的记忆)。关于此仓库的长期修正意见、用户上次审查类似 PR 时给出的规则、用户偏好而非手动实现的库:每一项都可能增加或移除一个视角,或让推荐更加准确。
-
只询问一次,并先给出推荐;每个视角的理由都要写在对话框内,因为对话框外的文本会丢失:
Lenses for PR #123 on octocat/fetcher, a repository you do not own (adds a retry loop in src/fetch.ts and a page docs/retries.md). Apply which? [x] /rubber-duck-review on the PR diff (Recommended) a second model, read-only, before staging [x] /never-twice criteria (Recommended) the retry loop repeats a fix from PR #98 [ ] /code-standards criteria their repository, their standards; memory: prefer a library over hand-rolling, if you hold this PR to it [ ] /working-text docs/retries.md is a new page [ ] /no-invalid-states no lifecycle flags or repeated guards in the diff [ ] /verify-with-controls the body claims no zero, alarm, or success reading -
在整个 PR 的待处理审查过程中保留用户的选择。 对此 PR 执行
/rubber-duck-review时,只展开用户在此处选择的## Review Criteria部分,而不是所有已安装的部分:该技能的全节规则适用于用户自己的变更,此处的选择则限定了审查范围。然后阅读 PR 链接的文档和代码,最后才开始撰写。
**暂存:**使用一个 JSON 正文,并在其中指定头部提交;不要包含 event 字段。commit_id 应写入文件:使用 --input 时,-f 字段会进入 URL 查询字符串。
使用 harness 的文件写入工具创建文件,并将头部 SHA 写入其中:评论正文可能包含反引号,用 shell heredoc 会执行这些内容;某些沙盒也会拒绝 heredoc、trap 或在命令中串联变量。每一步只执行一条普通命令,并将删除操作作为最后一条独立命令,方式与 /pr-and-issue-discipline 技能的 PR 正文回退方案相同。
跨越多行的问题应锚定整个范围,使用 start_line 和 line;start_side 和 side 用于指定这些行所在的差异侧:新文件中的行使用 RIGHT,删除的范围使用 LEFT。只有当单行足以完整描述问题时,才使用单行锚点。
gh pr view <n> --repo <owner>/<repo> --json headRefOid -q .headRefOid # 1. the head SHA, for commit_id below
mktemp -d /tmp/pr-review-XXXXXX # 2. prints e.g. /tmp/pr-review-Kq3mZp; copy the printed path by hand
# 3. write /tmp/pr-review-Kq3mZp/review.json with the harness's file-writing tool:
# {
# "commit_id": "<head SHA>",
# "comments": [
# {"path": "src/metrics.ts", "line": 42, "side": "RIGHT", "body": "Review summary (copy into the summary box)\n\n[comment, not approve yet]\n\n**Works:** ...\n**Blocks:** ..."},
# {"path": "src/metrics.ts", "start_line": 84, "start_side": "RIGHT", "line": 88, "side": "RIGHT", "body": "[blocking] The two headline metrics disagree on answers that cannot be parsed. Count them the same way in both."}
# ]
# }
gh api -X POST repos/<owner>/<repo>/pulls/<n>/reviews --input /tmp/pr-review-Kq3mZp/review.json --jq .id # 4. no "event": stays pending
rm -rf /tmp/pr-review-Kq3mZp # 5. its own command, whatever gh returned
**修改:**GitHub 对每位作者在每个 PR 上只允许有一份待处理审查,因此第二次 POST 会失败。重新读取当前待处理审查中的评论,因为用户可能已在网页界面中编辑过它们;然后根据这些文本重建完整内容。接着删除该审查,确认没有剩余待处理审查,再重新创建,并告知用户其 ID 已更改:
# --paginate: a PR with many reviews spreads them over pages, and the pending one is the newest
gh api --paginate repos/<owner>/<repo>/pulls/<n>/reviews --jq '.[] | select(.state == "PENDING") | .id' # the id to delete
gh api --paginate repos/<owner>/<repo>/pulls/<n>/reviews/<id>/comments --jq '.[] | {path, start_line, start_side, line, side, body}' # the current text, web edits included, with each anchor's range; rebuild from this (position alone would collapse a ranged comment to one line)
gh api -X DELETE repos/<owner>/<repo>/pulls/<n>/reviews/<id>
gh api --paginate repos/<owner>/<repo>/pulls/<n>/reviews --jq '.[] | select(.state == "PENDING") | .id' | wc -l # must print 0 before the new POST
结论应保留在 PR 上,绝不能写入文档。
- 摘要是暂存的行内评论,位于首个变更行上方,标题为
Review summary (copy into the summary box),接着是方括号括起的建议([LGTM]、[comment, not approve yet]或[request changes]),然后仅有Works:和Blocks:两行。需要写成第三行的细枝末节不会暂存。网页对话框会丢弃通过 API 设置的评审正文,因此用户要将这段内容粘贴到摘要框中。 - 用户已决定并告知 Agent 发布的评审结论会直接发送,包含
event(APPROVE、REQUEST_CHANGES或COMMENT)和body,而不是暂存。该指令即为发布;没有该指令时,一切都会保持待处理状态。 - 给用户的报告是一行聊天消息,包含建议:不生成问题文档、不生成供复制粘贴的文件,也不添加仪表板条目。
每条评论:
- 用通俗英语写一到两句话,尽可能简短。 以方括号括起的发布者提示开头(
[blocking]、[small ask]、[question]),然后写明要求的具体改动。不写背景,也不复述代码的作用。可接受的示例:"[blocking] The linked comment has only headline and per-type tables, not the 100-task paired table the body promises. Please post it or link to it." - 语气自然,像真人说话: 使用 Replies 部分的措辞(通俗语言,不用内部名称),而不是它的双段式布局或语言配对。不可接受的示例:"PARSING_ERROR maps to COULD_NOT_EXTRACT_ANSWER, which is trainable, so the rollout arrives as a CompletedRollout with reward 0"。每条评论最多使用一个代码标识符,进行一项比较,不串联多个数字。只有作者若不知晓便无法采取行动的技术细节才予以说明。
- 重新评审时,只暂存仍未解决或部分解决的问题评论。 作者已处理的问题不单独评论;摘要可用一行列出已解决的问题。
- 只关注会改变行为、可靠性或已陈述事实真实性的问题。 除非用户提出要求,否则不暂存测试覆盖率、YAGNI 和代码整理方面的小问题:大多数发布者会丢弃它们,因此暂存只会增加一轮编辑。
- 仅影响 Windows 的问题(换行符转换、路径分隔符)只有在仓库支持 Windows 时才构成问题:其 CI 矩阵、文档或问题列表中必须有相关说明。大小写不敏感的文件系统也是 macOS 的默认设置,因此仍应视为问题。
- 适用去标识规则:暂存的评论会以用户的名义发布。