Seedy Pea

Topology Config

The CLI compiler accepts TOML, YAML, and JSON, then normalizes the source into a versioned topology snapshot.

npx seedypea compile seedy-pea.yaml --out seedy-pea.config.json

Normalized Shape

{
  "version": 1,
  "source": "/absolute/path/seedy-pea.yaml",
  "tenant": "ten_123",
  "identity": [],
  "computed": [],
  "segments": [],
  "triggers": [],
  "temporal": {
    "segments": [],
    "traits": []
  },
  "reactors": []
}

tenant

Required string.

tenant: ten_123

identity

Declare identity fields and merge rank.

identity:
  by:
    - type: email
      rank: 100
      normalize: lowercase_trim
    - type: shopify_customer_id
      rank: 90
    - type: anonymous_id
      rank: 10

TOML object form is also accepted:

[identity.email]
rank = 100
normalize = "lowercase_trim"

[identity.anonymous_id]
rank = 10

Each item normalizes to:

Field Required Description
type yes Identifier type name.
rank yes Numeric merge strength.
normalize no Optional normalization name.

computed

Named expressions that update profile traits or other computed fields.

computed:
  traits.page_views:
    on: PageViewed
    expr: (profile.traits.page_views ?? 0) + 1

  traits.last_seen_at:
    on: "*"
    expr: event.at

Each entry normalizes to:

Field Default Description
name key Computed field name.
on * Event type that wakes the expression.
expr required Expression source.

segments

Named segment expressions.

segments:
  known:
    expr: Boolean(profile.ids.email)

  high_intent:
    expr: |
      profile.traits.lifecycle_stage === "evaluating" &&
      (profile.traits.page_views ?? 0) >= 3

Segments use the same normalized entry shape as computed: name, on, and expr.

triggers

Boundary events emitted when a segment changes.

triggers:
  score_high_intent_lead:
    boundary: high_intent
    enter: LeadScoreNeeded
    exit: LeadScoreNoLongerNeeded
Field Required Description
boundary yes Segment or boundary name.
enter no Event emitted on entry.
exit no Event emitted on exit.

temporal

Lists segments and traits that should retain temporal history.

temporal:
  segments:
    - high_intent
  traits:
    - lifecycle_stage

Both fields default to empty arrays.

reactors

Reactors are passed through by the current compiler. The section must be an array.

reactors:
  - name: score_high_intent_lead
    wake:
      event: LeadScoreNeeded
    run:
      type: mothad
      job: lead_score
      max_cascade_depth: 3
      debounce_seconds: 3600

The legacy key actions is accepted as an alias for reactors.