From candid
Loops candid-review to iteratively apply fixes and re-review code until issues resolved, with auto, review-each, or interactive modes and config support.
npx claudepluginhub ron-myers/candid --plugin candidThis skill uses the workspace's default tool permissions.
Run `candid-review` repeatedly until your code is clean. This skill automates the fix-review-fix cycle, applying fixes and re-running reviews until no issues remain (or max iterations is reached).
Orchestrates implement-analyze-fix loops: implements code, AI-reviews changes, fixes issues, repeats until clean or max iterations. For iterative development with quality checks.
Iteratively reviews code for critical issues with code-reviewer, auto-fixes via fixer agent, verifies tests pass, repeats up to 5 cycles until clean.
Automates codex CLI code review remediation: classifies P0-P4 findings, fixes P0/P1 iteratively up to 3 cycles, defers P2-P4 to backlog, handles monorepos. Triggered by 'codex review'.
Share bugs, ideas, or general feedback.
Run candid-review repeatedly until your code is clean. This skill automates the fix-review-fix cycle, applying fixes and re-running reviews until no issues remain (or max iterations is reached).
Execute these steps in order:
Load loop configuration from CLI flags and config files.
Precedence (highest to lowest):
.candid/config.json → loop field)~/.candid/config.json → loop field)Parse CLI arguments for loop options:
| Flag | Description | Default |
|---|---|---|
--mode <auto|review-each|interactive> | Execution mode | auto |
--max-iterations <N> | Maximum loop iterations | 5 |
--categories <list> | Categories to enforce (comma-separated) | all |
Valid modes:
auto - Automatically apply all fixesreview-each - Go through each fix one by one (Yes/No for each)interactive - Full control with skip, ignore, and batch optionsValid categories: critical, major, standards, smell, edge_case, architectural, all
If CLI flags are provided, use them and skip config file checks for those specific options.
Read .candid/config.json and extract the loop field:
jq -r '.loop // null' .candid/config.json 2>/dev/null
If the loop field exists:
mode if not set by CLImaxIterations if not set by CLIenforceCategories if not set by CLIignored object (categories, patterns, ids)Output when loading from config: Using loop settings from project config
Same procedure for ~/.candid/config.json if project config doesn't have loop field.
Output when loading from user config: Using loop settings from user config
For any options not set by CLI or config:
mode = "auto"
maxIterations = 5
enforceCategories = ["all"]
ignored = { categories: [], patterns: [], ids: [] }
Set up tracking variables:
iteration = 0
totalFixesApplied = 0
allFixedIssues = []
registerQuestionsRaised = 0
registerQuestionsResolved = 0
registerPriorDecisionsApplied = 0
Display mode banner:
Auto mode:
[Auto Mode] Running candid-loop with max [N] iterations...
Review-each mode:
[Review-Each Mode] Running candid-loop with max [N] iterations...
You will review each fix one by one.
Interactive mode:
[Interactive Mode] Running candid-loop with max [N] iterations...
Full control: skip, ignore, or batch process fixes.
Execute the main loop:
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
Display iteration header:
[Iteration [N]/[MAX]]
Running candid-review...
Invoke the candid-review skill to analyze current code:
/candid-review.candid/last-review.jsonNote: candid-review will present its own fix selection prompt. In auto mode, we need to handle this by selecting "Apply all fixes". In interactive mode, we defer to the user's choices within candid-review.
Decision Register: If the decision register is enabled in config, each candid-review iteration reads and updates the register file independently. This means:
After candid-review completes, read the saved review state:
cat .candid/last-review.json 2>/dev/null
Parse the JSON to extract:
issues array with all found issuesid, file, line, category, title, descriptionIf file doesn't exist or is empty:
No review state found. candid-review may not have completed.
Exit with error.
If enforceCategories is NOT ["all"]:
Filter the issues array to only include issues matching enforceCategories:
filteredIssues = issues.filter(issue =>
enforceCategories.includes(issue.category)
)
Category mapping:
critical → issues with category "critical"major → issues with category "major"standards → issues with category "standards"smell → issues with category "smell"edge_case → issues with category "edge_case"architectural → issues with category "architectural"Output: Enforcing categories: [list]. Filtered to [N] issues.
Apply the ignored filters from config:
1. Filter by ignored categories:
filteredIssues = filteredIssues.filter(issue =>
!ignored.categories.includes(issue.category)
)
2. Filter by ignored patterns (regex match on title):
filteredIssues = filteredIssues.filter(issue =>
!ignored.patterns.some(pattern =>
new RegExp(pattern, 'i').test(issue.title)
)
)
3. Filter by ignored IDs:
filteredIssues = filteredIssues.filter(issue =>
!ignored.ids.includes(issue.id)
)
If any issues were filtered:
Filtered out [N] ignored issues ([M] remaining)
If filteredIssues.length === 0:
[Iteration [N]/[MAX]] No issues found!
exitLoop = true
Skip to Step 4 (Summary).
If mode == "auto":
Display found issues:
[N/MAX] Found [M] issues. Applying fixes...
The candid-review skill will have already applied fixes if the user selected "Apply all fixes" in its prompt. Since we're in auto mode, we should have configured candid-review to auto-apply.
For each issue that was fixed, log:
✓ [icon] Fixed: [title] in [file]:[line]
Track fixes:
totalFixesApplied += appliedCount
allFixedIssues.push(...appliedIssues)
Decision Register in auto mode:
If the decision register is enabled, candid-review handles register consultation during its Step 6 (before raising Clarification Needed questions). In auto mode:
Applied prior decision (#N) for [file]open in the registerApplied [N] prior decisions, skipped [M] new questions requiring clarificationTrack register activity:
registerPriorDecisionsApplied += priorDecisionsCount
registerQuestionsRaised += newQuestionsCount
registerQuestionsResolved += resolvedCount
Where resolvedCount comes from candid-review's Step 10.5 output — it includes questions answered by the user during Phase 8b and auto-resolutions from re-review. Read the register file after each iteration to count newly resolved entries compared to the previous read.
Continue to next iteration.
If mode == "review-each":
Go through each fix one by one with simple Yes/No prompts.
Display found issues:
[N/MAX] Found [M] issues. Reviewing each...
For each issue, use AskUserQuestion:
[1/M] [icon] [title]
File: [file]:[line]
Problem: [description]
Question: "Apply this fix?"
Options:
Track user choices:
After processing all issues, if any fixes were applied, continue to next iteration.
If mode == "interactive":
Full control mode with additional options for skipping, ignoring, and batch processing.
Display found issues:
Found [M] issues:
For each issue, use AskUserQuestion:
[1/M] [icon] [title]
File: [file]:[line]
Problem: [description]
Question: "How would you like to handle this issue?"
Options:
Track user choices:
After processing all issues in interactive mode, if any fixes were applied, continue to next iteration.
If user chose "Add to ignore list" for any issues:
.candid/config.json (or create if doesn't exist)loop.ignored.ids array# Read, modify, write
jq '.loop.ignored.ids += ["issue-id-1", "issue-id-2"]' .candid/config.json > tmp.json
mv tmp.json .candid/config.json
Output: Added [N] issues to ignore list in .candid/config.json
After loop exits (success or max iterations), display final summary:
Success (no issues remaining):
Candid Loop Complete
Summary:
- Iterations: [N]
- Issues fixed: [M]
- Status: PASS
Your code is clean!
Max iterations reached:
Candid Loop Stopped
Summary:
- Iterations: [N] (max reached)
- Issues fixed: [M]
- Issues remaining: [P]
- Status: INCOMPLETE
Remaining issues:
[icon] [title] in [file]:[line]
[icon] [title] in [file]:[line]
...
Consider:
- Increasing --max-iterations
- Adding persistent ignores for false positives
- Manually reviewing complex issues
User cancelled (interactive mode):
Candid Loop Cancelled
Summary:
- Iterations: [N]
- Issues fixed: [M]
- Issues skipped: [P]
- Status: CANCELLED
Skipped issues:
[icon] [title] in [file]:[line]
...
Decision Register section (add to all summary variants when register is enabled):
If decisionRegister.enabled == true in config, append this section to whichever summary is displayed:
Decision Register:
- Prior decisions applied: [N]
- New questions raised: [M]
- Questions resolved: [P]
- Open questions: [Q]
If open questions remain:
Open questions can be reviewed at: [registerPath]/review-decision-register.md
Add to .candid/config.json:
{
"version": 1,
"tone": "harsh",
"loop": {
"mode": "auto",
"maxIterations": 5,
"enforceCategories": ["all"],
"ignored": {
"categories": [],
"patterns": [],
"ids": []
}
}
}
| Field | Type | Default | Description |
|---|---|---|---|
loop.mode | string | "auto" | "auto", "review-each", or "interactive" |
loop.maxIterations | number | 5 | Maximum review-fix cycles |
loop.enforceCategories | array | ["all"] | Categories to enforce |
loop.ignored.categories | array | [] | Categories to skip entirely |
loop.ignored.patterns | array | [] | Regex patterns to match issue titles |
loop.ignored.ids | array | [] | Specific issue IDs to skip |
Ignore all edge cases and architectural issues:
{
"loop": {
"ignored": {
"categories": ["edge_case", "architectural"]
}
}
}
Ignore issues mentioning Unicode or timezone:
{
"loop": {
"ignored": {
"patterns": ["Unicode", "timezone", "DST"]
}
}
}
Only enforce critical and major issues:
{
"loop": {
"enforceCategories": ["critical", "major"]
}
}
# Run with defaults (auto mode, all categories, max 5 iterations)
/candid-loop
# Review-each mode - go through each fix one by one (Yes/No)
/candid-loop --mode review-each
# Interactive mode - full control with skip, ignore, batch options
/candid-loop --mode interactive
# Limit iterations
/candid-loop --max-iterations 3
# Only fix critical issues
/candid-loop --categories critical
# Fix critical and major issues
/candid-loop --categories critical,major
# Combine options
/candid-loop --mode review-each --max-iterations 10 --categories critical,major
| Category | Icon | Description |
|---|---|---|
critical | 🔥 | Production killers: crashes, security holes, data loss |
major | ⚠️ | Serious problems: performance, missing error handling |
standards | 📜 | Technical.md violations |
smell | 📋 | Maintainability: complexity, duplication |
edge_case | 🤔 | Unhandled scenarios: null, empty, concurrent |
architectural | 💭 | Design concerns: coupling, SRP violations |
The goal of candid-loop is to automate the review-fix cycle so you can quickly get your code to a clean state.
Mode selection:
Best practices: