Troubleshooting

Shipmoor Team
July 13, 2026
10 min read

Common situations, what they look like, and what to do. Every message below is real shipmoor claim-check output. For the model this page assumes (the frozen acceptance set, the deterministic floor, and the judge), see What is Claim Check.

”requires entitlement ‘claim_check’” (the feature is locked)

$ shipmoor claim-check . --agent claude
shipmoor ic: requires entitlement 'claim_check'. IC features are available after sign-in; run `shipmoor login`.

Under --json you get the shipmoor.paid_feature_error.v1 contract instead. Both exit with code 2.

Fix: full mode (with --agent) is an IC feature. Sign in:

shipmoor login
shipmoor capabilities --json   # confirm .capabilities.claim_check.enabled == true

The entitlement is checked first. On a locked license, Shipmoor never imports the judge engine or spawns your agent. Floor-only mode (--floor-only, or just omit --agent) skips the judge entirely, and with it the code path this entitlement check guards. Whether floor-only itself requires sign-in on your plan is still being settled; check shipmoor capabilities --json, or see Plans & tiers, if you need a definite answer for your account.

”unknown_signing_key” (from-source-build case)

$ shipmoor claim-check .
shipmoor: license verification failed: unknown_signing_key

This appears when you are running a from-source build of Shipmoor and the license signature cannot be verified against the bundled signing key set. It is a build-time configuration issue, not a Claim Check bug.

Fix: run shipmoor doctor to confirm the install is intact, and shipmoor capabilities --json to see the entitlement state. If you built from source, install the official binary instead:

curl -fsSL https://dl.shipmoor.dev/install.sh | bash
shipmoor login

“Why did my run come back INCONCLUSIVE even though nothing looked wrong?”

The most common cause has nothing to do with your change. When no acceptance set is committed, Claim Check can auto-derive one, and it writes that derived set as a draft, at .shipmoor/acceptance.yaml.draft, not as the live .shipmoor/acceptance.yaml. An unapproved draft downgrades an otherwise-READY run to INCONCLUSIVE: the obligations exist, but nobody has signed off that they’re the right obligations yet.

Fix: read the draft, and once you agree it states the right obligations, approve it by promoting it to the live acceptance set and committing it with the change:

mv .shipmoor/acceptance.yaml.draft .shipmoor/acceptance.yaml
git add .shipmoor/acceptance.yaml

A committed acceptance file is the approved, author-mode form. Until one exists, every run is checking your change against a draft nobody has agreed to, which is exactly what INCONCLUSIVE is for: not a failure, and not a silent pass either.

”the judge didn’t run”

You passed --agent and the judge opinion does not appear in the output. The most common causes, in order:

  1. The intent confidence is low. The judge only runs at medium or high confidence. Add a second, agreeing intent source (--intent-ticket alongside --intent-prompt) to raise it. See Providing intent.
  2. No cannot_check acceptance criteria. The judge only adjudicates acceptance criteria the floor marked cannot_check. If the floor decided every one, there is nothing for the judge to do.
  3. No agent is configured, or the bare preset name doesn’t resolve. claude is the only bare preset with a built-in invocation; a bare codex or cursor fails fast with a usage error rather than silently skipping the judge (see the “agent command not found” section below), and with no --agent/review.agent at all, the judge simply abstains.
  4. --floor-only was passed. Floor-only mode skips the judge by design. Drop --floor-only to run full mode.

Diagnose with the trace sidecar:

shipmoor claim-check . --agent claude --trace-out .shipmoor/claim-check.trace.json

The trace carries, per acceptance criterion, why the judge did or did not run, and its rationale if it did.

”acceptance set malformed”

$ shipmoor claim-check .
shipmoor: acceptance set malformed: .shipmoor/acceptance.yaml: expected a top-level "acceptance_criteria" list, got mapping

Fix: the acceptance set must be a top-level list of acceptance criteria. Scaffold a known-good one with init and diff it against yours:

shipmoor claim-check init

The binary reads the acceptance set without a YAML dependency in the shipped artifact, so the parser is strict and the error messages are precise. Fix the structural issue the message names, then re-run.

”I wrote the test the fix packet asked for, but the obligation still isn’t satisfied”

When an acceptance criterion can’t be bound to an existing check, Claim Check prints a fix packet: a specific tag string it wants attached to a test. Two things trip people up here:

  • The match is an exact substring, not a fuzzy one. The tag string has to appear character for character somewhere in your test’s id or filename. A close paraphrase, a reworded test name, or the right idea captured only in a docstring does not bind. Copy the tag exactly as given.
  • The test has to actually distinguish base from head. The binder checks that your test fails at the base commit and passes at the head commit. A test that already passes before your change existed proves nothing about the change, and it will not bind to the obligation, even with the right tag attached.

Shipmoor is not the oracle here; your test is. Claim Check binds the obligation to that test, runs it at both commits, and records what happened. If the test doesn’t move from failing to passing across the change, there’s nothing to record a pass from. See Using Test Evidence with Claim Check for how a bound test’s result across commits becomes evidence Claim Check consumes.

”the judge agent preset has no built-in command”

$ shipmoor claim-check . --agent cursor
shipmoor: the judge agent preset 'cursor' has no built-in headless-JSON command for the intent-fidelity judge; pass a raw command instead, for example --agent "claude -p" (a print-mode CLI that answers a prompt with JSON).

