Understanding your system
Most of the console answers operational questions — is it healthy, is it keeping up, what's in the dead-letter queue. A second, quieter set of screens answers a structural question instead: what is this system, actually? They read your running Critter Stack application back to you — its message flows, its event model, its generated HTTP surface, the DDL it installed — assembled live from the code and the runtime rather than from a diagram someone drew once and forgot to update.
This page is a map of those reflection surfaces and the order to reach for them. Each has its own reference page; this is the "which one, and when."
Why it stays honest. Hand-drawn architecture diagrams drift the moment someone ships a change. These surfaces don't: every one is derived from what's running — the assembled lifecycle model, Wolverine's own
ActivitySource, the projection code the service actually executes, the schema Marten/Wolverine actually installed. If the picture is wrong, the system is wrong, not the doc.
The question each surface answers
| Surface | The question it answers | Scope |
|---|---|---|
| Workflow | Where does this message / event / saga fit? | Fleet-wide, seeded on a type |
| Event Model | What is the command → event → projection → read-model shape, and do my sources agree about it? | Fleet-wide, merged across every source |
| Conversations | What actually happened to this one message instance? | A single concrete request, across services |
| Message Topology | Who produces this message, and who handles it? | Fleet-wide routing graph |
| HTTP chain detail | What did Wolverine generate for this route? | One HTTP endpoint |
| Projection Stepper | What is this projection doing on this stream? | One projection over one slice of events |
| DDL viewer | What schema did the stack actually install? | One store's durability / projection tables |
Two axes: shape vs. behaviour
The surfaces split along one line — what the system can do (static shape, read from code and declared structure) versus what it did do (observed behaviour, read from the runtime).
- Shape — Workflow, Event Model, Message Topology, HTTP chain detail, and the DDL viewer describe the possible: every path a type can take, every lane an event-sourced flow occupies, the C# and OpenAPI Wolverine emitted, the tables that exist.
- Behaviour — Conversations and the Projection Stepper replay the actual: the real send/receive/ execute chain one request set off, the per-event before/after state one projection produced.
Workflow sits deliberately on the seam — it unions inferred (static code structure), observed (runtime causation edges), and confirmed (both), so a single graph shows you where the drawn shape and the lived behaviour agree and where they don't.
A reading order
When you're trying to understand an unfamiliar corner of the system — a service you didn't write, an incident in a flow you don't own — the surfaces compose top-down, broad to narrow:
- Start with the shape. Seed Workflow on the type at the centre of your question and follow it across service boundaries, or switch that screen to its Event Model view for the fleet's command → event → projection spine as canonical Event Modeling slices. Message Topology is the routing-only view when you just need "who sends, who handles."
- Drop into one instance. When the static shape raises a "but did this one make it through?" question, switch to Conversations and open the concrete message instance — the real causal graph, captured with no tracing backend to stand up.
- Drill into the internals. From there the fine-grained tools take over: HTTP chain detail for the generated code + OpenAPI of a route, the Projection Stepper to step a projection row-by-row over a slice of a stream, and the DDL viewer for the exact schema the stack installed.
The Event Model drill-downs tie the levels together: click a handler card for its handler-chain detail, a projection card for its projection detail, a message or event card to re-seed the whole screen on that type — so you can move from "here's the shape" to "here's the code" to "here's what it did" without leaving the thread.
Richer with the source generator
Every surface renders from runtime observation alone, filling in as messages actually flow. A service that references CritterWatch.SourceGeneration additionally contributes a statically-discovered manifest, so its Workflow graph comes through fully populated before any traffic — the shape is known from the code, not inferred from load. Both render; the source-generated service is simply richer up front.
⚠️ That generator enriches the lifecycle, not the Event Model's slices: it emits aggregates, handler relationships and sagas, and explicitly no slices. The Event Model's derived half comes from the IEventModelDefinitionSource implementations registered in your app — which every Wolverine host has one of already.
On the roadmap: declared-vs-implemented drift
The strongest form of "reads your app back to you" is drift detection: comparing what a service declares it does (an EventModelDefinition) against what it actually implements, and flagging the gaps — a handler you built but never declared, or a declared step with no matching handler.
Part of this has landed. The Event Model is assembled from several sources and the merge emits a SourceDisagreement hotspot where two of them describe the same slice differently — most often production doing something the code does not say it does. And where a Bobcat spec monitor is bound, each slice chip carries an evidence dot that flags drift between a slice and the specifications bound to it. The per-node declared / drift / missing status pills an older revision of this section pointed at were on the retired per-service swim-lane and no longer exist.
What is still missing is the declared rung itself: CritterWatch registers no hand-written overlay of its own, so nothing in the console's own merge can claim Declared. An overlay declared in your app arrives through that service's pushed manifest.
