Findings & rules

Shipmoor Team
June 11, 2026
5 min read

A Shipmoor finding is not a style nit. Every rule in the catalog targets a high-confidence failure mode of generated code: the things a coding agent gets wrong that a linter, a type checker, and a tired reviewer all let through. This page covers what those failure modes are, how severity is assigned, and how to use shipmoor rules and shipmoor explain to go from a finding to a fix.

The failure modes

The headline classes, in the order reviewers hit them:

Failure modeWhat it means
Phantom importThe code references a package or local module that isn’t in the manifest, the lockfile, or the project.
Hallucinated APIA function, method, endpoint, or local symbol is called even though it doesn’t exist.
Stub pathA handler returns success while the real persistence, payment, or side effect is missing.

The full catalog organizes its rules into five categories:

  • Phantom imports / dependencies. The agent invented a package, mis-spelled one, or used one without declaring it. python.phantom_import, typescript.phantom_dependency, javascript.phantom_dependency, go.phantom_import.
  • Placeholder logic. Empty bodies, pass / ellipsis, constant returns, throw new Error("not implemented"), panic("TODO"). *.placeholder.*.
  • Trust suppression. any at public boundaries, as any, @ts-ignore: code that bypasses the type system so a generated change compiles without satisfying the contract. *.trust.*.
  • Quality signals. Bare except, mutable default arguments, ignored errors on side-effecting calls, console.log / fmt.Print left in production code, oversized functions. *.quality.*, *.error.*, *.debug.*, *.structure.*.
  • Control flow. Unreachable code after a return or throw. *.control_flow.*.

Shipmoor 0.4.0 ships 30 rules across Python, TypeScript, JavaScript, and Go. List them all, with severities, in one command:

shipmoor rules
shipmoor rules --json

Phantom-import subtypes

The phantom-import rules classify every finding by subtype, so a reviewer can tell at a glance whether the agent invented something or just forgot a manifest entry:

SubtypeWhat it means
hallucinated_packageNo such package exists on the public registry. Often a real agent hallucination.
missing_manifest_entryThe package exists on the registry, but the project never declared it.
broken_relative_pathThe import is local, but the target file does not exist on disk.
unresolved_local_moduleThe import looks local but doesn’t match any module under the project’s source roots.

The subtype appears in the human message and in JSON under finding.subtype. The optional registry lookup behind hallucinated_package is the Community CLI’s only outbound network call. Disable it with SHIPMOOR_OFFLINE=1, and those findings fall back to missing_manifest_entry, marked unverified.

How severity is assigned

Severity is set per defect class and held consistent across languages. A hallucinated import is high whether it’s Python or Go, because the code cannot run as authored in either:

Defect classSeverityWhy
Hallucinated import or dependencyhighCode cannot run as authored; strong signal of agent failure.
Placeholder body in non-test, non-interface codemediumStrong review signal, but some legitimate stubs exist.
Ignored error from a side-effecting callmediumReviewer-actionable, conservative default.
Trust suppression at a boundary or via ignore directivesmediumA defensible signal that safety checks were bypassed.
Bare except / catch-all that discards failureslowCommon pattern with high context sensitivity.
Debug output left in sourcelowUsually cosmetic and easy to clean up.

A few rules sit outside the shared classes. A Python syntax error is critical (the file can’t even be analyzed), and a placeholder panic("TODO") in Go is high. You can override any rule’s severity, or disable a rule entirely, in .shipmoor.yaml. See Gating & policy.

Explaining a finding

Every finding carries a stable ID. Ask Shipmoor for the why, the root cause, and the fix, either by rule or by finding ID from a JSON report:

shipmoor explain phantom_import
shipmoor explain SHM-b00b9982e581ed39 --from shipmoor.json
✗ high · phantom import   python.phantom_import
app.py:3 · SHM-b00b9982e581ed39 · confidence high · phantom_dependency
────────────────────────────────────────────────────────
why
  Local module 'imaginary_shipmoor_package' is referenced but no file matches under PYTHONPATH.
root cause
  No matching local module file could be resolved from project paths.
fix
  → 'imaginary_shipmoor_package' looks local but does not resolve from project module paths.
    Add the file, fix PYTHONPATH, or remove the import.
evidence
  import_name: imaginary_shipmoor_package
  registry_lookup: not_applicable

After any --json or --sarif run that produced findings, the scan prints the exact shipmoor explain command for one of them; copy it to drill in. Agents use the same loop: the shipmoor-fix skill feeds explain output back to the agent as repair guidance.

What Shipmoor deliberately doesn’t flag

Style, formatting, dependency vulnerabilities, and general SAST are other tools’ jobs (ruff, ESLint, pip-audit, semgrep, CodeQL). Shipmoor stays focused on the question those tools don’t answer: is this generated change real, grounded, and implemented?

Next

Last updated on June 11, 2026

Was this article helpful?

Your response is saved on this device.