# `Mailglass.Tracking.Guard`
[🔗](https://github.com/szTheory/mailglass/blob/v0.1.0/lib/mailglass/tracking/guard.ex#L1)

Runtime auth-stream tracking guard (D-38).

**Dual enforcement with Phase 6 `TRACK-02 NoTrackingOnAuthStream`**:

- Compile-time: Phase 6 Credo catches most cases via AST inspection of
  `@mailglass_opts` + mailable function names.
- Runtime: THIS MODULE catches the dynamic-function-name bypass
  (metaprogrammed mailables, `def unquote(name)(...)` patterns).

Invoked from `Mailglass.Outbound.send/2` (Plan 05) as a precondition
similar to `Mailglass.Tenancy.assert_stamped!/0` — not a preflight STAGE
(no `{:error, _}` return path), but a FAIL-LOUD raise.

## Regex (D-38)

`^(magic_link|password_reset|verify_email|confirm_account)` — matches the
four canonical auth-carrying function-name prefixes. Variant function names
starting with these prefixes (e.g. `magic_link_verify`, `password_reset_confirm`)
ALSO match — Outlook SafeLinks pre-fetch could pre-trigger a tracked pixel on
an auth email, which would be visible in scroll-tracking logs and represent a
privacy regression.

## Adopters CANNOT turn this off

Deliberate choice (D-38). The "acknowledged" escape hatch is not provided.
Adopters who hit the regex falsely should rename their function or split their
mailable module.

## nil mailable_function (T-3-04-01)

When `mailable_function` is `nil`, the guard returns `:ok` — it cannot perform
the heuristic without a function name. Phase 6 Credo `TRACK-02` is the primary
enforcement for this case via compile-time AST inspection.

# `assert_safe!`
*since 0.1.0* 

```elixir
@spec assert_safe!(Mailglass.Message.t()) :: :ok
```

Raises `%Mailglass.ConfigError{type: :tracking_on_auth_stream}` when the
mailable's compile-time tracking opts would enable opens or clicks AND the
calling function name matches the auth-stream regex.

Returns `:ok` otherwise.

## Examples

    iex> msg = %Mailglass.Message{mailable: MyApp.UserMailer, mailable_function: :welcome}
    iex> Mailglass.Tracking.Guard.assert_safe!(msg)
    :ok

---

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