A Claude Code plugin — verification controls for agentic delivery

A report of success
is not evidence.

open source 20 skills 8 commands 5 agents 3 hooks 11 check gates built under its own rules

rigor applies change-enablement discipline to work done by agents. An agent's output is often well-formed and wrong at the same time — a green test run that exercised a stub, a figure restated instead of recomputed, a feature that compiles but was never wired in. Before "tests pass", "deployed", or "done" is accepted, the agent re-runs the real gate, recomputes from the raw source, and shows a negative control — and every irreversible step stays with a human.

claude — install
# in a Claude Code session
/plugin marketplace add hossainpazooki/rigor
/plugin install rigor@rigor
Why the premise holds

Well-formed and wrong at the same time.

Not a hypothetical. Three findings from applying the toolkit to its own repository — kept on the record rather than cleaned up.

handoff doc: 39 tests passing
Re-running the suite at that same commit gave 46. Every required field was present and the schema check was green — a schema check is a floor, never a verdict.
adversarial reviewer: 4 verdicts returned
2 of the 4 were incorrect rejections, caught only because the orchestrator re-ran the gates independently. A reviewer's verdict is a claim like any other.
multi-agent build: workers on cheap models
505 of 505 turns answered on the expensive orchestrating model — every call unpinned, silently inheriting the session's. Invisible in the run's own artifacts; now enforced by a gate.
The control under everything

Verification before acceptance.

Every other component is this one control applied to a bigger unit of delivery: a question, a build, a release's aftermath, a dataset.

load-bearing claim

A claim a decision rests on. "Tests pass" before a merge is load-bearing; a passing lint note is not. rigor spends its skepticism where a wrong claim is expensive.

negative control

A check that must fail when the thing it checks for is absent. A probe that would pass either way proves nothing — rigor calls that a vacuous probe and refuses to credit it.

Which command, when

What are you about to accept?

Pick the thing you're about to accept as done. rigor has one command for it — and a specific way of checking it.

recommendation
/rigor:verify-claim move: refute

source on GitHub ↗

↑ pick a symptom to see the exact command and what it actually does.

Segregation of duties

Three hooks run without being asked.

Two of them hold the boundary the whole design rests on: the agent proposes the irreversible step, a human runs it.

git-guard runs unasked

Blocks agent-initiated git history writes — including wrapped, flag-cluster and remote-side gh forms. The agent emits the command and a human runs it. Per-repository override: RIGOR_GIT_ALLOW=1. Friction that keeps the boundary visible, not a security boundary.

change-guard provisional

Refuses deploy-shaped commands — kubectl apply, helm upgrade, terraform apply, gh workflow run — unless a committed change record carries the required evidence, or a committed emergency-change record names who, when and why.

session-start runs unasked

Injects the toolkit pointer before the first claim is made, so the discipline is loaded rather than remembered.

What ships

Three roles, kept apart.

The agent proposes a change and its evidence; deterministic gates decide whether that evidence is sufficient; a human promotes anything irreversible. Some of rigor executes as code; the rest is judgment the agent applies inside your repository, against your gates.

Executes as code

3 hooks + 11 check scripts, all under node --test

  • git-guard, change-guard & session-start hooks
  • check-surface-scrub — no project fingerprints leak into shipped examples
  • check-citation-fidelity — every cited identifier/quote exists in its named source
  • check-effect-probe — effect credited only if the probe passed and the negative control failed
  • check-fanout — a multi-agent workflow carries a contract, integration step, and verify phase
  • check-dispatch — every verifier dispatch logged its stakes; floors held; no silent downgrades
  • check-tier-placement — every non-verify agent() call carries a real tier pin
  • check-tier-sync — agent frontmatter agrees with config/models.json
  • check-learnings — ledger entries anchored, append-only, index↔folder consistent
  • check-runlog — a run-log entry carries its invariant core and a re-verification pointer
  • check-misfire-closure — a closure carries the evidence it claims; an open one halts
  • check-change-record — the deployment properties, in form (provisional)

Applied as judgment

20 skills · 8 commands · 5 agents

  • refute — the core move, specialized per unit
  • implemented-vs-planned — built / in-progress / planned, tagged
  • fanout-build & fanout-recon-synthesize — multi-agent work with gates
  • verify-the-effect — probe the state an action left behind
  • judgment-dispatch — which model tier runs each verifier
  • gate-discipline, orchestrate, pick-up + the data-engineering four
  • skeptic, prober, integration & cartographer agents
Deliberately not shipped — a turnkey validator. A checker that certified artifacts whose schema it cannot know would itself be unverified (ADR-0002 ↗).
Model-tier dispatch

The expensive model, exactly where it counts.

A check is only as strong as the model running it — and premium tokens are exactly what you don't want to spend on a lint note. Verifiers route across a premium judgment tier and a cheap tier via an explicit stakes rubric the orchestrator must apply and log before every dispatch. Builders never get the judgment tier: it's never spent writing the code it will later have to judge.

The hazard is rigor's own self-report problem inside its dispatch: stakes are inferred by the same agent whose claims are being checked — an agent that under-rates stakes buys itself cheap verification exactly where the strong skeptic matters most. Three mechanical answers:

