Configuration

Shipmoor Team
June 27, 2026
6 min read

Shipmoor’s configuration lives in your repo, in plain YAML, reviewable like any other change. Three files matter: .shipmoor.yaml (the scan config, plus the optional harness: block), the optional intent file under .shipmoor/, and the optional verdict-policy file for the Claim Check gate. A handful of other files are written for you by shipmoor harness and shipmoor skills; they are tracked below but are not meant to be hand-edited.

Discovery and project roots

Shipmoor works with zero config; every file below is optional.

  • Inside a git repository, scans resolve project context from the git root, so shipmoor scan src/foo.py resolves imports the same way --changed does.
  • Outside git, Shipmoor walks upward to the nearest .shipmoor.yaml, .shipmoor.yml, pyproject.toml, package.json, requirements*.txt, or go.mod and treats that as the root.
  • Manifest discovery runs downward from the resolved root, so a monorepo’s nested backend/package.json and frontend/requirements.txt both contribute to import resolution.

Precedence: config file > command-line flag > built-in default. Pass --config <path> to use an explicit file.

.shipmoor.yaml

Generate a starter with shipmoor init (it also adds .shipmoor/ to .gitignore):

schema_version: 1
languages:
  enabled: [python, typescript, javascript, go]
ignore:
  - .shipmoor/
rules:
  disabled: []                # rule IDs to turn off entirely
  severity_overrides: {}      # rule ID → severity
thresholds:
  fail_on: high               # none | critical | high | medium
diff:
  only_introduced: true       # gate only what the change introduced
output:
  default_format: human

The rules, thresholds, and diff knobs are covered in Gating & policy.

The harness: block

The Agent Harness keeps its settings in the same file and edits only its own block, preserving every other key, comment, and blank line byte-for-byte. The CLI ignores the top-level harness: key, so adding it never disturbs scanning. The full block:

harness:
  mode: feedback            # observe | feedback | block   (default: observe)
  max_feedback_cycles: 3    # cap re-prompts so a loop never spins (default: 3)
  watch:
    debounce_ms: 750        # watch debounce window in ms (default: 750)
    exclude:                # extra ignore globs, watch-only
      - "**/*.snap"
      - dist/**
KeyDefaultMeaning
harness.modeobserveHow the loop reacts to a finding. observe scans and records, never interrupting. feedback routes concise findings back into the agent’s context. block exits non-zero on a threshold breach (CI or foreground dev loops).
harness.max_feedback_cycles3Hard cap on re-prompts in a single change. When the cap is hit, the loop stops and surfaces whatever remains rather than ping-ponging forever.
harness.watch.debounce_ms750How long shipmoor harness watch coalesces a burst of edits before running one scan.
harness.watch.exclude(none)Extra glob patterns the watcher ignores, on top of .gitignore and the scan-side ignore: list. Watch-only: these do not affect a plain shipmoor scan. The watcher never descends into .shipmoor/.

block degrades to feedback when the intent_scan entitlement is unavailable, unless you pass --force-structural (after which shipmoor harness status reports a mode_block_without_intent warning). Set the mode with shipmoor harness mode <mode> rather than editing by hand; it rewrites only the mode line.

The harness writes into this block only through the CLI’s minimal YAML subset (flat key: value at 2-space indent), so values stay readable by both the harness and the scan-side parser. See .shipmoor.yaml lists & flow shapes behavior if you mix richer YAML elsewhere in the file.

Reserved Team keys

Two extension points are reserved for the Team tier (preview, not yet released) and are accepted but inert today:

policy:
  mode: local
  rulesets: []
baselines:
  shared: []
  ignore_fingerprints: []

Intent files (.shipmoor/)

For Claim Check in CI or agent workflows, drop the change’s intent in the scanned directory instead of passing flags:

  • .shipmoor/intent.txt: a plain one-line goal, auto-discovered by scan as an intent source.
  • .shipmoor/intent.yaml: the structured contract the shipmoor-intent-contract skill writes (task, expected side effects, must-nots).

The .shipmoor/ directory is working state (reports, intent, watch output) and belongs in .gitignore; shipmoor init puts it there.

The verdict policy (Claim Check gate)

The gate for the claim check is configured in a separate, explicitly passed file; it is never picked up silently:

# .shipmoor/verdict-policy.yaml
gating:
  enabled: true
  min_intent_confidence: medium    # high | medium (never low)
  block_on_major_gap: true
  require_evidence_basis: deterministic
shipmoor scan --staged --intent "…" --verdict-policy .shipmoor/verdict-policy.yaml

A policy can tighten the gate but can’t loosen its engine-level floor; unknown keys or weaker-than-floor values are validation errors. Details and the --would-block rollout path: Turning on the gate.

Adapter-managed files

When you run shipmoor harness install <agent> or shipmoor skills install <agent>, Shipmoor writes a marker-wrapped, idempotent managed block into your agent’s own files. Do not hand-edit these regions; re-running install is byte-stable, and uninstall removes only Shipmoor’s block, restoring the rest. Edit the source of truth (.shipmoor.yaml) instead, then re-run install if needed. Anything outside the markers, including your own content and the other surface’s block, is preserved.

Harness and skills are distinct kinds. Where they share a file (Codex, Aider) they live in separate marker blocks; where they don’t (Claude, Cursor) they write to different files entirely.

AgentHarness writesSkills writes
Claude.claude/settings.json (PostToolUse + Stop hooks, recorded under a "// shipmoor:harness" sibling key)the managed block in CLAUDE.md
Cursor.cursor/hooks.json (native afterFileEdit + stop hooks), or .cursor/rules/shipmoor-harness.md with install cursor --soft.cursor/rules/shipmoor.md
Codexthe managed guidance block in AGENTS.mdthe managed block in AGENTS.md (separate block)
Aider.aider.conf.yml (a managed lint-cmd block) plus the .aider.shipmoor.yml include.aider.conf.yml (+ .aider.shipmoor.yml include)

The Claude harness never touches CLAUDE.md (owned by skills), and the Claude skills installer never touches .claude/settings.json (owned by the harness). A malformed or unmarked shipmoor:harness footprint is refused rather than clobbered.

Per-agent setup and what each block contains live in Agent support and Using skills with your agent.

Next

Last updated on June 27, 2026

Was this article helpful?

Your response is saved on this device.