A defect sink that formats every emitted capsule as a Logger line.
Not started by default — per
decisions/2026-09-04-defect-reports-are-a-shipped-feature.md, mob is
never the collector, and a sink that runs unbidden would violate that. An
app opts in explicitly:
Mob.Defect.Sinks.Dev.start_link()or under its own supervision tree:
children = [
# ... app children ...
Mob.Defect.Sinks.Dev
]It is Dev because Logger output is the medium the connected-agent workflow
already uses — mix mob.connect streams the device's Logger output into
the agent's IEx session, so a defect logged here reaches the agent for
free. An app that wants a production sink (a remote endpoint, a file, a
push channel, or nothing) writes their own subscriber; the API is
Mob.Defect.Bus.subscribe/0 plus a handle_info({:mob_defect, capsule}, ...).
What it logs
severity: :fatal | :critical→Logger.errorseverity: :warning→Logger.warning- anything else →
Logger.info
The severity mapping is what routes a real bug to the log level a triager
reads first. Logger.info for everything would bury a fatal alongside a
perf regression; Logger.error for everything would train the reader to
ignore the channel — exactly what the redaction and dedup work goes into
preventing.
Summary
Functions
Returns a specification to start this module under a supervisor.
Start the sink under name, defaulting to the module.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec start_link(keyword()) :: GenServer.on_start()
Start the sink under name, defaulting to the module.