
Choose who answers, or send to every destination
Some integration needs should use one provider. Others, such as additional audit destinations, need every configured destination to receive the event. Wildo records that distinction in the capability itself.
Declare the providers each runtime may reach, then select a primary where the capability calls for one.
Example — One email service, several audit destinations
A product selects one transactional email provider for a message. Its configured audit sinks receive the event as additional destinations, rather than competing to become the primary sink.
For engineers
Declare candidates before choosing the primary
Wonder Todos declares providers under providers.scopes.backend.providers, then adds this selected part of the backend selection map:
[EngineCapability.AI_LLM]: {
primary: 'anthropic',
whenUnavailable: ['openai', 'google'],
},
[EngineCapability.EMAIL_TRANSACTIONAL]: {
primary: 'resend',
whenUnavailable: [],
},
Each selected provider must be discovered, declared for that runtime and able to serve the enabled capability. Backend, companion, browser services and workers have distinct scopes. A provider being present elsewhere in the application does not make it a candidate for this process.
Read substitutes as resolution order
The current field is whenUnavailable. It orders eligible substitutes after the primary during provider resolution; it does not retry a second vendor after the first vendor’s call fails. The registry filters candidates by declared capability and runtime scope, places eligible primary/substitute references first, then retains the other eligible references.
The select-one consumer takes the first resolved provider. Do not use a selection list as a claim of delivery redundancy. Application-specific retry or recovery must account for the actual operation and whether a failed call may already have been accepted.
Use fan-out for additive destinations
The capability resolution map assigns COMPLIANCE_AUDIT_TRAIL to FAN_OUT. The composite audit sink asks the registry for the resolved set and sends to the configured destinations. The application does not author a primary for this capability.
| Mode | Result of resolution | Appropriate expectation |
|---|---|---|
| Select one | One resolved provider | One provider answers the operation. |
| Fan-out | The eligible destination set | Each configured destination participates. |
| Substitute order | Candidate priority before execution | Another eligible provider can be selected when the primary is absent from the candidate set. |
The mapping is exhaustive over engine capabilities, so adding one requires choosing its resolution mode. Inspect the runtime’s resolved selection when validating setup; declared names alone do not establish that a remote service is reachable or that a send succeeded.
Observe and recover each destination independently
Selected from CompositeAuditLogSink.recordAuditEvent; sink resolution and the empty-set return are omitted. Each sink write has its own catch, so one rejected write does not cancel the other attempts.
await Promise.all(
sinks.map(async ({ ref, sink }) => {
try {
await sink.recordAuditEvent(event);
} catch (err) {
this.metricsService.recordAuditSinkFailure({ providerRef: ref });
console.error('[audit] provider sink failed (non-fatal)', {
providerRef: ref,
...projectCaughtErrorLogFields(err),
});
}
}),
);
The failure metric identifies the destination that needs attention. A returned fan-out call is not an acknowledgment from every remote destination. This boundary catches individual sink-write failures; it does not make every surrounding operation infallible.
Recovery depends on the sink contract. The completeness reconciler replays database events for sinks that implement both checkpoint methods; a fire-and-forget SIEM webhook is not in that checkpointed set. Configure monitoring and recovery for the actual destination rather than assuming fan-out provides one universal retry or exactly-once guarantee.