Shipmoor plugs into Claude Code on three levels, and the integration is strongest when you use all of them. The CLI is the scan engine, the source of truth for findings. The Skills are always-on instructions in CLAUDE.md that make the agent want to scan and triage its own work. The Harness is a set of lifecycle hooks in .claude/settings.json that make the scan actually happen after each edit and gate the result before Claude declares the task done. Skills shape behavior; hooks enforce it. This page wires up both.
Prerequisites
- CLI:
shipmoor --versionis0.5.1or newer (the harness has been bundled into the main binary since0.5.0). - Entitlements:
shipmoor capabilitiesshowsagent_skillsandagent_harnessasenabled, the IC tier. Check identity withshipmoor whoami; sign in withshipmoor login. - PATH:
shipmooris on yourPATH, because the hooks Claude runs invoke the bareshipmoorcommand. Confirm withcommand -v shipmoor.
shipmoor --version # shipmoor 0.5.1
shipmoor capabilities # agent_skills + agent_harness enabled (ic)
command -v shipmoor # ~/.shipmoor/bin/shipmoor
If agent_skills or agent_harness is locked, see Plans & tiers.
Step 1: Install the Skills
Skills teach Claude the Shipmoor behaviors. Installing them writes a single marker-wrapped managed block into your project’s CLAUDE.md:
shipmoor skills install claude # write the managed block into CLAUDE.md
shipmoor skills status # what's installed where
shipmoor skills uninstall claude # remove only the managed block
The write is idempotent; re-run it any time to update the block in place. uninstall removes only the managed block, leaving the rest of your CLAUDE.md untouched. The five skills it installs:
| Skill | What it does |
|---|---|
shipmoor-review | Run the scan, triage findings, explain blockers, and report a review-readiness verdict. |
shipmoor-agent-guard | Inject compact pre-edit guardrails that prevent common defects before review. |
shipmoor-intent-contract | Compare the change against its declared intent and surface what didn’t earn its claim. |
shipmoor-fix | Repair findings introduced by the current change and re-scan until the gate passes. |
shipmoor-pr-preflight | Run the final PR-readiness path: diff scan, structural gate, and a copyable PR note. |
See The five skills for the behavior each one drives. In Claude Code, shipmoor-review also responds to slash triggers; type any of these to invoke it on demand:
| Trigger | Effect |
|---|---|
/shipmoor | Scan the current change and report the verdict. |
/shipmoor-changed | Scan the working-tree change-set (scan --changed). |
/shipmoor-gate | Run the structural gate and report whether the change is ready. |
/shipmoor-explain | Expand a finding into the why and the fix. |
Step 2: Install the Harness hooks
Skills make Claude willing to scan, but they don’t guarantee a scan runs. The harness does: shipmoor harness install claude writes managed lifecycle hooks into .claude/settings.json. Claude reads hooks from the top-level hooks key, so the harness mirrors its entries there and records provenance in a sibling "// shipmoor:harness" key. The managed shape looks like this:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|MultiEdit|Write|NotebookEdit",
"hooks": [
{ "type": "command", "command": "shipmoor harness hook claude-code post-tool-use" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "shipmoor harness hook claude-code stop" }
]
}
]
},
"// shipmoor:harness": {
"note": "Managed by shipmoor-harness (Claude Code adapter). Uninstall removes exactly these entries."
}
}
The install is idempotent, so re-running it is byte-identical. uninstall restores the file byte-for-byte. And because pre-bundle installs wrote the standalone shipmoor-harness … command form, a reinstall recognizes and migrates those legacy hook entries to the bundled shipmoor harness … form.
shipmoor harness install claude # write hooks into .claude/settings.json
shipmoor harness status # mode + adapter for this project
shipmoor harness uninstall claude # restore settings.json byte-for-byte
Skills vs hooks. Skills make the agent want to scan: that’s behavior. Hooks make the scan happen and gate the result: that’s enforcement. Use both. They live in separate files (
CLAUDE.mdvs.claude/settings.json) and never conflict: the skills installer ownsCLAUDE.mdand never touchessettings.json, and the harness owns its hook entries and never editsCLAUDE.md.
How the loop behaves
Once the hooks are installed, the integrity loop runs on Claude’s own lifecycle:
- After each edit, the
PostToolUsehook fires on anyEdit,MultiEdit,Write, orNotebookEditand scans the working-tree change-set.- In feedback mode, a finding is returned as
hookSpecificOutput.additionalContextso Claude reads it as context and keeps working. - In block mode, a finding is written as
[shipmoor-harness] …to stderr and the hook exits 2, so Claude surfaces it to the model as a hard block.
- In feedback mode, a finding is returned as
- Before Claude finishes, the
Stophook runs the gate one more time, so a session can’t end on an unaddressed blocker. - A clean scan, observe mode, or a missing CLI is a no-op (exit 0): the harness never interrupts the agent over tooling problems or when there’s nothing to say.
- The whole loop is bounded by
max_feedback_cycles, so it can never trap a session in an endless fix-rescan cycle.
Choose a mode
shipmoor harness mode feedback # day-to-day: findings flow back as context
shipmoor harness mode block # firmest: pair with CI to enforce the gate
shipmoor harness status # verify the active mode + adapter
Use feedback for everyday work: Claude sees each finding inline and self-corrects without being hard-stopped. Use block when you want the harness to enforce the gate, paired with the same gate in CI so nothing slips past locally that would fail the build. See Install & modes for the full mode contract.
A real example: a block in flight
With the project in block mode, an edit that introduces a phantom import triggers the Stop/PostToolUse block path. The harness writes the finding to stderr and exits 2, and Claude feeds it straight back to the model:
[shipmoor-harness] Shipmoor found 1 issue (1 high).
[high] pay.py:6 python.phantom_import
Local module 'receipt_engine' is referenced but no file matches under PYTHONPATH.
→ 'receipt_engine' looks local but does not resolve from project module paths. Add the file, fix PYTHONPATH, or remove the import.
Shipmoor caught a change that referenced a module it can’t find; it doesn’t claim the change is correct, only that this import doesn’t resolve. Claude reads the block, fixes the import, and the next scan clears.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Claude finishes despite open findings | The project is in observe mode (report-only, never affects the verdict). | shipmoor harness mode feedback (or block), then confirm with shipmoor harness status. |
| Hooks never seem to fire | The hooks weren’t written to .claude/settings.json, or shipmoor isn’t on PATH for the command Claude runs. | Re-run shipmoor harness install claude; verify command -v shipmoor resolves in the same environment Claude launches in. |
Old shipmoor-harness … hook entries linger | Pre-bundle installs wrote the standalone command form. | Re-run shipmoor harness install claude; a reinstall recognizes and migrates legacy entries to the bundled shipmoor harness … form. |
The standalone
shipmoor-harnessscript is a recognized legacy alias only. Since 0.5.0 the harness is theshipmoor harness …subcommand of the main binary. Don’t add new hooks that call the old script.
Next
- Cursor integration: the same three-level wiring for Cursor.
- The self-correction loop: how feedback and block mode drive the fix-rescan cycle.
- The five skills: what each Skill does and the loop it drives.
- Install & modes: the harness command surface and mode contract.