Skip to content

Grounded Self-Review Loop — User Guide

What it is: an integrated quality loop that runs before Claude hands you a plan or findings. It self-checks the result against a fixed 5-point contract — grounded, no fabrication, simplest that works, consistent, verified-by-execution — and appends a short Self-Review Ledger so you can see the checks happened. It exists so you stop having to repeat "make it fact-based, don't fabricate, don't overcomplicate, ground it in the data, and actually test it" after every plan.

Where it lives: - Always-on (Tier 0): CLAUDE.md §8 — fires automatically, no command. - On-demand deep pass (Tier 1): /gp.claude/commands/gp.md.claude/skills/grounded-plan/SKILL.md.


Why this exists

The criteria were already in the project — scattered across the memory directives accuracy-consistency-no-fabrication, always-verify-dont-estimate, CLAUDE.md §7, and the backend grounding registry (backend/services/grounding/registry.py). What was missing was a loop that fires automatically and a visible receipt that it ran. This guide documents that loop.


The Grounded Output Contract (the 5 gates)

Every plan/finding is checked against:

Gate Meaning
1. Grounded Every number, file path, line, behavior claim, and spec traces to a file read, a tool/command output, or your message — including absence claims ("nothing does X"), which need a search that would have found it, or they count as fabrication.
2. No fabrication Anything that can't be verified is labeled unknown / not verified — never plausibly filled in.
3. Simplest that works Fewest files/abstractions that meet the intent; reuse existing services over new code; scope creep is flagged.
4. Consistent One canonical term per concept throughout.
5. Verified by execution Any claim that code builds/passes/behaves a certain way is backed by running the relevant check — never asserted. (See the verification gate below.)

The loop is draft → critique against the 5 gates → revise → run the targeted verification → repeat, capped at 2–3 passes (the cap is itself an anti-overcomplication guard).


How to read the Self-Review Ledger

At the bottom of a plan/findings you'll see a block like this (example — values illustrative):

Self-Review ✓ (2 passes)
- Grounded: _pa_scoring.py (cost dimension), component_power.assess_power — read, not recalled
- Verified: tsc + vitest paSelection.test.ts → pass (3 files)
- Unverified: QPA9126 current catalog presence — flagged, not assumed
- Simpler option considered: reuse the existing application_fit weight → chose reuse (no new code)
- Additivity: verified — paSelection.test.ts unchanged & green (claim-triggered; omitted when no additivity claim is made)

Read it in ~5 seconds: - Grounded — the sources behind the key claims. Spot-check one if you want. - Verified — the actual check that was run and its result (e.g. tsc + vitest → pass), or an honest not run (reason) / n/a — plan only. This is proof the claim was executed, not assumed. - Unverified — the honest gaps. This line is a feature: it surfaces what couldn't be confirmed instead of hiding it behind a confident guess. A clean grounded line plus a frank "unverified" line is exactly the trust signal that lets you skip the old "are you sure?" follow-up. - Simpler option considered — proof the overcomplication gate ran: what simpler path was weighed, and why it was kept or dropped.


The verification gate (gate 5)

The loop doesn't just claim something works — when a code change is involved, it runs the relevant check and reports the result. It's scoped to stay fast and honest:

  • Targeted, not blind. It runs the specific check for what changed — cd frontend && npx tsc --noEmit + the affected vitest file, or backend/venv/Scripts/python.exe -m pytest <path>, or the eval guard_replay (offline first) — not the whole suite every time.
  • Reads the nightly report first. Before re-running a full suite it checks test-reports/latest.md (the 4:30 AM self-test), so it doesn't redo work that's already green.
  • Loops on failure, capped. Fail → fix → re-run, up to ~3 attempts, then it surfaces the remaining failure honestly rather than hiding red or claiming a green it didn't see.
  • Concurrency-aware. With another session editing the tree, the full suite reflects their in-flight work too — so it prefers the targeted test for your files.
  • Plan-only is fine. If nothing's implemented yet, the gate just means the plan's Verification section lists concrete, runnable commands; the ledger shows Verified: n/a — plan only.
  • "Additive" must be proven, not asserted. If the output claims a change is additive or doesn't alter existing behavior, that's a behavioral claim too — the loop proves it (existing tests still pass unchanged, no call-site/flag/condense.py-keep-list trap fired) or relabels it a behavior change. This is claim-triggered: a deliberate bug fix or refactor should change behavior — there the proof flips to "the fix's test goes red→green with no collateral regression," and additivity is never demanded.