The inference is itself a logged, refutable claim.

Every dispatch records which rubric criteria fired; check-dispatch fails closed on an unlogged one — and a high-stakes marker paired with a cheap-tier verifier is flagged even when the declared stakes say "low".

Floors are beyond inference's reach.

Floored nodes — the effect-verdict cross-check, the pre-publish honesty check — always get the judgment tier, listed in config/models.json and enforced by the gate, not by prose.

Downgrades are never silent.

The verdict logs the requested and the answering model; a substitution without downgraded: true fails the gate. Model churn is a config edit, not a prose hunt.

Worked example

A fan-out build, with rigor loaded.

A feature too big for one pass. Every step exists because a specific failure happens without it.

00Spike — does the riskiest unknown build?

If no: HALT — fix the base first. No stage advances past a red gate.

01Contract — one shared source of truth

Exact interfaces plus a file→owner map. The contract is what keeps parallel agents from drifting apart; disjoint file ownership is what keeps them from colliding.

02Scaffold — shared files compile as stubs

Then builders fan out in parallel: agent per file, each on the build tier.

03Integration gate — the real gate, run to green

The integration-runner returns verbatim output, not a self-report. Evidence instead of a summary.

04Skeptic pass — refute the claim, not the gate

Is the feature wired and reachable, or merely present? Skeptics are dispatched at the tier the stakes rubric earns. This catches the green-gate-but-unwired case.

05You re-run the load-bearing gate yourself

A workflow saying "done" is a claim, not a result — exactly the kind this plugin refuses to trust.

06git-guard — the agent emits commit commands, the human runs them

Your git history stays yours, by construction.

07Shipped irreversibly? verify-the-effect

Probe the state the action left behind, paired with a negative control — never the action's own exit log.

Data-engineering layer

The same move, aimed at data.

Each skill names a failure that leaves the pipeline green while the data is wrong.

data-quality-fail-closed

failure: unevaluable coerced into pass

A data-quality check has three outcomes: pass, fail, and unevaluable — the check itself couldn't run. Fail-closed means unevaluable halts the pipeline instead of being silently coerced.

no-lookahead

failure: the leak appears only on corrections

In point-in-time data, no row may depend on information timestamped after that row's moment. Tested with a restatement — append-only test data can pass while the same code leaks on late corrections.

idempotent-restatement

failure: run twice, count twice

Running the pipeline twice must not double-count; same-key records resolve by an explicit, tested tiebreak. Proven by running twice and diffing, not asserted.

lineage-replay

failure: "reproducible" is remembered, not checked

"We can reproduce this dataset" is only true if the replay is re-executed and diffed; every published batch carries a content-addressed identity so "same input" is checkable.

Newest layer — proposed

Has the change earned the right to proceed?

The layer sits upstream of post-implementation verification — before the irreversible step, not after. rigor is the control at the change-approval step; it is not the pipeline, the change advisory board, the deploy executor, or an SRE platform.

Proposed 2026-08-22, and not yet validated. Fixture-tested, with no independent codebase and no live run — every part of it stays provisional until it has been shown to reject a known-bad change in a real repository. The design's first draft was rejected by three independent reviewers and its first build by nine; what ships is what survived five review rounds (the decision ↗).
Play with it

Audit a claim before you trust it.

Think of the last "done" an agent handed you. Check what actually happened — the verdict updates live, the way rigor's discipline would call it.

claim.audit
REJECTED
evidence score 0 / 100
⚠ vacuous probe — the probe passed but no negative control failed. A check that passes either way proves nothing; probe credit withheld.

Nothing verified. Whatever this claim looks like, right now it's a correct-shaped lie candidate.

next → /rigor:verify-claim — recompute from the source and re-run the real gate before believing anything.
Engineering, not hype

Status: what's proven, what isn't.

rigor applies its own standard to itself. Every component is provisional until the promotion ledger records it surviving ≥2 independent domains. "Settled (scoped)" means settled for the named scope only — unproven reach kept visible.

ComponentKindStatusThe honest caveat
refuteskill settled · scoped 2 domains, for numeric provenance + citation fidelity; reach over semantic / design / omission defects unproven.
skeptic-verifieragent settled 1 logged misfire — 2/4 false refutations on its one independent fan-out domain, caught only by the orchestrator's own re-run.
fanout-buildskill settled · scoped 2 independent domains end-to-end; same operator both times, second domain smaller with an unstressed verify phase.
effect-proberagent settled · scoped 3 non-vacuous probes, self-verified; no independent oracle, no genuine live irreversible action yet.
judgment-dispatchskill provisional Pin mechanism live-verified with a non-vacuous probe; the rubric hasn't survived an independent domain yet.
data-eng skills ×4skills provisional No independent data-eng domain survived yet.
everything elsecommands · hooks · gates provisional Each with its logged limits — e.g. check-citation-fidelity is insufficient for numeric provenance.

The misfires stay in the table on purpose — a verification toolkit that hides its own false refutations would be its own counterexample. Full dated entries live in the promotion ledger.

Install

Stop accepting the report.

Two commands in a Claude Code session. The controls load before the first claim is made.

claude — install
/plugin marketplace add hossainpazooki/rigor
/plugin install rigor@rigor