This is exit 2 (a usage error: the judge never ran). claude is the only bare token with a built-in invocation today; codex and cursor are deliberately excluded rather than guessed at, because their headless review commands aren’t yet an established judge invocation, and a wrong guess would be worse than a clear failure.

Fix: use the claude preset, or point --agent at the raw command for whatever agent you want to drive (for example --agent "claude -p", or your own wrapper script), as long as it implements the wire contract. A raw command (anything with a space or a path in it) is never remapped, so it runs exactly as given.

A related but different error, shipmoor: judge agent not found: '…', means the resolved command itself couldn’t be launched: a typo, a binary not on PATH, or a script that isn’t chmod +x. Fix the command, not the preset name.

The judge “failed” (exit 3: the agent ran but the run failed)

$ shipmoor claim-check . --agent "my-agent"
Claim Check — failed
judge failed: all adjudications failed — check your LLM configuration and API key

Exit 3 is an operational failure (distinct from the exit-2 “not found” above): the judge launched but every adjudication failed. Common causes: the judge returned malformed JSON or an empty choices array, exited non-zero, wrote non-UTF-8 to stdout, or exceeded the timeout on every acceptance criterion. The ones the judge could not adjudicate stay cannot_check. The floor verdict is unaffected.

”Why does my CI build fail now when it didn’t before?”

shipmoor claim-check maps BLOCKED and INCONCLUSIVE to a non-zero exit code unconditionally. There is no policy flag that makes this conditional: if a CI step runs the command and something checks its exit code, that step fails the moment the verdict is BLOCKED or INCONCLUSIVE, whether or not that was the intent when the step was added.

Fix, if you wanted a signal rather than a gate: don’t let your merge check consume this command’s exit code directly. Run it as a separate step instead, guarded so its result can’t fail the job:

shipmoor claim-check . || true

Read the verdict from the VSA or the JSON output in that case, rather than from the job’s pass/fail state. See CI integration for the full pattern, including which step should stay a real gate.

Large diffs and slow runs

A claim check runs per acceptance criterion with a worker pool. If runs are slow or time out:

  • Narrow the change: check a tighter selection (--staged, a smaller --from / --to range, or --diff <spec>) instead of the whole working tree or --all.
  • Run floor-only (--floor-only) to skip the judge entirely; this is the fastest path and is what most CI gates run.
  • If you run the judge, raise the per-acceptance-criterion timeout in your config (claim_check.timeout).

”Why didn’t the judge pass my change?”

By design. The judge is monotonic toward safety: it can only BLOCK by citing a divergence, or ABSTAIN by routing to a human. It never passes a judgment obligation. A READY verdict always comes from the deterministic floor, never from the judge. So a judgment acceptance criterion the floor routed to cannot_check either becomes BLOCKED (the judge cited a divergence, with a resolving pointer that mechanically resolves, and the sampling floor agreed), INCONCLUSIVE (the judge abstained on a required judgment), or stays open (the judge did not block).

If you want a merge to be blocked on findings, that already happens with no extra flag:

shipmoor claim-check . --floor-only   # the exit code is the gate, unconditionally

Run the two together deliberately, rather than expecting the judge itself to ever hand you a passing verdict: floor-only in your required step with full mode as a separate advisory step, or full mode directly in the required step if you want the judge’s BLOCK to count too. See CLI reference and CI integration.

Floor versus judge, at a glance

You want…Use
Adjudication of the judgment acceptance criteria the floor cannot checkshipmoor claim-check --agent <agent> (judge, monotonic toward safety)
A merge blocker on a deterministic unmet acceptance criterionshipmoor claim-check --floor-only (the exit code is the gate)
Both, with the judge’s BLOCK also able to fail the buildshipmoor claim-check --agent <agent> in your required step (no --floor-only)
Both, with the judge kept advisory onlyThe floor-only step gates; a separate, || true-guarded full-mode step reports

Diagnosing with shipmoor doctor and shipmoor capabilities

Two commands cover most diagnostics:

shipmoor doctor                # checks install, license, and config integrity
shipmoor capabilities --json   # shows entitlement state, including claim_check

shipmoor doctor walks the install, the license, and the project config, and prints a precise report. shipmoor capabilities --json shows which entitlements are enabled, so you can tell at a glance whether the judge will run.

FAQ

Does Shipmoor send my code to a model or a server? No. The floor never calls a model. The judge, when you opt in, runs as your subprocess and only talks to its provider. No source is uploaded to Shipmoor, ever. See Privacy & telemetry.

What happened to shipmoor scan --intent? It is gone, and has been since the claim_check entitlement split. The legacy intent-scan, resolve-intent, probes, and scan --intent surfaces were folded into shipmoor claim-check and its init, resolve, and probes subcommands. shipmoor scan is now a pure community line-scoped scanner with no --intent flag.

Can I run a claim check without an agent at all? Yes. Floor-only mode (no --agent, or --floor-only) runs the deterministic floor and synthesizer with no judge. It’s the mode most CI gates run.

Is there a --fail-on flag on claim-check? No. --fail-on belongs to shipmoor scan. Claim Check doesn’t need an equivalent: its exit code already maps BLOCKED and INCONCLUSIVE to a non-zero code unconditionally. The two gates are independent; either can fail the build.

Where is the VSA written? To .shipmoor/claim-check.vsa.json by default, or to a path you choose with --vsa-out. Its predicateType is https://slsa.dev/verification_summary/v1. See Reading the verdict.

Last updated on July 13, 2026

Was this article helpful?

Your response is saved on this device.

Related Articles