Claude Code integration

Shipmoor Team
June 27, 2026
7 min read

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 --version is 0.5.1 or newer (the harness has been bundled into the main binary since 0.5.0).
  • Entitlements: shipmoor capabilities shows agent_skills and agent_harness as enabled, the IC tier. Check identity with shipmoor whoami; sign in with shipmoor login.
  • PATH: shipmoor is on your PATH, because the hooks Claude runs invoke the bare shipmoor command. Confirm with command -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:

SkillWhat it does
shipmoor-reviewRun the scan, triage findings, explain blockers, and report a review-readiness verdict.
shipmoor-agent-guardInject compact pre-edit guardrails that prevent common defects before review.
shipmoor-intent-contractCompare the change against its declared intent and surface what didn’t earn its claim.
shipmoor-fixRepair findings introduced by the current change and re-scan until the gate passes.
shipmoor-pr-preflightRun 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:

TriggerEffect
/shipmoorScan the current change and report the verdict.
/shipmoor-changedScan the working-tree change-set (scan --changed).
/shipmoor-gateRun the structural gate and report whether the change is ready.
/shipmoor-explainExpand 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.md vs .claude/settings.json) and never conflict: the skills installer owns CLAUDE.md and never touches settings.json, and the harness owns its hook entries and never edits CLAUDE.md.

How the loop behaves

Once the hooks are installed, the integrity loop runs on Claude’s own lifecycle:

  • After each edit, the PostToolUse hook fires on any Edit, MultiEdit, Write, or NotebookEdit and scans the working-tree change-set.
    • In feedback mode, a finding is returned as hookSpecificOutput.additionalContext so 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.
  • Before Claude finishes, the Stop hook 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

SymptomLikely causeFix
Claude finishes despite open findingsThe 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 fireThe 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 lingerPre-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-harness script is a recognized legacy alias only. Since 0.5.0 the harness is the shipmoor harness … subcommand of the main binary. Don’t add new hooks that call the old script.

Next

Last updated on June 27, 2026

Was this article helpful?

Your response is saved on this device.