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

Loads `priv/security/bundled_versions.exs` — the source-of-truth
manifest of what versions ship inside the OTP tarballs that
`MobDev.OtpDownloader` distributes.

See [`priv/security/bundled_versions.exs`](priv/security/bundled_versions.exs)
for the full schema and update procedure.

## Why a manifest, not a fingerprint-only approach

Manifest first, fingerprint second. The manifest is a *claim*
reviewable in git — every PR that touches it is auditable.
Fingerprinting is the *receipt* that proves the claim.

A fingerprint-only approach can silently fail when build flags
change and a version string is stripped or moves to a different
binary; the scanner just reports "version unknown" and you stop
noticing. A manifest-first approach forces a human to write down
what shipped — and the fingerprinter then catches drift.

# `active`

```elixir
@spec active() :: map()
```

Return the currently active bundle (the hash Mob is shipping today).

# `for_hash`

```elixir
@spec for_hash(String.t()) :: {:ok, map()} | {:error, :unknown_hash}
```

Return the bundle entry for a given OTP tarball hash.

Returns `{:ok, bundle}` when present, `{:error, :unknown_hash}`
otherwise. Useful for the fingerprinter when the hash on disk
doesn't match the manifest's `:active_hash` — the tarball might
be from an older or unpublished build.

# `load`

```elixir
@spec load() :: %{active_hash: String.t(), bundles: %{required(String.t()) =&gt; map()}}
```

Load the manifest from disk. Returns the parsed map.

Raises if the file is missing or doesn't evaluate to a map with
the expected shape — the manifest is a hard requirement for the
bundled-runtime scan layer; a missing file is a real bug, not a
soft warning.

# `manifest_path`

```elixir
@spec manifest_path() :: Path.t()
```

Path to the manifest .exs file.

---

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