Cephalon.Eventing.Wolverine
Maturity:
M3· Ownership: provider-managed · Family:eventing· See audit, matrix.
Cephalon.Eventing.Wolverine is an optional Wolverine companion package for Cephalon event-driven workloads.
What it owns
Section titled “What it owns”- wires the optional
WolverineFxruntime into a Cephalon host whenEventDrivenIntegrationis active - keeps Wolverine-specific host registration out of
Cephalon.EngineandCephalon.Eventing - exposes a dedicated
wolverine-adapterruntime surface underevent-driven-integration - publishes the
eventing.wolverinecapability so operators can see when the optional adapter choice is active - defaults to
dispatchBridge = consumer-managedwhen the pack is only being used for host wiring and runtime-surface projection - can opt into a
wolverine-manageddurable dispatch loop on top ofIEventDispatchStoreby enablingEnableDispatchLoop - schedules bounded fixed-delay dispatch retries through the shared dispatch-store eligibility contract and reports terminal
failedstate whenDispatchMaxAttemptsis exhausted - can opt into
wolverine-manageddeclared subscription execution on top of that staged-event dispatch loop by enablingEnableSubscriptionExecution - keeps managed subscription ownership explicit by requiring declared
IEventSubscriptionExecutorregistrations and projecting binding metadata back throughIEventSubscriptionExecutionBindingCatalogplus the shared eventing runtime surfaces - keeps managed subscription readiness explicit through
IEventSubscriptionExecutionReadinessCatalogandevent-subscriptionsmetadata such asexecutionReadiness,executionPath, andexecutionReadinessReasons - projects that managed loop back through hosted-execution, execution-graph, capability, and event-dispatch runtime surfaces without leaking Wolverine APIs into the core eventing contract
- schedules bounded fixed-delay managed subscription retries through Wolverine’s own scheduled-message pipeline instead of inventing a second retry subsystem, and reports terminal
failedstate whenSubscriptionMaxAttemptsis exhausted - contributes named dispatch-runtime descriptors that flow through
/engine/event-dispatch-runtimes,/engine/event-dispatches,/engine/event-dispatches/terminal-failures,/engine/outboxes, andsnapshot.EventDispatchRuntimes/snapshot.EventDispatchStates, with canonical aggregate summaries and terminal-failure counters projected back into those runtime descriptors - contributes a dedicated diagnostics convention so
/engine/diagnosticscan advertise the Wolverine loop and managed-subscription event ids and message templates alongside the shared eventing diagnostics catalog
Main surfaces
Section titled “Main surfaces”Configuration/WolverineEventingOptions.csModules/WolverineEventingModule.csRegistration/WolverineEventingEngineBuilderExtensions.csServices/WolverineEventDispatchHostedService.csServices/WolverineEventingDiagnosticsConventionContributor.csServices/WolverineEventingDispatchRuntimeContributor.csServices/WolverineEventingRuntimeSurfaceContributor.csServices/WolverineEventingRetryPolicy.csServices/WolverineManagedEventSubscriptionExecutorCatalog.csServices/WolverineManagedEventSubscriptionDispatcher.csServices/WolverineManagedEventSubscriptionExecutionProcessor.csServices/WolverineManagedEventSubscriptionExecutionRequest.csServices/WolverineManagedEventSubscriptionExecutionHandler.cs
How it fits
Section titled “How it fits”This package is intentionally thin, but it is no longer just a passive host-wiring shim. Cephalon now has a shipped Wolverine companion path that can be selected and introspected without pushing Wolverine APIs into the engine core, and it can optionally own both the durable staged-event dispatch loop and one truthful managed subscription-execution lane when the app deliberately enables that behavior.
Today the pack does three concrete things truthfully. First, it registers Wolverine host wiring and projects that choice back into Cephalon runtime introspection through eventing.wolverine and the wolverine-adapter surface. Second, when EnableDispatchLoop is turned on and a real IEventDispatchStore is available, it runs a hosted wolverine-managed dispatch pump that reads staged EventPublication payloads, publishes them through Wolverine, records durable dispatch outcomes, and reports execution/runtime metadata back through the shared eventing surfaces. DispatchMaxAttempts defaults to 3, can be set to 1 to disable dispatch retries, and causes both no-destination and Wolverine PublishAsync(...) exception paths on the final exhausted attempt to report failed with retryExhausted = true / terminalFailure = true metadata instead of re-entering pending dispatch forever. Third, when EnableSubscriptionExecution is turned on, EnableDispatchLoop is already active, EnableHostWiring is left on, and at least one declared IEventSubscriptionExecutor is registered, the same staged-publication flow can trigger wolverine-managed execution of matching declared subscriptions with bounded fixed-delay retry scheduling through Wolverine’s own scheduled-message pipeline. SubscriptionMaxAttempts defaults to 3, can be set to 1 to disable requeue retries, and causes the final exhausted attempt to report failed with retryExhausted = true / terminalFailure = true metadata instead of silently requeueing forever. That bridge is no longer limited to the Entity Framework outbox baseline; the current MongoDB, Redis, Elasticsearch, OpenSearch, Neo4j, Qdrant, and NATS outbox packs now register the same runtime-neutral dispatch-store contract as well.
That runtime story is now visible in several complementary places:
wolverine-adaptershows the adapter configuration plus aggregate dispatch state and managed-subscription state such asmanagedSubscriptionCount, retry-pending counts, and the latest observed outcome, all sourced from the canonical dispatch and subscription runtime summaries/engine/event-dispatch-runtimespublishes the named runtime descriptors such as the Wolverine-managed loop id, ownership metadata, the outbox/runtime ids it is responsible for, and a live aggregateSummaryonce dispatch reports start arriving, including terminal-failure observation counts, terminal outbox counts, andHasTerminalFailures/engine/outboxesnow also shows the effectiveDispatchPolicyfor each outbox, so the same managed loop is visible aswolverine-managed/runtime-managedwithout reading runtime-specific metadata by handevent-dispatchescan now project configured dispatch-runtime descriptor metadata for each outbox path before any runtime report exists, then layer the latest operator-facing report metadata,terminalFailure, andterminalFailureCounton top once dispatch activity starts/engine/event-dispatches/terminal-failuresfilters the live dispatch-state catalog to outbox paths whose latest report is terminally failed, without claiming broker-specific dead-letter ownership- dispatch retry metadata now reports
retryPolicy = bounded-fixed-delay,retryMaxAttempts,retryDelaySeconds,retryDurability = dispatch-store-delayed-eligibility,retryScope = provider-managed,routing = publishorrouting = no-destinations, and terminal failure posture when the Wolverine dispatch loop exhausts the configured attempt budget IEventSubscriptionExecutionBindingCatalogandevent-subscriptionscan now projectdispatchRuntime = wolverine-managed,subscriptionRuntime = runtime-bound,executionRuntimeId,executionOwnership,executionMode, andbinding.*metadata for the declared subscriptions this pack actually ownsIEventSubscriptionExecutionReadinessCatalogandevent-subscriptionscan now answer that the same subscriptions areruntime-boundwith an observed execution path and amanaged-binding-availablereason instead of forcing operators to infer readiness from adapter metadata- retry metadata now reports
retryPolicy = bounded-fixed-delay,retryMaxAttempts,retryDelaySeconds,retryDurability = wolverine-scheduled-message,retryScope = provider-managed, and terminal failure posture when a managed subscription exhausts the configured attempt budget eventing.subscribenow appears only when the managed subscription path is truly enabled, so capability discovery stops overstating what the pack owns/engine/diagnosticsnow exposes the Wolverine-specific diagnostics convention so host operators can discover the stable4300-4306event ids without reading the source
That means the package now has three truthful operating modes:
- baseline mode: Wolverine host wiring is active, while durable dispatch remains consumer-managed
- managed-loop mode: Wolverine owns the staged-event dispatch loop, reports
dispatchBridge = wolverine-managed, and keeps failed dispatch retry bounded through terminal failure metadata - managed-subscription mode: Wolverine owns execution for the declared subscriptions that have registered
IEventSubscriptionExecutorimplementations, with retry scheduling surfaced as part of the same runtime story
Those modes are optional companion behavior, not the definition of engine completeness. The engine side of that readiness lives in the runtime-neutral contracts and surfaces owned by Cephalon.Eventing; consumer apps can choose to install this companion, skip it, or later adopt a different companion pack without changing the core eventing contract itself.
The current managed-subscription baseline is intentionally narrow. It is triggered from the staged EventPublication dispatch flow rather than an arbitrary inbound broker-consumption path, it only owns subscriptions that have declared executors, and it currently uses bounded fixed-delay retry scheduling over Wolverine scheduled messages rather than a broader broker-owned retry vocabulary. The managed dispatch loop is also bounded on purpose: terminal failed dispatch observations stop the supported dispatch stores from returning that staged publication as pending again, but the package still does not claim broker-specific dead-letter queues, generic inbound consumption, or durable inbox ownership. The remaining work is therefore not to invent a first durable bridge from scratch, but to deepen observability, broader provider-native dispatch-store follow-through where a pack can truthfully persist dispatch outcomes, richer inbound-consumption stories when they are real, and later broker-specific follow-through on top of the same IEventDispatchStore, IEventSubscriptionExecutor, and IEventSubscriptionRuntimeReporter contract set. ClickHouse now stays explicit about the opposite answer: its outbox is visible to the runtime as DispatchPolicy.PolicyId = unsupported with ExecutionMode = disabled, so the Wolverine bridge and the shared eventing surfaces do not pretend the current analytics-first storage model already owns mutable dispatch state.
The showcase sample and test hosts can wire this package directly, so local and validation hosts can expose /engine/event-dispatch-runtimes, /engine/event-dispatches, /engine/event-dispatches/terminal-failures, /engine/outboxes, event-subscriptions, and matching snapshot answers without custom host-only code.