
Separate what you need from who provides it
An application need, a provider’s abilities and its connection method answer different questions. Wildo records each explicitly, so choosing an email service is distinct from enabling email or describing how that service receives a message.
You declare the providers the application uses. Wildo connects their declared abilities to the framework features that consume them.
Example — An email service with a clear role
A product needs transactional email. Its backend declares a provider that supports that need and the email connection contract. The same product can use a different provider for language models without coupling those decisions.
For engineers
Read the declaration as three separate decisions
Wonder Todos enables EngineCapability.EMAIL_TRANSACTIONAL in engineCapabilities, then declares Resend under providers.scopes.backend.providers. This actual declaration states what that runtime may use:
resend: {
engineCapabilities: [EngineCapability.EMAIL_TRANSACTIONAL],
providerCapabilities: ['EMAIL_TRANSACTIONAL'],
protocols: ['EMAIL_PROVIDER'],
},
The engine capability names the framework need. The provider capability records an ability the provider contributes. The protocol selects its executable connection contract. defineSaaSProviders validates declarations against the discovered catalogue; the backend registry filters them again for its active scope.
Understand where the ability comes from
The provider module owns the corresponding ability declaration. Resend’s backend module includes:
providerCapabilities: [
BUILTIN_PROVIDER_CAPABILITY.EMAIL_TRANSACTIONAL,
],
secretsContract: {
apiKey: {
envVarName: "RESEND_API_KEY",
required: true,
description: "Resend API credential for email delivery."
}
},
The module’s protocol binding then supplies the email implementation. The application supplies the credential through its supported secret configuration and selects the provider for the enabled capability. The shared projection map derives engine capabilities from provider abilities rather than maintaining a second vendor-specific slot list.
Know when a capability selection is the wrong abstraction
| Integration | How it is addressed |
|---|---|
| Transactional email or a language model | A provider serving the enabled engine capability in the runtime scope |
| An enterprise REST API binding | The provider reference named by the binding |
| Organizations or application language support | Engine-implemented activation, not an external provider selection |
An enterprise API provider can therefore declare empty capability lists and still expose its REST protocol. Do not invent a slot merely to make every integration look alike. The capability map now checks that each engine capability is either mapped or explicitly engine-owned; adding an unaccounted capability is a compile-time error.
Provider tier and origin are additional declared metadata. They describe the provider’s role and provenance, not whether your application has enabled or configured it. Keep those questions separate when tracing why a provider is available.