The provider CONTRACT — what magma requires of a provider, with no commitment to how one is reached.
── ★ WHY THIS CRATE EXISTS ──────────────────────────────────────────
Until now the contract was implicit: magma-apply held a concrete
magma_plugin::provider::ProviderConn and called inherent methods on
it. That bound the engine to ONE transport — a Go subprocess speaking
tfplugin5/6 over go-plugin — and the binding was invisible, because a
concrete type never announces that it is a choice.
It is a choice, and an expensive one. Measured on the operator image
(r349, trivy artifact 9648954592): the Rust binary scans 0, while
the 8 baked Go provider binaries carry 190 findings / 49 unique
ids. The largest single contributor is terraform-provider-random
at 36 — a provider that makes no network calls at all.
So the contract is named here, in a crate that depends on magma-cty
and NOTHING ELSE. A provider is 8 methods over cty values. gRPC is one
implementation of them; a native Rust provider is another, and needs
no tonic, no subprocess, and no Go.
── WHAT LIVES HERE, AND WHY IT MOVED ────────────────────────────────
ProviderSchema, PlannedChange, Diag, Severity, ProviderError
and SchemaError were defined in magma-plugin. They are the
protocol's DATA MODEL, not its transport, and leaving them next to the
tonic client made the dependency edge point the wrong way: the trait
crate would have had to depend on the gRPC crate that implements it —
a cycle cargo rejects outright.
They are moved verbatim, and magma-plugin re-exports every one of
them, so every existing magma_plugin::provider::ProviderError path
still resolves. This is a relocation, not a redesign.