Claim Check quickstart

Shipmoor Team
July 13, 2026
6 min read

A structural scan tells you a change is well-formed. Claim Check checks whether it did what the task actually asked, the question a linter can’t answer. It catches a change that claims to do one thing and quietly does another, and it says so plainly when it has no way to check an obligation at all, rather than guessing. This walkthrough takes about five minutes: sign in, write a small acceptance set, run your first claim check, and read both a real READY verdict and a real BLOCKED one.

1. Sign in

shipmoor version
# shipmoor 0.8.0

shipmoor login

login runs a device flow against the Console and stores a signed license token locally. Claim Check’s full mode, the one with a judge, needs the claim_check entitlement; sign in to unlock it. A plain structural scan never needs any of this. See Sign in & licensing for how the token works, and Plans & tiers for what each tier includes.

2. Write and approve an acceptance set

An acceptance set is a short list of atomic, plain-language obligations, “acceptance criteria,” that the change gets checked against. Scaffold a starter one:

shipmoor claim-check init

init writes a starter file to .shipmoor/acceptance.yaml. Open it and replace the placeholder with the obligations for this change:

goal: "Add a Stripe webhook handler for failed payments"

acceptance_criteria:
  - "A handler is bound to the Stripe payment_intent.payment_failed event."
  - "The webhook signature is verified before the handler runs."

This is author mode, the default: you write the acceptance set by hand, no model involved anywhere. (Skip this step and Claim Check can derive a starter set from your intent instead, by setting claim_check.authoring_mode to auto or hybrid in .shipmoor.yaml. What comes out is a draft at .shipmoor/acceptance.yaml.draft, not an approved set, until you’ve looked at it.)

Approval is nothing more than committing the file:

git add .shipmoor/acceptance.yaml
git commit -m "Add acceptance criteria for the failed-payment webhook"

Until you commit it, an otherwise clean run reads INCONCLUSIVE, not READY. A draft is never an approved pass. Once you do commit it, Claim Check pins it by hash so the intent can’t be swapped later without detection; more on that in Providing intent. See Reading the verdict for what each of the four verdicts means.

3. Run your first claim check

Pass the change’s intent as a one-line goal:

shipmoor claim-check . --intent-prompt "Add a Stripe webhook handler for failed payments (payment_intent.payment_failed)"

(The acceptance file’s own goal: line would also work as a fallback if you left this flag off; see Providing intent for the full precedence order.)

If the change actually wires the handler:

Intent: Add a Stripe webhook handler for failed payments (payment_intent.payment_failed)

Claim Check  READY  ·  exit 0  ·  policy v3
  ✓ A handler is bound to the Stripe payment_intent.payment_failed event.
  ✓ The webhook signature is verified before the handler runs.
VSA written: .shipmoor/claim-check.vsa.json

READY means every acceptance criterion held, checked against the diff itself, not against a description of the diff.

4. Watch it catch a miss

Now suppose the handler only pretends to do the job, say it logs the request body somewhere instead of processing the event. Run the exact same command against that change:

Claim Check  BLOCKED  ·  exit 1  ·  policy v3
  ✗ A handler is bound to the Stripe payment_intent.payment_failed event.
  ✓ The webhook signature is verified before the handler runs.
VSA written: .shipmoor/claim-check.vsa.json

Shipmoor caught the change that didn’t earn its claim: the badge reads BLOCKED, and the failing line names the exact obligation that wasn’t met, not a generic warning. The exit code follows the verdict directly, 1 here, the same signal a CI step would see.

Coverage, honestly. A criterion with no probe behind it yet isn’t guessed at or waved through. Shipmoor reports it as “not yet checked” and leaves it open rather than passing it by default. Honest silence, not a pass. See Reading the verdict for how that interacts with the verdict.

5. The fully deterministic path: —floor-only

Every run above already used the deterministic floor: check adapters that read a git ref, a command’s exit code, a test pattern, nothing that calls a model. Pass --floor-only when you want a guarantee that stays true, which is what you want in CI:

shipmoor claim-check . --floor-only --intent-prompt "Add a Stripe webhook handler for failed payments (payment_intent.payment_failed)"

--floor-only and --agent are mutually exclusive: the entire point of floor-only is that no judge runs. What you get back is a reproducible verdict from a frozen acceptance set and a fixed evidence set, same inputs, byte-identical verdict, every time. See Turning on the gate for wiring this into a merge check, and Plans & tiers for what each tier includes.

6. Optional: bring a judge

Both criteria above happened to have a deterministic probe behind them. Plenty of real obligations don’t; they’re judgment calls a probe can’t decide mechanically, and the floor is honest about that rather than guessing, reporting them as not yet checked instead. For those, you can opt in to a judge built from your own coding agent:

shipmoor claim-check . --agent claude --intent-prompt "Add a Stripe webhook handler for failed payments (payment_intent.payment_failed)"

Your own toolchain is the oracle here, not Shipmoor. Shipmoor binds the obligation to a check, runs it, and records the outcome. The judge can BLOCK by citing a specific divergence, or ABSTAIN and route to a human; it never hands back a passing verdict on its own, so any READY you see always rides the deterministic floor underneath it. claude is the only bare preset with a built-in invocation; point --agent at a raw command to run any other coding-agent CLI. See BYO-Judge.

Next

Last updated on July 13, 2026

Was this article helpful?

Your response is saved on this device.

Related Articles