Skip to content

Workflow

The Workflow screen answers one operator question: "Where does this message, event, or saga fit in the system?" You give it a type name; it traces that type across every monitored service and draws the result as a diagram. It works for any messaging application, not just event-sourced ones.

Reach it from the Explore → Workflow sidebar item (/workflow).

One model, two views

CritterWatch assembles a single workflow model on the server by unioning three sources:

  • inferred — the static structure read from your code's signatures (handlers → emitted/cascaded messages → projections),
  • observed — the causation and event-append edges actually seen at runtime,
  • confirmed — edges present in both.

That one model is then rendered two ways via the view-mode toggle in the scope bar:

  • Sequence (default) — a Mermaid sequence diagram reading top-to-bottom through the cascade.
  • Event Model — the formal Event Modeling swim-lanes over the same model (see Event Modeling).

Switching views never re-queries — it's the same model drawn differently.

Tracing a type

The scope bar drives everything:

  • Service select — "All services" by default. This is a display scope (the trace itself is always fleet-wide); narrowing it emphasises one service's nodes and decides which service's trace provider the per-instance lookup queries.
  • Subject input — a message, event, or saga type, e.g. OrderPlaced (short name or fully-qualified). Press Enter or click Trace.
  • Depth stepper (1–10) — how far the cascade expands. When the model is capped you'll see a "Truncated at depth N — increase depth to expand the cascade" note.

Deep links: /workflow?type=Fully.Qualified.Name pre-seeds the subject and traces automatically. The View in Workflow / "Where does this fit?" buttons on message-type, handler, and topology displays route here with that query. The old /lifecycle?type= URL redirects here and keeps its query, so existing bookmarks still resolve.

Reading the diagram

  • Sequence mode nodes are clickable: a handler routes to its handler-chain detail, a projection to its projection detail — so the diagram is a navigation surface, not just a picture.
  • A provenance legend (sequence mode, before you load an instance) explains the edge styles: --> inferred (structural), ◆ observed (runtime), ✓ confirmed (source + runtime).
  • A seed line names the subject (type + kind + the services it was found in), and a gaps list explains anywhere the model couldn't be completed.

If the trace returns but every service shows as unreachable, the diagram falls back to runtime-observed edges only (no static structure) — usually because the sample services don't ship the event-model responder. The trace still renders what it has rather than blocking.

"What happened" — per-instance lookup

The per-instance bar turns the abstract workflow into the concrete history of one saga or correlation:

  • Instance id — the saga-id / correlation-id value — plus the What happened? button.
  • Correlation tag (optional) — override the discriminating tag key; otherwise CritterWatch auto-resolves the saga's {SagaName}Id and shows "matching <tagKey>".

The result card stitches together all correlated OTel traces for that id into one "what happened" sequence, including scheduled re-entrances (saga timeouts, deferred commands). This is pulled on demand from the OTel backend you bound under Settings → Service trace binding — so an empty result means either no trace provider is bound for that service or the spans have aged out of the provider's retention window.

Past vs. still-to-come

Once an instance is loaded, the legend flips to ✓ observed (N) / ⟳ still to come (N) and the diagram fuses the two in both view modes: edges already seen for this instance render solid, while edges the model expects but hasn't observed yet render dashed. It's the difference between "what this saga did" and "what it will do next."

Free for read-only monitoring. A commercial license is required for administrative actions and the MCP server.