I had the clever idea this week of turning Fable loose to analyze all the places across the Critter Stack where we throw exceptions, then discuss those with me as an exercise in improving the troubleshooting skills here, and boy howdy did that turn into a huge pile of work to improve exception messages and validation across the entire stack!
We shipped Critter Stack AI Skills 1.14 today, and that brings the catalog to 121 skills. The headline this time is a set of eight troubleshooting guides that I'm genuinely excited about, but I want to use this release as an excuse to step back and make the larger case for why the AI Skills exist at all and what they actually buy you when you're building on the Critter Stack with a coding agent doing a lot of the typing.
If you haven't run across these yet, the short version is that the AI Skills are structured documentation written for the coding agent rather than for you. Not API reference -- the agent can already read that -- but the accumulated "here's what this actually means, here's the trap, here's what to check next" that otherwise only lives in the heads of the people who built the thing. I wrote up a whole session of an agent using them against a real codebase a while back if you want to see them working before you read any of my opinions about them.
The new troubleshooting guides
While we certainly try to make the stack traces from Marten, Wolverine, Polecat, or Fisher as usable as possible, the cause or the corrective action isn't always perfectly clear. The exception type is almost always correct and almost never sufficient. ConcurrencyException tells you what happened, but the interesting questions are whether a retry can possibly succeed, how you might use messaging features in Wolverine to avoid concurrent writes in the first place, which store threw it (for you folks getting aggressive with modular monoliths), whether the aggregate uses a numeric revision that your handler is re-storing by accident, and whether the Postgres detail was redacted before it ever reached your logs. An agent that only has the exception name can easily and confidently propose the wrong fix.
So for 1.14 we went through the whole family of exceptions each library can throw, one topic at a time, and wrote a skill per topic that starts from the exact message text and works backward to the cause and possible approaches to avoid getting the exception in the first place:
- Concurrency failures -- the whole
JasperFx.ConcurrencyExceptionfamily tree, which store throws which subtype, whatOnException<T>actually matches given that inheritance, when a retry is pointless, and the Wolverine.HTTP mapping to a409instead of a500. - Stream identity and collisions --
ExistingStreamIdCollisionException,NonExistentStreamException, archived streams, the Guid-vs-string identity refusal, and the rule that explains most of it: a plainAppendnever throws for a missing stream. - Projection and daemon exceptions -- the eight triggers for
InvalidProjectionException, what restarts a paused shard under each daemon mode, where each store keeps its dead letters, and why yourWaitForNonStaleProjectionDataAsynctest is timing out. - Schema management and migrations -- the
AutoCreatematrix as Weasel actually executes it, migration lock timeouts, and the raw42P01thatAutoCreate.Noneleaves behind for you to find in production. - LINQ across Marten, Polecat, and Fisher -- organized by query shape rather than by exception, because that's how you actually hit it. It also makes the argument that a LINQ refusal is a correctness guarantee, not a missing feature.
- Multi-tenancy -- unknown and disabled tenants, cross-tenant writes, and the four different tenant id casing behaviors across the stack that will absolutely split your data if you don't know about them.
- Messaging transports -- one cross-transport skill plus a reference page per broker (RabbitMQ, Azure Service Bus, SQS/SNS, Kafka, NATS, Pulsar, MQTT, Redis, SignalR) with every verbatim error message, its trigger, and the fix.
- Wolverine.HTTP binding and responses -- the startup refusals from
MapWolverineEndpoints, and the runtime cases where the status code is the only symptom you get: the415, the406, the400on unparseable JSON, and the404that means a missing entity.
Worth being honest about how these got written, because it's the same way most of the skills get written: we point an agent at a deliberately broken system, watch where it gets stuck or, worse, where it gets confidently unstuck in the wrong direction, then write down what it should have known. Several of these turned up real gaps in the libraries along the way, and those became GitHub issues rather than caveats in the skill.
Also in 1.14, we filled in some gaps with: batch message processing with BatchMessagesOf<T>, the new logical message deduplication features in Wolverine, scheduled and recurring cron messages in Wolverine, the full MartenOps side effect catalog, and three more CritterWatch operator skills for tenant operations, SQL over the event store, and stream compaction policies.
Now for the larger argument.
Without the skills, your agent thinks Wolverine is just another .NET tool
In no small part, Wolverine was and is conceptualized around the idea that typical enterprise .NET applications have far too much code ceremony and that you'll be much better off in the end with a lot less code ceremony and far fewer layers. In other words, Wolverine is meant to be the cure for the Clean/Onion Architecture poisoning that is far too prevalent in .NET circles.
Every coding agent in the world has been trained on an ocean of ASP.NET Core Minimal API and MVC code. Left to its own devices, an agent given a Wolverine.HTTP project will write Wolverine.HTTP code the way it writes Minimal API code: inject IDocumentSession or a DbContext into the endpoint, load the entity by hand, null check it, return Results.NotFound(), mutate, call SaveChangesAsync(), return Results.Ok(...). Then it'll add a separate validator class, probably a service class to "keep the endpoint thin," and maybe a repository interface for good measure because that's what the training data does. It all compiles. It all works. And it's three or four times more code than it needs to be.
Here's the idiomatic Wolverine.HTTP version of that same "approve an order" endpoint:
public static class ApproveOrderEndpoint
{
[WolverinePost("/orders/{id}/approve")]
public static (OrderApproved, IStorageAction<Order>) Post([Entity] Order order)
{
order.Status = OrderStatus.Approved;
return (new OrderApproved(order.Id), Storage.Update(order));
}
}The [Entity] attribute loads the Order from the route argument and answers 404 for you if it's missing. The IStorageAction<Order> return value is the persistence. The transaction is middleware. There's no session, no null check, no SaveChangesAsync, no Results.* wrapper, and no service class. The method is a pure function you can unit test without a database. I wrote a whole post on why this compression matters for agents specifically, and the short version is that the structure of your codebase is now effectively part of the prompt.
But an agent will only write the idiomatic version if it knows that [Entity], side effect return values, and the Wolverine.HTTP fundamentals exist and are the preferred shape. That's exactly what the skills are for. And the economics are pretty straightforward from there: fewer files means fewer tokens to generate, fewer tokens to read back into context on every subsequent change to that feature, and fewer places for the agent to get something subtly wrong. Terse, declarative code is cheaper code, and it stays cheaper every time someone touches it.
Opting into the optimizations you didn't know were there
The same idea applies to performance. Wolverine has a lot of opt-in optimizations that are close to free once you know the idiom, and that an agent will simply never discover on its own because they don't look like anything in the training data.
The one I point people at first is refactoring to batched loads. If a handler does three sequential reads -- load the order, load the customer, query the open line items -- the skill teaches the agent to recognize that those reads are independent, and to rewrite the handler so the [Entity] parameters and a query plan returned from a Load method all execute through one Marten batched query. One round trip instead of three, and the Handle method becomes a pure function as a side benefit. There are sibling skills for compiled queries and query plans, and the point of all three is that you can tell your agent "look for handlers that would benefit from batching and fix them" and have it actually know what that means.
Talking you through concurrency, parallelism, and ordering
Message-based systems have a category of questions that don't have a snippet-shaped answer. Should this listener be inline, buffered, or durable? Why did this message get processed twice? I need these messages handled in order -- why did Sequential() on the local queue not do that across my cluster? These are design conversations, and this is where I think the skills are most valuable, because they let the agent hold the conversation instead of guessing.
The endpoint modes skill walks through the delivery guarantee, the per-message database cost, and how long the broker holds a delivery unsettled for each mode, and it explicitly covers why the local ordering calls don't order a cluster and what does. The message routing skill covers parallelism and partitioned sequential processing, and the new batching skill has the gotcha that Sequential() does not sequence a batch against unbatched handlers. And when it does go wrong in production, the new concurrency troubleshooting skill knows the difference between a failure that a retry policy will fix and one it never can.
I've written at length about ordered messaging across a cluster and local queues in modular monoliths. The skills are how that reasoning gets into your agent's context at the moment it's deciding how to configure your listener.
The agent can run the diagnostics itself
Something I did not fully anticipate when we started this: the skills are at their best when they're paired with tooling the agent can actually execute.
The Critter Stack ships a lot of command line diagnostics, and the command line diagnostics skill teaches the agent when to reach for each one. describe to see what Wolverine actually discovered and how it's routing. db-assert to prove the schema matches before anything else. codegen test to catch a bad handler signature before deployment. event-query and stream-query to read the event store from the shell. And projection-run to replay your real projection code over real events and watch the state at every step. When an agent hits a stuck projection, it doesn't have to theorize; it can run the command, read the output, and tell you what it found.
If you're running CritterWatch, it goes a lot further. CritterWatch ships an MCP server, and there's a family of skills that turn it into an operator the agent can drive. Dead letter triage is the canonical example, and I showed what that looks like in practice a few weeks ago: "what's failing and why" followed by "replay the recoverable ones and discard the rest," and the agent knows not to report an empty queue when only half the databases have answered. This release adds three more to that family: tenant operations with the confirmation protocol a destructive call deserves, SQL over the event store, and stream compaction policies.
And to be explicit about the packaging, because people ask: the AI Skills are included with every JasperFx support plan and with every CritterWatch Professional or Enterprise purchase. If you have either, you already have them.
EF Core, SQL Server, and SQLite too
The skills are not Marten-only, and I want to say that plainly because it's a common assumption.
If you're on EF Core, the skills cover the transactional outbox setup, publishing domain events from your entities, EF Core sagas, and the Eager versus Lightweight transaction modes, plus a new project template for SQL Server or PostgreSQL. If you want the document database and event store experience on SQL Server, Polecat has a setup and decision guide that also lays out honestly when you'd pick it versus Marten. And for SQLite, Fisher covers the one-writer-per-file constraint, the Solo-only daemon, and database-per-tenant as a performance feature. The new LINQ and multi-tenancy troubleshooting skills above are deliberately cross-store for the same reason. There's also a skill on writing store-agnostic code for the folks who need to support more than one.
Where this is going: Event Modeling and Spec Driven Development
JasperFx is building toward a workflow where you start from an Event Model -- the slices, the commands, the events, the read models -- and the agent takes it from there: scaffold the executable specs for a slice, then write the implementation that makes them pass, in idiomatic Critter Stack code, without editing the spec to make it green. The AI Skills will be the glue that makes that all flow together.
There's already a skill for importing a declared Event Model and turning its slices into work orders, skills for scaffolding specs from a model and going from a failing spec to the implementation.
The coordination layer for all of that is a new tool we're calling Stoat. Stoat gives agents durable memory across sessions and a way to work through a plan that spans repositories, so one agent can wait on another's package publish instead of polling for it. I described the memory side in the search post because it's what drove the shared search API. Stoat will be a commercial tool, and it'll be included with the AI Skills when it's released, along with the support plans and CritterWatch that already bundle them. We'll be showing the whole Event Modeling flow end to end soon.
Getting the skills
The AI Skills are available standalone:
- Solo -- $250/year, for individual developers
- Team -- $1,000/year, for teams under 10 developers
- Team (Large) -- $2,000/year, for teams of 10 or more
All the plans are on the products page, and again, they're already included in every support plan and with CritterWatch Professional and Enterprise. The full catalog is browsable at ai-skills.jasperfx.net, and the install guide covers wiring them into Claude Code, Cursor, Codex, or any other agent that reads the agentskills.io format. Existing subscribers just take the 1.14 update.
If there's a corner of the Critter Stack you keep having to re-explain to your agent, tell us. That's genuinely how most of these get picked, and it's how the troubleshooting guides got to the top of the list for this release.



