Skip to content

Steps

A job runs an ordered chain of steps. Each step implements IWorkflowStep and registers itself in the StepRegistry (registration is env-gated — a step only appears when its dependency is configured).

The registered steps

StepAvailabilityWhat it does
readalwaysPulls from a source (Gmail / web / CDP scraper) via platform-ingestion.
analyzeLLM key setA cheap LLM pre-filter before paying for scraping in enrich.
enrichLLM key setScrapes + enriches content via IContentEnricher.
exportany IExportTarget existsDispatches by config.destination: notion, email_digest, social_post, blog_post.
publishalwaysSelf-sourcing social publish worker — selects its own due drafts.
publish_blogalwaysSelf-sourcing blog publish worker.
read_quote_requests / mark_quote_requests_reviewedalwaysDB-backed quote-request steps.
triageLLM key setFlagged Gmail thread → kanban Task.
watchalwaysGeneric numeric monitor-and-alert (see below).

Export destinations

ExportStep dispatches on config.destination, with keys canonical in EXPORT_DESTINATIONS (shared by presets and buildJobs so they can’t drift):

  • notionNOTION_INTEGRATION_TOKEN
  • email_digestRESEND_API_KEY
  • social_post ⇐ an LLM key
  • blog_post ⇐ an LLM key

ExportStep threads context.metadata.userId into the destination config — the tenancy seam that owner-scopes social / blog drafts.

The watch step

watch is the subject-agnostic monitor-and-alert primitive. For each upstream item it appends an Observation to an append-only numeric time-series, then applies a targetValue / dropPercent guard against a baseline (lowest_seen / rolling_avg_30d / first_seen) computed from prior history. It can optionally LLM-confirm via a Skill, and emits a price-alert Task that is idempotent on <subjectId>@<value>. Classifieds price is consumer #1, but it works for any numeric subject (a Qonto balance, an SLA latency, …).