Configuration

Shipmoor Team
August 29, 2026
6 min read

Shipmoor’s configuration lives in your repo, in plain YAML, reviewable like any other change. Four artifacts matter: .shipmoor.yaml (the scan config, plus the optional harness: and claim_check: blocks), the optional intent file under .shipmoor/, the Claim Check acceptance set, and an optional floor-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/.

Set the mode with shipmoor harness mode <mode> rather than editing by hand; it rewrites only the mode line. Harness itself is unlimited on Free and Pro. If an adapter or Skill launches a metered child command, that command consumes its own Free allowance.

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 local Claim Check or agent workflows, keep the change’s intent and acceptance artifacts under .shipmoor/. These are inputs to shipmoor claim-check, not flags or implicit inputs to shipmoor scan. Self-managed CI supports Scan only:

  • .shipmoor/intent.txt: a plain one-line goal read by shipmoor claim-check resolve.
  • .shipmoor/intent.yaml: the structured contract the shipmoor-intent-contract skill writes (task, expected side effects, must-nots).
  • .shipmoor/acceptance.yaml: the editable acceptance set used by shipmoor claim-check.
  • .shipmoor/acceptance.json: the frozen pin written by shipmoor claim-check freeze for review and commit.

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

The floor policy (Claim Check gate)

Claim Check ships a default deterministic floor policy. To customize its optional requirements, point the project config at a policy file:

# .shipmoor.yaml
claim_check:
  policy_path: .shipmoor/floor_policy.yaml
# .shipmoor/floor_policy.yaml
policy_version: "1.1.0"
optional_enabled:
  - scan_fail_on
  - artifact_valid
scan_fail_on: high
shipmoor claim-check . --staged --floor-only

The policy can enable or disable optional requirements and select the structural scan threshold. It cannot disable core deterministic requirements; naming a core requirement in optional_enabled is a validation error. See 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 August 29, 2026

Was this article helpful?

Your response is saved on this device.