# `JobyKit.Lint`
[🔗](https://github.com/jobycorp/joby_kit/blob/v0.2.0/lib/joby_kit/lint.ex#L1)

Lint engine for JobyKit-installed apps. Verifies wrapper-contract
invariants by introspecting a manifest module and scanning the host's
component source files.

## Rules

  * `:manifest_drift` (error) — a manifest entry points at a function
    that is not actually a Phoenix function component. Caught first
    because every other check depends on the entry being live.
  * `:missing_data_component` (error) — a registered wrapper does not
    carry `data-component="Module.function"` in its source.
  * `:missing_rest_global` (warning) — a registered wrapper does not
    declare `attr :rest, :global`, blocking pass-through of phx-* and
    aria-* attributes from callers.
  * `:unregistered_wrapper` (warning) — a function carries a
    `data-component="..."` attribute but is not registered in the
    manifest, making it invisible to `/design.json` and to agents.
  * `:raw_html_primitive` (warning) — a `.heex` template (or `~H`
    block in a `.ex`) contains a raw `<button>`, `<input>`,
    `<textarea>`, or `<select>` outside of a wrapper definition. The
    kit ships wrappers for all four; reaching past them drops the
    contract. Whole-file skipped when the file contains
    `data-component=` (i.e., defines wrappers). Per-line opt-out via
    `<%!-- jobykit:allow-raw-html --%>` (or `# jobykit:allow-raw-html`
    on the preceding line for `.ex` files).

Each violation is a map with `:rule`, `:severity`, `:message`,
`:file`, `:line`, `:module`, `:function`. The engine is pure data —
formatting and exit codes live in `Mix.Tasks.JobyKit.Lint`.

# `severity`

```elixir
@type severity() :: :error | :warning | :info
```

# `violation`

```elixir
@type violation() :: %{
  rule: atom(),
  severity: severity(),
  message: String.t(),
  file: String.t() | nil,
  line: non_neg_integer() | nil,
  module: module() | nil,
  function: atom() | nil
}
```

# `run`

```elixir
@spec run(keyword()) :: [violation()]
```

Run the lint engine. Returns a list of violations in deterministic
order (drift first, then per-entry checks in manifest declaration
order, then unregistered wrappers sorted by data-component string).

## Options

  * `:manifest` — required. The host's manifest module
    (`use JobyKit.Manifest`).
  * `:paths` — list of glob patterns to scan for the unregistered-
    wrapper rule. Defaults to `["lib/**/*.ex"]`. Patterns are
    resolved relative to `cwd`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
