gabe-review
Code review with risk pricing, confidence scoring, interactive triage, and deferred item tracking. Surfaces the cost of NOT fixing each finding. Usage: /gabe-review [target] or /gabe-review deferred
Gabe Review — Code Review with Risk Pricing
Purpose
Review code changes and price every finding — what it costs to fix now, what it costs to ignore, and what you're betting by deferring. Track deferred items across reviews and escalate when the same gap gets kicked down the road.
This is NOT a generic checklist review. Every finding gets a Defer Risk (consequence + probability) and a Maturity Gate (MVP/Enterprise/Scale). The output is a risk matrix with a Review Confidence Score that lets humans make informed ship/defer decisions — and an interactive Triage loop to resolve findings on the spot.
When to Use
Use when:
- You're about to open a PR and want to understand what you're shipping
- A code review (CE:review, BMad, manual) approved with deferred items and you want to price the risk
- You want to see all accumulated deferred items and their escalation status
- You need to decide between "fix now" and "defer" with real risk information
- You want to fix findings interactively without leaving the review context (
/gabe-review fix)
Don't use when:
- You need deep multi-persona review (use CE:review or BMad code-review first, then /gabe-review post-review)
- You're assessing a proposed change before implementing (use /gabe-assess)
- You're looking for structural gaps in design (use /gabe-roast)
Required Inputs
1. Target — What to review
| Input Type | Example |
|---|---|
| Diff | git diff, git diff --staged, PR diff (default: staged + unstaged changes) |
| File(s) | /src/services/rateLimiter.ts |
| Folder | /functions/src/ |
| Post-review | Output from CE:review or BMad code-review (parses their findings and adds risk pricing) |
| Deferred | No target — shows only the deferred items dashboard |
If no target is provided, default to git diff HEAD (all uncommitted changes).
2. Maturity — What standard to apply
| Maturity | What it means | Default severity threshold |
|---|---|---|
| MVP | Prototype/early product — fix security and data loss, accept rough edges | Only CRITICAL blocks merge |
| Enterprise | Production with users — fix performance, error handling, monitoring | CRITICAL + HIGH block merge |
| Scale | Large-scale operations — fix optimization, edge cases, polish | CRITICAL + HIGH + MEDIUM block merge |
How maturity is determined (in order):
- Explicit argument:
/gabe-review --maturity enterprise - Read from
.kdbp/BEHAVIOR.mdmaturity field (if project has.kdbp/) - Ask the user
- Default: MVP (conservative — strictness goes up, not down)
Never auto-detect from test count or CI presence. Maturity is a human decision.
Review Process
Step 0.5: Load KDBP Context (if available)
If .kdbp/LEDGER.md exists, read the last 5 checkpoint entries. For each:
- If a value was CONCERN on a file that's in the current diff → note it as prior signal
- If a scenario was ❌ on a file that's in the current diff → pre-seed as expected finding
This means gabe-review knows what the automatic checkpoints already flagged. Prior signals add a FLAGGED (Nx) annotation to the finding (where N = number of checkpoint flags). If flagged 3+ times, bump severity by one tier (LOW→MEDIUM, MEDIUM→HIGH, HIGH→CRITICAL). Do not bump findings already at CRITICAL.
If no .kdbp/LEDGER.md exists, skip this step silently.
Step 1: Load Deferred Backlog
Before reviewing new code, check for existing deferred items:
- Look for
.kdbp/deferred-cr.mdor.planning/deferred-cr.md - If found, load all entries with
Status != Resolved - For each deferred item, check if the current diff addresses it:
- Match by file path (exact match)
- If file matches, compare Finding text with >50% word overlap
- If file was renamed (detected via
git diff --find-renames), match on Finding text alone with >70% overlap
- If addressed: mark as
Resolvedin the file (use Edit tool to update the table row) - If NOT addressed and the diff touches the same function or within 20 lines of the finding's original location: increment
Times Deferredand apply escalation rules. Changes elsewhere in the same file do NOT trigger escalation.
Step 2: Review the Diff
For each changed file, check these dimensions:
| Dimension | What to find | Default severity |
|---|---|---|
| Security | Injection, auth bypass, secrets, OWASP Top 10 | CRITICAL |
| Data integrity | Data loss, corruption, race conditions, missing validation | CRITICAL |
| Error handling | Unhandled exceptions, fail-open without test, swallowed errors | HIGH |
| Test coverage | New branches without corresponding test changes | HIGH |
| Logic | Off-by-one, null handling, wrong condition, unreachable code | HIGH |
| Performance | N+1 queries, unbounded loops, missing indexes, memory leaks | MEDIUM |
| Style | Naming, formatting, dead code, console.log in production | LOW |
Confidence gate: Only report findings with >80% confidence. If uncertain, investigate further before reporting.
Step 3: Branch-Test Gap Detection
For each modified source file:
- Check if it introduces new error handling (
try/catch,if (error), fallback logic,.catch() - Check if a corresponding test was also modified in the diff. Look for:
[filename].test.[ext]or[filename].spec.[ext](direct match)- Test files in
e2e/,__tests__/,tests/that import or reference the modified source module - Any test file in the diff that exercises the new branch (check import statements)
- If new branches exist without test coverage:
⚠️ TEST GAP: [file] adds [branch type] at L[line] — no test exercises this path.
Defer Risk: UNTESTED PRODUCTION PATH — P(high), Impact(high)
Step 3.5: Churn Annotation
For each file in the diff, check its recent churn:
git log --oneline --since=30.days --follow -- [file] | wc -l
| Churn (30d) | Label | Meaning |
|---|---|---|
| 8+ commits | 🔴 HOT | Fragile — changes constantly, defer risk amplified |
| 4-7 commits | ⚠️ WARM | Active area — watch for coupling |
| 0-3 commits | ✅ STABLE | Low risk of cascading issues |
The churn label appears in the findings table. A finding on a HOT file has higher effective risk than the same finding on a STABLE file — "untested path on a file that breaks every sprint" is worse than "untested path on a file nobody touches."
Step 4: Price Each Finding
Every finding gets these fields:
| Field | Description |
|---|---|
| # | Sequential number |
| Severity | CRITICAL / HIGH / MEDIUM / LOW |
| Finding | One-line description |
| File | file:line |
| Churn | 🔴 HOT / ⚠️ WARM / ✅ STABLE (from Step 3.5) |
| Fix Cost | T-shirt estimate: S (<30m), M (1-3h), L (3-8h), XL (>1d) |
| Defer Risk | [CONSEQUENCE] — P([probability]), Impact([severity]) |
| Maturity Gate | MVP / Enterprise / Scale — when this finding becomes relevant |
| Escalation | Empty for new findings, ⚠️ RECURRING (Nth time) for deferred items |
Defer Risk Scales
Probability (how likely the bad outcome is):
| Level | Meaning |
|---|---|
| certain | Will happen in normal usage |
| high | Likely under common conditions |
| medium | Possible under specific conditions |
| low | Unlikely but plausible |
| negligible | Theoretical only |
Impact (how bad when it happens):
| Level | Meaning |
|---|---|
| catastrophic | Data loss, security breach, complete failure |
| high | Major feature broken, user trust eroded |
| moderate | Degraded experience, workaround exists |
| low | Minor friction, cosmetic |
| negligible | Barely noticeable |
Risk score for sorting: Rank by probability first, then impact within same probability. In the Risk Dashboard, highest risk items appear first.
Step 4.5: Review Confidence Score
After pricing all findings, compute a Review Confidence Score (0–100). This tells the user: "how confident should you feel shipping this code as-is?"
Scoring Formula
Start at 100. Deduct per finding:
| Severity | Base deduction | HOT churn | ESCALATED (2+) |
|---|---|---|---|
| CRITICAL | −20 | ×1.5 | ×1.5 |
| HIGH | −12 | ×1.3 | ×1.3 |
| MEDIUM | −5 | ×1.2 | — |
| LOW | −2 | — | — |
Multipliers stack: a CRITICAL finding on a HOT file that's ESCALATED = −20 × 1.5 × 1.5 = −45.
Coverage confidence modifier (from existing coverage assessment):
| Coverage | Modifier |
|---|---|
| HIGH | 0 |
| MEDIUM | −5 |
| LOW | −10 |
| VERY LOW | −15 |
Floor: 0. Ceiling: 100.
Confidence Projections
After the score, show what happens if the user fixes findings at each tier. Each projection removes the deductions from findings that match the criteria:
| Projection | Which findings are removed from the score |
|---|---|
| Fix CRITICAL + HIGH | All findings with severity CRITICAL or HIGH |
| Fix all MVP gate | All findings with Maturity Gate = MVP |
| Fix all Enterprise gate | All findings with Maturity Gate = MVP or Enterprise |
| Fix all (including Scale) | All findings (score → 100 minus coverage modifier) |
Multiplier handling: Projections remove the full multiplied deduction of each matching finding (including churn and escalation multipliers), not just the base severity deduction.
Output Format
### Review Confidence
Score: 62 / 100
| If you fix... | Findings resolved | Projected | Δ |
|---------------|-------------------|-----------|---|
| All CRITICAL + HIGH | 4 of 9 | 78 / 100 | +16 |
| All MVP gate | 5 of 9 | 85 / 100 | +23 |
| All Enterprise gate | 7 of 9 | 95 / 100 | +33 |
| All (incl. Scale) | 9 of 9 | 100 / 100* | +38 |
*Assumes HIGH coverage (modifier = 0). Actual ceiling: 100 minus coverage modifier.
Interpretation guide:
| Score range | Signal | Recommendation |
|---|---|---|
| 90–100 | Ship with confidence | Minor items can be deferred safely |
| 70–89 | Ship with awareness | Review the projections — a small fix effort may buy a lot of confidence |
| 50–69 | Caution | Significant risk exposure. Check which tier gives the best ROI |
| 0–49 | Do not ship | Critical gaps. Fix at minimum the CRITICAL + HIGH tier before proceeding |
The confidence score appears BEFORE the verdict — it informs the verdict but doesn't replace it.
Step 5: Triage
After the verdict and session estimate, present the triage prompt. This closes the gap between "here's what's wrong" and "let's fix it."
Entry Point
### Triage
N findings to resolve. Enter triage? [Y/n]
If the user declines, persist any findings above the maturity gate as deferred items and end. If the user accepts, enter the triage loop.
Triage Loop
Present findings grouped by file (not by severity), because fixes in the same file batch naturally. Within each file group, order by severity (CRITICAL first).
For each finding, show a compact card:
[1/5] HIGH — Missing fail-open test | rateLimiter.ts:88 | Fix: S (<30m)
Defer Risk: SILENT FAILURE — P(medium), I(high)
(f) Fix now (d) Defer (x) Dismiss (s) Skip for now (a) Fix all remaining
Actions
| Action | What happens |
|---|---|
| f — Fix now | Claude applies the fix immediately. For code changes: edit the file, show the diff. For test gaps: write the test. For doc issues: update the doc. After fix, re-validate and mark resolved. |
| d — Defer | Ask for optional justification. Write to deferred-cr.md with current date, finding details, and Times Deferred = 1 (or increment if recurring). Move to next finding. |
| x — Dismiss | Ask for one-line reason. Record dismissal in the review output (not in deferred backlog). Move to next finding. Dismissals don't persist across reviews — they're session-only decisions. |
| s — Skip | Leave in the findings table without deciding. At end of triage, un-skipped items get a final "defer or dismiss?" prompt. |
| a — Fix all | Apply fixes for all remaining findings in sequence without per-finding prompts. Show a summary diff at the end. Useful when the user trusts the fixes and wants to batch them. |
Fix Behavior
When the user picks Fix now, Claude should:
- Read the file at the finding's location (if not already in context)
- Apply the minimal fix — same constraints as normal editing (no scope creep, no bonus refactoring)
- Show the diff — so the user can see what changed
- Re-validate — check if the fix actually resolves the finding (e.g., does the test now exist? is the validation present?)
- Report result:
Fixed: [finding summary] — [file:line]orPartial fix: [what remains]
For findings that can't be auto-fixed (e.g., "needs architectural decision", "requires external input"):
This finding needs manual resolution: [reason].
Suggested approach: [one-liner]
(d) Defer (x) Dismiss
Fix All Behavior
When the user picks (a) Fix all remaining, Claude:
- Groups remaining findings by file (reduces file re-reads)
- Applies fixes in severity order within each file (CRITICAL first)
- After all fixes, shows a single batched summary:
Applied 4 fixes across 3 files: - rateLimiter.ts: #2 fail-open test, #3 error handling - vault-protocol.md: #1 schema count, #5 working type rules - Any finding that couldn't be auto-fixed is collected at the end:
1 finding requires manual resolution: - #4 concurrency model — needs architectural decision (d) Defer (x) Dismiss
Triage Summary and Score Update
After all findings are processed, show a compact summary with updated confidence score:
### Triage Complete
| Action | Count | Findings |
|--------|-------|----------|
| Fixed | 3 | #1 schema drift, #2 working type lifecycle, #5 quick capture fields |
| Deferred | 1 | #3 signal log granularity → deferred-cr.md |
| Dismissed | 1 | #4 concurrency model — "single-agent MVP, revisit at Scale" |
Review Confidence: 62 → 87 / 100 (+25)
### Final Verdict
[APPROVE|WARNING|BLOCK] — [reason, incorporating triage outcomes]
Deferred items written to .kdbp/deferred-cr.md
The post-triage score recalculates: fixed findings are fully removed from the deduction, dismissed findings count at 50% of their original multiplied deduction (acknowledged but unresolved risk), and deferred findings count at full deduction. The Final Verdict replaces the Provisional Verdict using the updated score and remaining finding state.
CRITICAL Finding Constraint
CRITICAL findings during triage cannot be deferred. The (d) option is disabled:
[2/5] CRITICAL — SQL injection via unsanitized input | api.ts:44 | Fix: S (<30m)
Defer Risk: DATA BREACH — P(high), I(catastrophic)
(f) Fix now (x) Dismiss (requires justification) (s) Skip for now (a) Fix all remaining
Edge Cases
| Situation | Behavior |
|---|---|
| All findings are LOW and below maturity gate | Still offer triage, but default prompt is "All findings below MVP gate. Defer all? [Y/n]" |
| User exits mid-triage (Ctrl+C, context limit) | Persist any already-deferred items. Un-triaged findings are NOT auto-deferred — they remain in the session output only. |
| Fix introduces a new issue | Don't re-review during triage. The fix-then-review loop is for the next /gabe-review run. |
| Finding references a file not in the workspace | Can't auto-fix. Offer defer/dismiss only. |
| Skipped CRITICAL at end of triage | CRITICALs cannot be deferred. At the final sweep, present only (f) Fix now or (x) Dismiss (requires justification). If the user skips again, auto-classify as Dismissed with note: "No resolution chosen — treated as acknowledged risk." |
Output Format
Full Mode (default)
## Gabe Review — Review Summary
**Maturity:** [MVP|Enterprise|Scale] | **Files:** N changed | **Deferred backlog:** N items
### Findings
| # | Severity | Finding | File | Churn | Fix Cost | Defer Risk | Gate | Escalation |
|---|----------|---------|------|-------|----------|------------|------|------------|
| 1 | CRITICAL | [description] | file:line | 🔴 HOT | S | [consequence] — P(x), I(y) | MVP | |
| 2 | HIGH | [description] | file:line | ✅ | M | [consequence] — P(x), I(y) | MVP | ⚠️ RECURRING (2nd) |
| ... | | | | | | | |
### Risk Dashboard (All Pending)
Items from this review + unresolved deferred backlog, ordered by risk:
| # | Source | Age | Finding | File | Defer Risk | Escalation |
|---|--------|-----|---------|------|------------|------------|
| D1 | [review name] | N days | [description] | file | [risk] | [status] |
| ... | | | | | | |
### Coverage Confidence
Before producing the verdict, assess coverage confidence:
| Condition | Coverage | Effect |
|---|---|---|
| All changed source files have corresponding test changes | HIGH | No cap |
| Some test gaps exist but none on error handling paths | MEDIUM | No cap |
| Test gaps exist on error handling / fail-open / fallback paths | LOW | Verdict capped at WARNING |
| Multiple untested branches on HOT files | VERY LOW | Verdict capped at BLOCK |
Format in output:
Coverage: LOW (2 untested error-handling branches) — verdict capped at WARNING
### Review Confidence
Score: [0-100] / 100
| If you fix... | Findings resolved | Projected | Δ |
|---------------|-------------------|-----------|---|
| All CRITICAL + HIGH | X of N | XX / 100 | +XX |
| All MVP gate | X of N | XX / 100 | +XX |
| All Enterprise gate | X of N | XX / 100 | +XX |
| All (incl. Scale) | N of N | XX / 100 | +XX |
### Verdict (Provisional)
[APPROVE|WARNING|BLOCK] — [reason]
*This verdict is based on findings as-is. Triage decisions below may change it.*
- APPROVE: No CRITICAL, no ESCALATED deferrals above maturity gate, coverage confidence ≥ MEDIUM, review confidence ≥ 70
- WARNING: HIGH findings within maturity tolerance, OR coverage confidence LOW (caps verdict), OR review confidence 50–69
- BLOCK: CRITICAL present, OR ESCALATED deferrals (2+ times), OR coverage VERY LOW, OR maturity gate exceeded, OR review confidence < 50
**Coverage vs confidence precedence:** The coverage verdict cap and confidence score are independent signals. When they conflict, the stricter result wins (e.g., coverage caps at WARNING but score < 50 → BLOCK).
### Session Estimate
Fixing [CRITICAL+HIGH]: ~Nh | Fixing all: ~Nh | Deferring [count]: risk exposure ≈ [summary]
### Triage
N findings to resolve. Enter triage? [Y/n]
Verdict finalization: The verdict shown before triage is PROVISIONAL. After triage completes, restate the Final Verdict incorporating triage outcomes (fixed items removed, dismissed at 50% weight, deferred at full weight). If the user declines triage, auto-defer findings above the maturity gate and restate the final verdict. If the user declines to track deferred items, the verdict cannot be APPROVE — downgrade to WARNING with note: "Deferred items not tracked — risk of invisible debt."
Brief Mode (/gabe-review brief)
Only the findings table + headline confidence score + verdict. No projection table, no interpretation guide, no dashboard, no session estimate, no triage. Format: Score: 62 / 100 | Verdict: WARNING — [reason]. In brief mode the verdict is final (not provisional) since triage is not offered.
Fix Mode (/gabe-review fix)
Runs the full review (Steps 0.5–4.5) then shows a compact pre-triage summary before auto-fixing:
Score: 48 / 100 (BLOCK) — 7 findings. Applying fixes...
Then enters triage with "(a) Fix all" pre-selected. Shows full triage summary with updated confidence score and Final Verdict at the end. For users who trust the review and just want everything patched.
Deferred-Only Mode (/gabe-review deferred)
Shows the Risk Dashboard table with current confidence impact of deferred items. Offers triage:
### Deferred Backlog — N items
| # | Age | Finding | File | Defer Risk | Times Deferred | Confidence cost |
|---|-----|---------|------|------------|----------------|-----------------|
| D1 | 26d | Missing IP skip test | suggestRecipes.ts:31 | P(high), I(high) | 2 ⚠️ | −18 pts |
| D2 | 26d | Missing fail-open test | rateLimiter.ts:88 | P(medium), I(high) | 1 | −12 pts |
| ...
Total deferred confidence drag: −XX pts
Tackle deferred items? [Y/n]
If yes, enter the same triage loop with (f)/(d)/(x)/(s) options.
Post-Review Mode (/gabe-review post-review)
Parse the most recent code review output in the conversation. Detect the source format and map findings:
| Source | Severity mapping |
|---|---|
| CE:review | P0→CRITICAL, P1→HIGH, P2→MEDIUM, P3→LOW |
| BMad code-review | decision_needed→HIGH, patch→by-dimension, defer→load into deferred backlog |
| ECC code-reviewer | CRITICAL→CRITICAL, HIGH→HIGH, MEDIUM→MEDIUM, LOW→LOW (same scale) |
| Manual/unknown | Infer from keywords (security→CRITICAL, performance→MEDIUM, style→LOW) |
Add Defer Risk + Maturity Gate + Confidence Score columns to each parsed finding. Present in the standard Gabe Review table format. After presenting findings, follow the full mode flow (confidence score with projections, provisional verdict, session estimate, triage).
Deferred Item Persistence
Written to .kdbp/deferred-cr.md or .planning/deferred-cr.md (first found, or create .kdbp/deferred-cr.md).
File format:
<!-- gabe-review:1.3 -->
# Deferred Code Review Items
| # | First Seen | Review | Finding | File | Defer Risk | Times Deferred | Status | Resolved |
|---|-----------|--------|---------|------|------------|----------------|--------|----------|
| D1 | 2026-03-10 | TD-2-9 | Missing IP skip test | suggestRecipes.ts:31 | UNTESTED PATH — P(high), I(high) | 2 | ⚠️ ESCALATED | |
| D2 | 2026-03-10 | TD-2-9 | Missing fail-open test | rateLimiter.ts:88 | SILENT FAILURE — P(medium), I(high) | 1 | Resolved | 2026-04-06 |
Persistence protocol: Use the Edit tool to update individual rows. Read the file → find the row by # → update Status, Times Deferred, and Resolved date → write back. If file doesn't exist, create it with the Write tool including the <!-- gabe-review:1.3 --> version header.
Triage Persistence
When a finding is fixed during triage:
- If it existed in deferred backlog: mark
Status: Resolvedwith today's date in theResolvedcolumn - Log which review resolved it
When a finding is deferred during triage:
- If new: add row with
Times Deferred: 1,Status: Deferred - If recurring: increment
Times Deferred, apply escalation rules (existing logic)
When a finding is dismissed during triage:
- NOT written to deferred backlog (dismissals are session-only)
- Noted in the triage summary output but not persisted
Escalation Rules
| Times Deferred | Status | Effect |
|---|---|---|
| 1 | Deferred | Shown in Risk Dashboard, no additional escalation multiplier on score |
| 2 | ⚠️ ESCALATED | Promoted to HIGH if was MEDIUM/LOW. Highlighted in findings. Confidence deduction uses ESCALATED multiplier. |
| 3+ | 🔴 BLOCKING | Treated as CRITICAL. Cannot approve until resolved or re-justified. |
Re-justification: When user explicitly provides NEW reasoning for why a deferral is acceptable (not just "defer again"), reset counter to 1 and append justification as a comment below the table row.
Integration with Gabe Suite
| Situation | This tool suggests |
|---|---|
| Finding has CRITICAL severity | Fix immediately, no deferral allowed |
| Finding has unclear blast radius | Run /gabe-assess on the finding before deciding |
| Multiple findings in same area | Run /gabe-roast [perspective] on that area |
| Alignment concern (wrong direction) | Run /gabe-align shallow to check values |
| Deferred item reaches 3+ deferrals | BLOCK. Suggest /gabe-roast qa for test coverage roast |
| KDBP checkpoint showed untested scenarios | Those scenarios become findings in gabe-review with severity HIGH |
| Review confidence < 50 | Suggest fixing CRITICAL+HIGH before proceeding. Show projection table. |
| Confidence jump ≥ 20 pts for a single tier | Highlight that tier as "best ROI" in the session estimate |