Engineering
One source of truth for runtimes and models, and a drift gate that keeps the templates honest
How we collapsed a sprawl of hardcoded provider switches into one manifest, derived everything from it, and gated the copy so it can never drift.
For most of the platform’s life, the answer to a deceptively simple question — “which model providers does this runtime actually support, and how is each one billed and served?” — lived in about six different places. The LLM proxy had a hardcoded switch that mapped a model id to an upstream provider. The provisioner had its own list of valid provider names. The workspace-creation UI shipped a static catalog of provider/model options. The billing path inferred the provider a third way, by slicing the prefix off a model slug. Each of these was correct on the day it was written, and each one slowly went stale on its own schedule.
This is the story of how we collapsed all of that into a single manifest, made every consumer derive from it instead of restating it, and then built a gate so the derived copies can never silently disagree with the source again.
The shape of the bug class
The failures all rhymed. A new model would get added to the proxy’s switch but not to the UI catalog, so the platform could serve a model you couldn’t select. A provider would get renamed in one path but not another. The most expensive version of this was a billing miss: the path that decides whether a workspace runs on platform-managed credentials or bring-your-own-key inferred the provider by string-slicing the model slug, and a slug it didn’t recognize quietly fell through to the wrong billing mode.
None of these were hard bugs individually. The problem was structural: there was no source of truth, just N copies of the same knowledge, each authored by hand, each free to drift. We had already paid for this exact anti-pattern in an unrelated area — upload size caps had been duplicated across five surfaces and bumped on different days (core#1604 eliminated that one with a single GET /uploads/limits endpoint). The provider/runtime matrix was the same disease, bigger.
The thing that finally forced the issue was a real serving outage rather than a UI mismatch — but the underlying lesson was identical. When the same fact is written down in more than one place, exactly one of those places is the truth and the rest are bugs waiting to be observed.
Deciding what the source of truth actually is
The first instinct, in cp#343, was to enumerate a superset: list every provider the platform could conceivably talk to, 24 of them, in one big manifest. That was wrong, and the CTO correction on the RFC said so plainly. A superset answers “what providers exist” but not the question consumers actually ask, which is “for this runtime, which providers and which exact model ids are native, and how is each one billed and served?”
So cp#352 rescoped the manifest to the inverse of a superset: a top-level runtimes: block in providers.yaml, keyed by runtime, where each runtime declares its own native support matrix. That block became the SSOT. cp#359 then put the canonical platform-managed-vs-BYOK matrix into the same place, per RFC internal#580 Option C — the decision being that the per-runtime platform matrix lives once, in the manifest, and is never hand-copied into the runtimes that consume it.
A subtle but important detail: a “runtime” and a “provider” are not the same axis, and the manifest had to keep them separate. The SDK registry defines claude-code, codex, hermes, and openclaw as official discovery choices, while the open RuntimeId schema also accepts bounded, path-safe custom adapter IDs. External registration describes where an adapter executes, not what that adapter is called. anthropic-oauth, openai-subscription, vertex, and minimax are providers — where tokens come from and who pays. Several runtimes split a vendor into provider arms by auth mode, such as openai-subscription versus openai-api and anthropic-oauth versus anthropic-api. Flattening those axes would reintroduce exactly the ambiguity we were trying to kill.
Derive, don’t restate
A source of truth that nothing reads is just a comment. The real work was repointing every consumer to derive from the manifest instead of carrying its own copy — and doing it without changing behavior on the way in.
cp#376 stood up the registry foundation: a DeriveProvider function backed by the manifest, plus a codegen step and a drift gate, all of it additive with zero behavior change. No production path read the new code yet; it just had to exist and be provably correct first. Then cp#377 made the LLM proxy the first real consumer, replacing its hardcoded inferLLMProvider switch with the registry-backed derivation. The discipline that made this safe was a byte-identical equivalence test: for every input, the old switch and the new registry-derived path had to produce the same output, byte for byte. You don’t get to claim “no behavior change” — you prove it in CI.
The billing path was the one that mattered most, and it was handled deliberately in two steps. core#1971 (landed via core#1972) repointed the platform-vs-BYOK decision to derive the provider from the registry rather than slug-slicing, and added only-registered validation. Initially that validation was WARN-mode: an unregistered (runtime, model) pair emitted a header and a log line but let creation proceed, so we could watch real traffic before tightening. Only once that was quiet did core#1981 flip it to a hard 422 UNREGISTERED_MODEL_FOR_RUNTIME. WARN-then-reject is the right shape for any gate that can reject legitimate traffic — you earn the right to reject by first observing that you wouldn’t have.
The UI was the last and most visible copy to retire. The workspace-creation dialog had shipped a static fallback catalog plus a runtime-specific hardcoded list; core#1848 and core#1926 deleted that and made it derive provider/model options from the selected template’s registry-served metadata. The platform can no longer offer you a model in a dropdown that the proxy can’t serve, because the dropdown and the proxy now read the same list.
Crossing the repo boundary without a second source of truth
The hard part is that the SSOT lives in the control plane, but molecule-core needs the same knowledge at the workspace boundary. The naive fix — keep a second copy in core and “remember to update both” — is the original bug with extra steps.
The CTO-decided shape was: distribution by SDK via codegen plus verify-CI. core#1970 brought the registry into core as generated code — a registry_gen.go produced from a byte-identical copy of providers.yaml — and pinned the source with a canonicalProvidersYAMLSHA256 constant. That SHA pin is the whole trick. The core copy isn’t authoritative; it’s a cache with a checksum back to the canonical. When the control plane changes the manifest, the sync isn’t “edit core to match” — it’s a mechanical operation: byte-copy the yaml, regenerate registry_gen.go, repin the SHA, run the golden test. You can see the exact ritual in the sync PRs: core#2098 syncing MiniMax-M3 from cp#428, and core#2103 mirroring the serving-url fixes from cp#432.
The gate that makes it stick
Architecture decays the moment nobody is watching it. The reason this didn’t quietly rot back into six copies is the drift gate, and there are really two of them working together.
The first is the codegen check shipped in cp#376: if you edit providers.yaml and don’t regenerate the registry, or you hand-edit the generated file, CI goes red. The generated artifact and its source are mechanically forced to agree. The second is the SHA pin in core: if the byte-identical copy drifts from the pinned hash, the build fails. Together they mean the SSOT and every derived copy of it — in-repo and cross-repo — are checked on every change, not audited quarterly by a human who happens to notice.
We later closed the loop on the behavior side too, with a live serving gate (cp#431): for each offered (provider, auth_mode) in the manifest, CI issues a real minimal completion against the actual upstream. That gate immediately earned its keep — it caught a kimi-coding base_url that was missing its /v1 suffix, a genuine production serving bug the static checks could never have seen (cp#432). The manifest is now not just internally consistent; it’s verified against reality.
The lesson
The shippable idea here is small and general: when the same fact is written down more than once, you don’t have documentation, you have a future incident. The fix is two moves, and they are equally important. First, pick one place for the fact and make everything else derive from it — proving “no behavior change” with equivalence tests as you migrate each consumer, and crossing repo boundaries with a checksummed cache rather than a hand-maintained twin. Second — and this is the part teams skip — build the gate that makes drift a red build instead of a tribal-knowledge chore. The SSOT is the easy half. The drift gate is what makes the SSOT true a year later.
What we got for it: adding a model is now a recipe, not an archaeology dig. Register it in providers.yaml, regenerate, sync the SHA into core, watch the serving gate go green against the real upstream. The UI, the proxy, the provisioner, and the billing path all pick it up because none of them know anything the manifest doesn’t tell them.