skills/wolverine/SKILL.md
WolverineFx (.NET) framework for in-process command/event handling, asynchronous messaging, durable inbox/outbox, sagas, and HTTP endpoints. Use when working in a .NET project that references `WolverineFx*` packages, calls `UseWolverine()`, or whenever the user asks about Wolverine handlers, message routing, transactional outbox, transports (RabbitMQ, Azure Service Bus, SQS, Kafka, NATS, Pulsar, PostgreSQL, SQL Server, Redis, MQTT, etc.), Wolverine.HTTP endpoints, Marten/EF Core/RavenDb integration, sagas/process managers, middleware, cascading messages, side effects, FluentValidation integration, tracked-session testing, or migrating to/from MediatR/NServiceBus/MassTransit. Also applies to Critter Stack and JasperFx conversations that mention Wolverine.
npx skillsauth add jakenuts/agent-skills wolverineInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
WolverineFx is a .NET runtime for command execution and message handling. One mental model covers many use cases: a method handles a message; the rest is just where the message comes from and what happens after it succeeds.
WolverineFx.Http exposes methods as ASP.NET Core endpoints with the same conventions.CQRS and event sourcing are one thing Wolverine pairs well with (via Marten), but most features apply equally to plain command/event-driven services, modular monoliths, vertical-slice web apps, background workers, and ETL pipelines. Do not assume a Wolverine question implies event sourcing.
If you only need the API shape for a specific topic, read the matching reference file below and skip the rest. The list below is the index — load only what you need for the current task.
| Reference | Load when... |
|-----------|-------------|
| references/handlers.md | Writing or modifying a handler: discovery rules, signatures, cascading messages, side effects, return types, error policies, FluentValidation, [Entity] loading. |
| references/messaging.md | Sending/publishing/scheduling messages, routing rules, listener config, local queues, conventional routing, topics. |
| references/transports.md | Configuring a specific broker (RabbitMQ, Azure Service Bus, SQS, Kafka, NATS, Pulsar, MQTT, Redis, PostgreSQL/SQL Server transport). |
| references/http.md | Building or migrating WolverineFx.Http endpoints, mediator-style routes, response/request conventions. |
| references/durability.md | Enabling inbox/outbox, idempotency, dead letter storage, claim checks, transactional middleware. |
| references/persistence.md | Picking/wiring Marten, EF Core, or RavenDb integration; sagas; multi-tenancy; event sourcing aggregate handlers (only when actually using event sourcing). |
| references/middleware-and-policies.md | Writing conventional middleware, policies, attributes; modifying handler chains. |
| references/testing-and-ops.md | Tracked-session integration tests, command-line diagnostics, codegen, logging, health checks, AOT/cold-start tuning. |
| references/patterns.md | Architectural shape: vertical-slice, modular monolith, mediator-only, railway, ping-pong, leader election, MediatR/MVC/MinAPI migration. |
A Wolverine application is WolverineOptions configured on the .NET Generic Host:
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseWolverine(opts =>
{
// routing, transports, durability, policies go here
});
var app = builder.Build();
// Opt into JasperFx CLI commands for `dotnet run -- describe|codegen|...`
return await app.RunJasperFxCommands(args);
IMessageBus is scoped, injected via DI, and is the single entry point at
runtime:
await bus.InvokeAsync(new DebitAccount(1111, 250)); // run handler now, await result
var status = await bus.InvokeAsync<AccountStatus>(cmd); // request/response
await bus.SendAsync(new DebitAccount(1111, 250)); // requires at least one subscriber
await bus.PublishAsync(new AccountOverdrawn(1111)); // fire-and-forget, OK with 0 subscribers
await bus.ScheduleAsync(new ReminderDue(id), 1.Days()); // delayed
A handler is any public method on a public class with a name like
Handle / HandleAsync / Consume / ConsumeAsync on a class suffixed
Handler or Consumer (or marked [WolverineHandler] / IWolverineHandler).
The first parameter is the message; the rest are method-injected from DI:
public static class DebitAccountHandler
{
public static IssueDebited Handle(DebitAccount cmd, IDocumentSession session)
{
// ...mutate state, return event
return new IssueDebited(cmd.AccountId);
}
}
Return values are not just data — they're cascading messages, side effects, or storage actions (see handlers.md). This is what lets handlers stay pure functions.
These are the things agents trip over. Read this section before touching unfamiliar handler code.
dotnet run -- codegen write writes the generated code to Internal/Generated/ so you can read what Wolverine is actually doing — use this when something seems "magic".AddSingleton<T>() / AddScoped<TInterface, TImpl>() / constructor injection. Opaque lambda factories (AddScoped<T>(sp => ...)) that handlers consume now throw at startup (Wolverine 6); use opts.CodeGeneration.AlwaysUseServiceLocationFor<T>() only as a deliberate escape hatch.IncludeInternalTypes).IMessageBus. Inject it as a method parameter when you need it; otherwise prefer returning cascading messages so handlers stay testable as pure functions.[assembly: WolverineModule] or opts.Discovery.IncludeAssembly(...).Static/Auto codegen mode, delete the stale file under Internal/Generated/ (or run dotnet run -- codegen write).InvokeAsync only auto-applies Retry policies from your error rules. Requeue, Discard, MoveToErrorQueue, and PauseThenRequeue are silently ignored when invoking inline — exhausted retries propagate the exception back to the caller. If you need dead-letter semantics on synchronous invocation, catch it yourself or use bus.SendAsync so a listener processes it.SendAsync throws when no subscriber exists — IndicatesNoHandlersException. If a handler "doesn't fire" after SendAsync, check the exception first (see testing-and-ops.md → diagnostics recipes); use PublishAsync for events with 0+ subscribers.PublishAsync / SendAsync are in-memory by default. A crash between the handler returning and the broker accepting the message loses the event. Enable the outbox in durability.md when you need guaranteed delivery — coming from MediatR's in-process INotification model, this is the trap most teams hit first.opts.Policies.AutoApplyTransactions() or [Transactional], the middleware calls SaveChangesAsync() / Marten SaveChangesAsync() for you and flushes the outbox in the same transaction. Calling it yourself produces a second commit and breaks atomicity.[Aggregate], IEvent<T>, event forwarding). Skip persistence.md's event-sourcing section unless the user is actually using IDocumentSession.Events or Marten projections.InvokeAsync if you need synchronous semantics; configure opts.LocalQueue(...) to tune parallelism and durability.Before debugging routing, handler discovery, or codegen issues, run:
dotnet run -- describe # full configuration dump: handlers, routes, endpoints, options
dotnet run -- codegen preview # see the generated adapter code Wolverine produced
dotnet run -- codegen write # persist generated code into Internal/Generated/
dotnet run -- check-env # validate environment & connectivity (transports, message store)
dotnet run -- resources setup # provision broker/db resources Wolverine knows about
opts.DescribeHandlerMatch(typeof(SomeHandler)) prints a textual report
explaining why Wolverine did or did not pick a type up as a handler. Reach
for it when handlers "go missing".
handlers.mdmessaging.md, plus transports.md for the specific brokertransports.mdhttp.mddurability.md, plus persistence.md for the storepersistence.md (sagas section)middleware-and-policies.mdtesting-and-ops.mdpatterns.mdpatterns.md#mediator-only (start here for MediatR-replacement use cases)development
WordPress content management via REST API for managing posts. Requires Node.js and WordPress REST API credentials.
tools
Search and analyze DealerVision production logs via SolarWinds Observability API. Use when investigating errors, debugging issues, checking system health, or when the user mentions logs, SolarWinds, production errors, or system monitoring. Requires the `logs` CLI tool to be installed.
tools
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
development
Sentry error monitoring and issue tracking skill for retrieving issues, events, and project health data. Use when working with error tracking, exceptions, crashes, debugging production issues, or analyzing error patterns.