Skip to content

doramirdor/skeptic

Repository files navigation

skeptic

A second opinion before Claude writes the code.

evals license claude code

Skeptic intercepting a plan and returning three objections

Skeptic intercepts Claude Code's plan mode and gives you up to three objections from a senior engineer who has seen this idea fail before. If the plan is fine it stays quiet. That's the whole product.

claude plugin marketplace add doramirdor/skeptic
claude plugin install skeptic@skeptic

Free. Open source. Runs locally. No account.

Why this exists

Coding agents will do what you ask. They will install the dependency. They will write the form. They will build the abstraction. They will not stop to ask whether the thing you asked for is the thing you actually want.

A senior engineer would. They would say: you do not need a custom CheckoutForm, Stripe ships one. You do not need a fetch wrapper, you already import axios. You do not need GraphQL, you have three slow endpoints. They would say it in a sentence and you would change your mind.

Skeptic is that sentence.

How it works

  1. You enter plan mode in Claude Code (Shift+Tab cycles, or --permission-mode plan).
  2. Claude makes a plan and calls ExitPlanMode to present it.
  3. Skeptic intercepts the call via a PreToolUse hook, spawns a fresh Claude session with the critic prompt, and feeds it the plan plus a small context bundle (CLAUDE.md, your package manifest, recent diffs).
  4. The critic returns 0–3 objections. If proceed, the hook exits silently and the plan runs. If object, the hook blocks the call and hands the objections back to Claude, which revises.

Everything runs on your machine. The only network call is the one your Claude Code session already makes.

Install

Plugin (recommended)

claude plugin marketplace add doramirdor/skeptic
claude plugin install skeptic@skeptic

Verified end-to-end: claude plugin validate passes and the PreToolUse hook loads with no model-context cost.

Settings.json (stable fallback)

If the plugin manager isn't available or you want to pin a fork:

git clone https://github.com/doramirdor/skeptic ~/.skeptic-src

Then add to ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "ExitPlanMode",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.skeptic-src/hooks/on_plan.py"
          }
        ]
      }
    ]
  }
}

No SKEPTIC_BACKEND needed — the hook auto-detects (see below).

Auth: auto-detected

Skeptic picks a backend for you — no configuration needed.

Backend Auth Latency Picked when
api ANTHROPIC_API_KEY ~3–5s that env var is set
cli Your Claude Code subscription ~30–90s it isn't — works for every Claude Code user

A subscription-only user with no API key gets the cli backend automatically, so Skeptic does something useful the moment it's installed. Set SKEPTIC_BACKEND=api or SKEPTIC_BACKEND=cli to override.

Modes

Every mode runs the same critic against the same plan. They only differ in voice. The 1–3 objection cap, the 90-token limit, the JSON contract, and the "return [] if the plan is fine" rule apply to every mode.

/skeptic <name> What it sounds like
default Senior engineer, fifteen years in. Tired but not mean.
harsh Same engineer, has had a bad week. Will not soften.
karen Performative complaint voice. Asks to speak to whoever scoped this.
stoic Marcus Aurelius. Short, declarative, no adjectives.
shakespeare Iambic pentameter. The objection still has to be correct.
axios Grounds every objection in your own codebase.
/skeptic harsh        # switch mode (persists in ~/.skeptic/config.json)
/skeptic off          # pause for the session
/skeptic on           # resume
/skeptic stats        # how often did Skeptic object this week
/skeptic last         # replay the last objection in full

What gets sent to the model

Field Source
user_request most recent user message from the transcript
plan the plan arg passed to ExitPlanMode
project_context.claude_md <cwd>/CLAUDE.md, capped at 4KB
project_context.package_manifest first match of package.json, pyproject.toml, Cargo.toml, go.mod, Gemfile
project_context.recent_diff git diff HEAD~5..HEAD --stat, capped at 2KB
mode SKEPTIC_MODE env var or ~/.skeptic/config.json

The 3-second git diff timeout means non-git directories add no latency. Skeptic is fail-open: any error path (missing API key, network failure, timeout, malformed model output) lets the plan proceed and logs to ~/.skeptic/debug.log. A broken Skeptic is invisible, not annoying.

Eval suite

The critic prompt is 80% of the product, so it has tests.

pip install anthropic
python evals/run.py                          # api backend, ANTHROPIC_API_KEY
python evals/run.py --backend cli            # uses your Claude Code subscription
python evals/run.py --seeds stripe-payments  # one seed at a time

The 8-seed suite covers dependency bloat, reinventing-paid-services, scope creep, expand-contract migrations, and two proceed cases. Current suite-level proceed-rate: 25%, dead center of the 20–35% target band from critic.md. See evals/README.md for the scoring rubric and the four prompt-degradation regressions the suite is designed to catch.

Contributing

The highest-leverage contribution is a new mode.

  1. Add prompts/modes/<your-mode>.md — a single overlay file describing the voice. Keep it short; the base prompt does the heavy lifting.
  2. Add the mode name to the list in critic.md.
  3. Add at least one seed in evals/seeds/ that exercises the new mode.
  4. Open a PR.

See CONTRIBUTING.md for the full guide, including how to add seeds and how to debug the hook locally.

License

MIT. See LICENSE.

About

A senior-engineer second opinion that intercepts Claude Code's plan mode and produces up to three sharp objections before any tool runs.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages