Credence.Pattern.NoAttrBeforeDefmodule (credence v0.7.1)

Copy Markdown

Correctness rule: Detects documentation/spec module attributes (@moduledoc, @doc, @spec, @type, @typep) placed at the top level before a defmodule, and moves them inside that module. A module attribute outside a module does not compile:

cannot invoke @/1 outside module

LLMs frequently emit @moduledoc "..." (and friends) just above the defmodule they belong to. The fix relocates the contiguous run of such attributes that immediately precedes a defmodule to the top of that module's body, in their original order.

Scope (deliberately narrow)

  • Only doc/spec attributes are moved (@moduledoc, @doc, @spec, @type, @typep) — never @impl, @derive, @behaviour, etc., whose placement carries ordering semantics.
  • Only when an actual defmodule follows. Bare code with no module is left alone — we never invent a module.
  • Nothing is ever deleted: existing attributes inside the module are kept as-is (no de-duplication).

Bad

@moduledoc "Greets people"
defmodule Greeter do
  def hi, do: :ok
end

Good

defmodule Greeter do
  @moduledoc "Greets people"
  def hi, do: :ok
end