feat(rustd): a fleet's credentials split by channel, not by convention
`runBilling` resolves every declared credential into one list, and the lease body then walks it calling `mintableId` per entry, appending to one of two builders. Nothing stops an edit from appending a mintable handle to both, so Invariant 1 — a stored App config never reaches the child — holds because that walk is written correctly. Here the walk produces a `Declared` with two fields and it is the only thing that can produce one. A credential reaches exactly one channel because exactly one branch runs, and a mintable handle is DROPPED by the branch that classifies it rather than carried forward. The invariant is an ownership fact; there is no caller that could break it. The vault moved out of `provider/` to the crate root on the way, because it now has two callers. One store, one process key, one decrypt routine serving both statements through a column offset — which is why the batch statement's odd column order is copied rather than tidied. `credentials/integration.zig` comes across as its CLASSIFICATION half only: the ids, the wire spellings, and whether a handle mints on demand. The `Mint` strategies are the broker's, and a lease never calls it — porting them would put an asynchronous HTTP client on the claim path for metadata that is three strings and a bool. The `REGISTRY` slice does not come across either: it exists because `Spec` carries a function pointer, and with the strategies gone every entry collapses to a bool the id already knows. An injected registry would be a seam for a test that does not need one. `mints_on_demand` is one negation rather than a list, so a new connector is on-demand BY DEFAULT: the failure mode of the other spelling is shipping a stored refresh token to a child process, and of this one a mint that answers `unknown_integration`. UZ-AGT-003 joins the Rust registry — this milestone's lease path is the first thing to emit it — with the problem row mirroring the Zig entry's 424. The registry parity test caught the missing `.failed_dependency` spelling, which is the test doing its job. Two vault failures now answer two codes, matching the two the Zig logs: a decrypt failure stays internal because which check failed is an oracle, while a body that is not an addressable object answers UZ-VAULT-001 — a fact the operator who stored it can act on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
K
Kishore Kumar committed
23d546c1dc6ba0d09b2528c85eb4c5f0dd6e4437
Parent: ffad7c9