# Dependency and supply-chain policy

MetaCrate treats the locked dependency graph as reviewed release input. The
canonical direct-dependency and duplicate-version inventory is
[`ci/dependency-policy.json`](../ci/dependency-policy.json), and the native Rust
`metacrate-ci-matrix dependency-audit` command compares that inventory with
`cargo metadata --locked --all-features`.

The audit fails when a direct crate or resolved direct version is added or
removed without review, duplicate versions drift, a registry dependency uses a
wildcard, a package comes from Git or an unapproved registry, rationale is
missing, or the dependency lacks an implemented responsibility in
[`RUSTREWRITE.md`](../RUSTREWRITE.md). Its JSON evidence records every direct
consumer and dependency scope, all approved duplicate sets, native direct
dependencies, review dates, and the resolved external package count.

The policy intentionally distinguishes Rust 1.96.0, the minimum supported Rust
version, from current stable Rust used for development and release validation.
The release matrix checks both. Raising the MSRV requires an explicit policy,
matrix, documentation, and changelog review; ordinary dependency updates may
not raise it accidentally.

## Automated gates

The Ubuntu-only consolidated required Gitea gate installs pinned versions of
`cargo-deny` and `cargo-machete`, then runs:

```sh
cargo run --locked -p metacrate-ci-matrix -- \
  dependency-audit --evidence artifacts/dependency-audit.json
cargo deny check advisories licenses bans sources --hide-inclusion-graph
cargo machete --with-metadata
```

`cargo-deny` accepts only crates.io sources and the reviewed permissive license
set in `deny.toml`. Advisory exceptions and license exceptions are empty.
Duplicate versions are denied unless one exact version is listed with a reason;
the Rust audit independently verifies the complete exact duplicate set across
the lockfile, including target-specific packages. `cargo-machete` rejects
unused direct dependencies. The only metadata exclusions are `pkg-config` and
`vcpkg` in the two native adapter crates because their target-conditional use
is directly visible in each `build.rs`.

## Native and platform requirements

All native boundaries have Linux, Windows, and macOS strategies:

| Boundary | Linux and macOS | Windows | Feature scope |
|---|---|---|---|
| libopus 1.3+ | `pkg-config` package `opus` | vcpkg `opus` for MSVC; `pkg-config` for GNU | WebRTC voice crate |
| OpenJPEG 2.5.4+ | `pkg-config` package `libopenjp2` | vcpkg `openjpeg` for MSVC; `pkg-config` for GNU | opt-in `jpeg2000` |
| j2k 0.8.1 | pure Rust, no platform prerequisite | same pure-Rust graph | opt-in `rust-j2k` |
| Skia 0.99.0 | target-specific official binary cache or source build | same target-specific strategy | opt-in `skia` |
| Vorbis 0.5.6 stack | `vorbis_rs` builds its reviewed C codec stack | same crate strategy | opt-in `vorbis` |
| Physical audio | ALSA development files on Linux; CoreAudio is system-provided on macOS | WASAPI is system-provided | opt-in `real-audio` |

`pkg-config` and `vcpkg` only discover libraries; they are not runtime
dependencies. `libremetaverse-opus` and `libremetaverse-openjpeg` are the only
workspace crates allowed to contain unsafe ABI calls. They expose owned,
validated safe Rust APIs and require exclusive mutable access to native codec
state. No macOS-only API is used without Linux and Windows equivalents.

## Review and update cadence

The graph is reviewed at least quarterly using `reviewed_on` and `review_by`.
RustSec advisories are reviewed immediately. For every update:

1. identify the implemented caller and confirm the dependency remains needed;
2. inspect release notes, maintenance state, license, MSRV, enabled features,
   native code, and target-specific build behavior;
3. update one crate deliberately with `cargo update -p NAME --precise VERSION`;
4. rerun the dependency audit, `cargo-deny`, `cargo-machete`, and the affected
   release-matrix profiles from clean target directories;
5. update the exact policy versions and duplicate reasons only after reviewing
   the resulting transitive graph.

High-cost or native dependencies require isolated feature testing and all-
features unification. A successful compile does not replace the real codec,
secure WebRTC loopback, device, or live-grid gates applicable to that boundary.
The abandoned `audiopus`/`audiopus_sys` stack is prohibited by absence from the
direct inventory and by RustSec; MetaCrate instead binds the maintained system
libopus ABI in its private adapter.
