Decision
Declarative JSON DSL, versioned, deliberately restricted so per-event incremental evaluation is possible: typed profile attribute conditions · event aggregates with window (count, sum(property), first_seen, last_seen over event_name in last-N-days|all-time) · membership in other segments (acyclic) and tiers · AND/OR/NOT. Covers RFM (recency=last_seen, frequency=count, monetary=sum). Prebuilt RFM templates ship per vertical taxonomy.
Membership materialized in core.segment_members with entered_at/exited_at history; diffs emit segment.entered|exited. Segments whose conditions are not incrementally evaluable are flagged nightly_only at creation — the builder tells the user. Full recompute per tenant runs at the data-freshness tier (nightly default) as the safety net.
Consequences
- Real-time segment triggers with bounded compute. − Expressiveness ceiling; extending the DSL is an explicit versioned change, never ad-hoc.