Reference

Thread catalog.

What a thread definition looks like. Reference template, not a product spec. Copy the form, fill in your own threads.

Why publish this.

A thread catalog is the first artifact a substrate-first team produces. It comes before any UI is drawn, before any agent is wired, before any event handler is written. It's the document the rest of the system answers to.

This page shows you what a thread definition looks like — the shape, not the contents. The example below is a generic order lifecycle. Your domain might be cases, shifts, visits, campaigns, or claims. The form stays the same.

Calibration (timing intervals, escalation hierarchies, channel trust scores) is per-engagement and lives in your own catalog. Don't copy the numbers below. Copy the structure.

The template.

Each thread in your catalog should have the following fields. Treat the catalog as an append-only document: new threads get added, existing threads get versioned, threads are never quietly deleted.

thread: {thread.name}
  description: One sentence. What lifecycle does this thread track?
  trigger:
    event: {event.name}
    source: which system / persona / channel emits the trigger
  terminal_events:
    - {event.name}  # describe each outcome explicitly
    - {event.name}
  expected_sequence:
    - step: {step.name}
      from_event: {event.name}
      to_event: {event.name}
      heartbeat:
        fires_after: {duration}
        on_fire: generates event {heartbeat.event.name}
        escalation: which persona, which surface
  context_attached:
    - {context.field}      # what enriches each event on this thread
    - {context.field}
  personas_involved:
    - {persona.name}: what decisions this persona owns
  policy_guardrails:
    - {rule}  # actions that never auto-route regardless of confidence
  notes: free text on edge cases, prior incidents, calibration history

One example: order lifecycle.

A generic B2B order from arrival to terminal outcome. The vocabulary is illustrative — replace with your domain.

thread: order.lifecycle
  description: |
    One B2B order from arrival through fulfillment to a terminal
    event (delivered, returned, written off, or cancelled).
  trigger:
    event: order.received
    source: channel.{marketplace|edi|portal|email}
  terminal_events:
    - order.delivered            # happy path
    - order.returned             # buyer-initiated return
    - order.written_off          # admin-finalized exception
    - order.cancelled            # cancelled before fulfillment
  expected_sequence:
    - step: intake
      from_event: order.received
      to_event: order.acknowledged
      heartbeat:
        fires_after: PT15M
        on_fire: generates order.intake_stalled
        escalation: ops_manager, action_queue
    - step: allocation
      from_event: order.acknowledged
      to_event: order.allocated
      heartbeat:
        fires_after: PT30M
        on_fire: generates order.allocation_stalled
        escalation: ops_manager, action_queue
    - step: pick_and_pack
      from_event: order.allocated
      to_event: order.packed
      heartbeat:
        fires_after: PT4H
        on_fire: generates order.fulfillment_stalled
        escalation: floor_lead, watch_face_complication
    - step: handoff
      from_event: order.packed
      to_event: order.handed_to_carrier
      heartbeat:
        fires_after: PT12H
        on_fire: generates order.handoff_missed
        escalation: ops_manager, approval_surface
    - step: in_transit
      from_event: order.handed_to_carrier
      to_event: order.delivered
      heartbeat:
        fires_after: {sla_per_service_level}
        on_fire: generates order.transit_overdue
        escalation: customer_service, pinned_chat
  context_attached:
    - customer.history
    - customer.chargeback_rate
    - warehouse.on_time_rate
    - carrier.service_level
    - sku.value
    - sku.fragility_flag
    - channel.trust_score
  personas_involved:
    - ops_manager: approves expedites, swaps warehouses
    - floor_lead:  signs off picks, handles equipment exceptions
    - customer_service: writes back to buyer on disputes
    - finance:     approves credits, writes off losses
  policy_guardrails:
    - chargebacks above {threshold} never auto-respond
    - returns to first-time buyers always notify customer_service
  notes: |
    Allocation heartbeat tightened from 60m to 30m after the
    Q4 stockout incident. See ADR-014.

How to use this.

If you're starting fresh: write your top three or four threads first. The big ones — the lifecycles that touch every persona on your team. Get those right and the smaller threads fall out as variants.

If you're retrofitting an existing product: walk the database. Every table whose rows have a clear beginning and end is a thread. Every status column is a terminal-event hint. Every cron job that nags a stale record is a heartbeat that should be made explicit.

The catalog is a living document. Add a thread when a new lifecycle shows up in your business. Version a thread when its expected sequence changes. Don't quietly mutate fields — that loses the record of why decisions were made.

Pair the thread catalog with a stimulus channels reference. Threads tell you what lifecycles exist; stimulus channels tell you how events arrive.

Build your own.

If you'd like help writing a thread catalog for your product, see substrate audits. Or read how we build for the six-step method this artifact lives inside.