The three ways to use it

1. Just ask — Tier 0 is automatic

Your default. Type your request normally; the ledger comes back attached.

You: plan a fix for the PA selector picking oversized GaN bricks for WiFi

Claude: [plan] + a Self-Review Ledger.

You did nothing extra — the quality bar is already applied, and you have the receipt.

2. /gp <request> — deep pass from the start

For a high-stakes plan where you want independent eyes before you even see a draft.

You: /gp redesign the power-tree gate-bias sequencing

Claude: [runs independent verifier agents — claims-vs-files checker, fabrication hunter, simplicity critic, test-runner — then synthesizes] → plan + a fuller ledger showing what each verifier caught and what the tests reported.

3. /gp alone — deep-check a plan you already have

This replaces the old habit of typing "are you sure this is all grounded, not overcomplicated, and actually tested?" — now it's two characters.

Claude: [normal Tier-0 plan + ledger]

You: /gp

Claude: [re-runs the deep adversarial pass + targeted tests on that same plan] → revised plan + what the independent check changed.

Quick reference

Situation What you do
Normal work nothing — just ask (Tier 0 auto-fires)
"This one's important, get independent eyes" /gp <request>
"I like this plan but double-check it hard" /gp on its own

Before / after (the friction this removes)

Before:

You: plan a fix for X Claude: [plan] You: ok but make sure it's fact-based, you didn't fabricate those paths, you're not overcomplicating it, and you actually ran the tests

You sent that second message every time.

After (Tier 0):

You: plan a fix for X Claude: [plan] + Self-Review ✓ ledger with sources, test results, and honest gaps

You read the ledger and move on. The reminder is baked in.


When to reach for /gp

Tier 0 (self-review) is me checking my own work — strong at catching unsourced claims, needless complexity, and untested assertions, but a self-check has limits. Use /gp when: - the change is high-stakes (touches power/thermal/compliance physics, or a shared engine), - you want an independent agent to re-derive every claim from the files and run the tests, or - the plan is large enough that one set of eyes might miss a blind spot.

For everyday work, Tier 0 is enough — reaching for /gp on a two-line plan is its own kind of overcomplication.


Scope

Applies to plans, findings, audits, and substantive recommendations. It deliberately skips trivial factual answers and tiny edits — adding a ledger to "what's the port number?" would be ceremony, not value. The verification gate only runs when a code change is actually involved; pure plans show Verified: n/a — plan only.


FAQ

Does this replace the backend guardrails? No. The backend grounding registry + output_guard enforce grounding inside the product's agent loop. This loop is about how Claude Code reviews its own plans/findings for you. They share the same criteria (GROUNDED_CATEGORIES) but operate in different places.

Does it run the whole test suite every time? No — that would be slow and, with a sibling session active, would test their in-flight work too. It runs the targeted check for what changed and reads test-reports/latest.md before any full-suite run.

What if Tier 0 starts drifting? It's a CLAUDE.md directive, so it relies on the model honoring it; the visible ledger is the forcing function. If it ever drifts in practice, the fallback is a Stop hook — deliberately not built yet, to avoid premature complexity.

Can I rename /gp? Yes — it's just a short handle (grounded-plan). Edit .claude/commands/gp.md (and the skill reference) to whatever you prefer (/verify, /ground, …).