关于 candid-loop
candid-loop 是围绕 candid-review 的代码审查与修复循环技能,供希望迭代处理审查问题的开发者使用。它支持自动、逐项确认和交互模式,并可按类别、忽略规则及迭代上限控制流程。
主要功能
- 01重复运行 candid-review
- 02自动或逐项应用修复
- 03交互式跳过与忽略问题
- 04按类别筛选问题
- 05配置迭代上限与审查规则
适用场景
- 01持续修复代码审查发现的问题
- 02逐项确认高影响修改
- 03忽略已知误报并限制审查类别
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ron-myers/ candid --skill candid-loop安装后在 Claude Code 中输入/candid-loop确认已加载。
详细介绍
Candid Loop
反复运行 candid-review,直到代码没有问题。此技能会自动执行修复-审查-修复循环,不断应用修复并重新运行审查,直到没有剩余问题(或达到最大迭代次数)。
工作流
按顺序执行以下步骤:
步骤 1:加载配置
从 CLI 标志和配置文件加载循环配置。
优先级(从高到低):
- CLI 标志
- 项目配置(
.candid/config.json→loop字段) - 用户配置(
~/.candid/config.json→loop字段) - 默认值
检查 CLI 参数
解析 CLI 参数中的循环选项:
| 标志 | 说明 | 默认值 |
|---|---|---|
--mode <auto|review-each|interactive> | 执行模式 | auto |
--max-iterations <N> | 最大循环迭代次数 | 5 |
--categories <list> | 要强制执行的类别(逗号分隔) | all |
有效模式:
auto- 自动应用所有修复review-each- 逐一处理每项修复(每项都回答 Yes/No)interactive- 完全掌控,可跳过、忽略并批量处理
有效类别: critical、major、standards、smell、edge_case、architectural、all
如果提供了 CLI 标志,则使用这些标志,并跳过对相应选项的配置文件检查。
检查配置文件并应用默认值
从 .candid/config.json 读取 loop 字段(jq -r '.loop // null' .candid/config.json 2>/dev/null);如果不存在,则尝试读取 ~/.candid/config.json。对于未通过 CLI 设置的 mode、maxIterations、enforceCategories,使用配置中的值;同时提取 ignored {categories, patterns, ids}。应用配置时,输出 Using loop settings from project config 或 Using loop settings from user config。
仍未设置的项目使用默认值:mode = "auto"、maxIterations = 5、enforceCategories = ["all"]、ignored = { categories: [], patterns: [], ids: [] }。
- 将已知误报的模式添加到忽略列表。
- 将 maxIterations 保持在 5-10。
步骤 2:初始化循环状态
设置跟踪变量:
iteration = 0
totalFixesApplied = 0
allFixedIssues = []
registerQuestionsRaised = 0
registerQuestionsResolved = 0
registerPriorDecisionsApplied = 0
显示模式横幅:[<Mode> Mode] Running candid-loop with max [N] iterations...,随后另起一行显示 review-each 模式说明("You will review each fix one by one.")或 interactive 模式说明("Full control: skip, ignore, or batch process fixes.")。
步骤 3:运行审查循环
执行主循环:
WHILE iteration < maxIterations:
iteration++
Execute Step 3.1 through Step 3.6
IF exitLoop == true:
BREAK
IF iteration >= maxIterations AND remainingIssues > 0:
Output warning: "Max iterations ([N]) reached. [M] issues remain."
List remaining issues
循环不变量 — 不得违反
- PASS 必须基于全新且无问题的审查。 仅当最后一次迭代在应用最后一项修复后运行了 candid-review,且发现筛选后的问题数为 0 时,状态才能为 PASS。确认
.candid/last-review.json的时间戳晚于最后一次 Edit。切勿根据较早迭代推断为 PASS。 - 没有进展 → 停止。 如果某次迭代应用了 0 项修复,但筛选后的问题仍然存在,则立即以 INCOMPLETE 退出——重复相同的审查无法解决问题。
- 振荡检查。 如果某个已在
allFixedIssues中的问题 ID 在后续迭代中再次出现,则停止:Oscillation detected: fix for [id] was undone or reintroduced.列出这两次修复,以便手动处理。 - 不要再次询问已拒绝的问题。 将通过“No”/“Skip”跳过的问题 ID 添加到
sessionSkipped;在后续迭代的步骤 3.4 中筛除这些问题。它们计入 INCOMPLETE,而不是再次提示。
第 3.1 步:运行 candid-review
显示迭代标题:
[Iteration [N]/[MAX]]
Running candid-review...
调用 candid-review 技能分析当前代码:
- 使用 Skill 工具运行
/candid-review - 如果已配置语气设置,则传递这些设置
- 等待审查完成,并将状态保存到
.candid/last-review.json
注意: candid-review 会显示自己的修复选择提示。在自动模式下,我们需要通过选择“应用所有修复”来处理。在交互模式下,则由用户在 candid-review 中自行选择。
决策记录: 如果配置中启用了决策记录,每次 candid-review 迭代都会独立读取和更新记录文件。这意味着:
- 第 1 次迭代提出的问题会记录在记录文件中
- 从第 2 次迭代开始,candid-review 会先检查记录文件,避免再次提出相同问题
- 如果问题已在之前的迭代中得到回答,则会自动沿用该答案
- 在自动模式下,记录文件中已有答案的“需要澄清”问题会直接应用,无需提示
第 3.2 步:读取审查结果
candid-review 完成后,读取保存的审查状态:
cat .candid/last-review.json 2>/dev/null
解析 JSON,提取:
- 包含所有已发现问题的
issues数组 - 每个问题包含:
id、file、line、category、title、description
如果文件不存在或为空:
No review state found. candid-review may not have completed.
报错退出。
第 3.3 步:按类别筛选问题
如果 enforceCategories 不是 ["all"]:
筛选 issues 数组,仅保留与 enforceCategories 匹配的问题:
filteredIssues = issues.filter(issue =>
enforceCategories.includes(issue.category)
)
输出:Enforcing categories: [list]. Filtered to [N] issues.
第 3.4 步:筛除忽略的问题
应用配置中的忽略筛选条件:移除类别属于 ignored.categories、标题匹配 ignored.patterns 中任一正则表达式(不区分大小写),或 ID 属于 ignored.ids 的问题。
如果有问题被筛除:
Filtered out [N] ignored issues ([M] remaining)
第 3.5 步:检查是否完成
如果 filteredIssues.length === 0:
[Iteration [N]/[MAX]] No issues found!
exitLoop = true
跳至第 4 步(摘要)。
第 3.6 步:根据模式处理问题
如果 mode == "auto":
显示发现的问题:
[N/MAX] Found [M] issues. Applying fixes...
如果用户在提示词中选择了“Apply all fixes”,candid-review 技能会先行应用修复。由于我们处于 auto 模式,因此应该已将 candid-review 配置为自动应用修复。
对于每个已修复的问题,记录:
✓ [icon] Fixed: [title] in [file]:[line]
跟踪修复:
totalFixesApplied += appliedCount
allFixedIssues.push(...appliedIssues)
auto 模式下的决策登记表:
如果启用了决策登记表,candid-review 会在第 6 步(提出“需要澄清”问题之前)处理登记表查阅。在 auto 模式下:
- candid-review 会自动应用登记表中的先前决策——记录:
Applied prior decision (#N) for [file] - 新的“需要澄清”问题(没有先前答案)不会自动应用——这些问题需要人工输入,并在登记表中记录为
open - 这些问题在循环中视为“已跳过”——不会被计为阻止循环完成的剩余问题
- 输出:
Applied [N] prior decisions, skipped [M] new questions requiring clarification
跟踪登记表活动:
registerPriorDecisionsApplied += priorDecisionsCount
registerQuestionsRaised += newQuestionsCount
registerQuestionsResolved += resolvedCount
其中,resolvedCount 来自 candid-review 第 10.5 步的输出——它包含用户在阶段 8b 中回答的问题,以及重新审查时自动解决的问题。每次迭代后读取登记表文件,并与上一次读取结果进行比较,以统计新解决的条目。
继续下一次迭代。
如果 mode == "review-each":
逐一处理每项修复,并使用简单的“是/否”提示。
显示发现的问题:
[N/MAX] Found [M] issues. Reviewing each...
对于每个问题,使用 AskUserQuestion:
[1/M] [icon] [title]
File: [file]:[line]
Problem: [description]
问题:“应用此修复吗?”
选项:
- “是,应用此修复”
- “否,跳过此修复”
- “显示确切差异”——将修复以统一的修改前/后差异形式展示,基于当前文件内容,然后仅用“是/否”选项重新提问
跟踪用户选择:
- 如果选择“是”→ 应用修复,将 totalFixesApplied 加 1
- 如果选择“否”→ 继续处理下一个问题
处理完所有问题后,如果应用了任何修复,则继续下一次迭代。
如果 mode == "interactive":
完全控制模式,提供跳过、忽略和批量处理等更多选项。
显示发现的问题:
Found [M] issues:
对于每个问题,使用 AskUserQuestion:
[1/M] [icon] [title]
File: [file]:[line]
Problem: [description]
问题:“你希望如何处理此问题?”
选项:
- “应用修复” - 应用此修复并继续
- “跳过” - 跳过此问题并继续处理下一个
- “添加到忽略列表” - 将此问题 ID 添加到 ignored.ids 并跳过
- “跳过所有剩余问题” - 退出循环,并列出剩余问题
跟踪用户选择:
- 如果选择“应用修复”→ 应用修复,将 totalFixesApplied 加 1
- 如果选择“跳过”→ 继续处理下一个问题
- 如果选择“添加到忽略列表”→ 在配置中将 issue.id 添加到 ignored.ids,然后继续
- 如果选择“跳过所有剩余问题”→ 将 exitLoop 设为 true,并跳出内层循环
在 interactive 模式下处理完所有问题后,如果应用了任何修复,则继续下一次迭代。
第 3.7 步:更新忽略列表(如有请求)
如果用户为任何问题选择了“添加到忽略列表”:
- 读取当前的
.candid/config.json(如果不存在,则创建) - 将问题 ID 添加到
loop.ignored.ids数组 - 将更新后的配置写回文件
# Read, modify, write
jq '.loop.ignored.ids += ["issue-id-1", "issue-id-2"]' .candid/config.json > tmp.json
mv tmp.json .candid/config.json
输出:Added [N] issues to ignore list in .candid/config.json
第 4 步:显示摘要
循环退出后(成功或达到最大迭代次数),显示最终摘要:
Candid Loop [Complete|Stopped|Cancelled]
Summary:
- Iterations: [N]
- Issues fixed: [M]
- Status: [PASS|INCOMPLETE|CANCELLED]
如果为 INCOMPLETE:添加 Issues remaining: [P],并按 [icon] [title] in [file]:[line] 的格式列出剩余问题,另附提示:增加 --max-iterations、为误报添加持久忽略规则、手动审查复杂问题。
如果为 CANCELLED:添加 Issues skipped: [P] 并列出已跳过的问题。
决策登记表部分(启用登记表时添加到所有摘要版本):
如果配置中的 decisionRegister.enabled == true,则将此部分追加到所显示的摘要中:
Decision Register:
- Prior decisions applied: [N]
- New questions raised: [M]
- Questions resolved: [P]
- Open questions: [Q]
如果仍有未解决的问题:
Open questions can be reviewed at: [registerPath]/review-decision-register.md
配置
配置文件架构
添加到 .candid/config.json:
{
"version": 1,
"tone": "harsh",
"loop": {
"mode": "auto",
"maxIterations": 5,
"enforceCategories": ["all"],
"ignored": {
"categories": [],
"patterns": [],
"ids": []
}
}
}
字段说明
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
loop.mode | 字符串 | "auto" | "auto"、"review-each" 或 "interactive" |
loop.maxIterations | 数字 | 5 | 最大审查修复循环次数 |
loop.enforceCategories | 数组 | ["all"] | 要强制检查的类别 |
loop.ignored.categories | 数组 | [] | 完全跳过的类别 |
loop.ignored.patterns | 数组 | [] | 用于匹配问题标题的正则表达式模式(例如:["Unicode", "timezone"]) |
loop.ignored.ids | 数组 | [] | 要跳过的特定问题 ID |
CLI 示例
# Run with defaults (auto mode, all categories, max 5 iterations)
/candid-loop
# Combine flags
/candid-loop --mode review-each --max-iterations 10 --categories critical,major
问题类别参考
| 类别 | 图标 | 描述 |
|---|---|---|
critical | 🔥 | 生产环境致命问题:崩溃、安全漏洞、数据丢失 |
major | ⚠️ | 严重问题:性能、缺少错误处理 |
standards | 📜 | 违反 Technical.md 规范 |
smell | 📋 | 可维护性问题:复杂度、重复 |
edge_case | 🤔 | 未处理的场景:null、空值、并发 |
architectural | 💭 | 设计问题:耦合、违反 SRP |