# `MobDev.SecurityScan.Runner`
[🔗](https://github.com/genericjam/mob_dev/blob/master/lib/mob_dev/security_scan/runner.ex#L1)

Orchestrates the scan: invokes each enabled layer in turn,
collects `LayerResult`s, and returns a `Report`.

Layers are run sequentially (not concurrently) so that terminal
output stays readable in the streaming formatter and so that
resource-heavy scanners like semgrep don't dogpile a laptop.

Layers never raise — failures land as `%LayerResult{status: :error}`.
The runner additionally guards every callback with a `try`, so a
bug in one layer can't take the whole scan down.

# `run`

```elixir
@spec run(
  [module()],
  keyword()
) :: MobDev.SecurityScan.Report.t()
```

Runs the listed layers in order. `opts` is forwarded to each
layer's `run/1` callback. The optional `:on_layer_start` and
`:on_layer_done` callbacks let the formatter stream progress
to the terminal as layers complete.

---

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