Concepts
Understand facts, definitions, evaluation, derived state, and delivery in Kite.
Kite is an event-driven Customer Success as Code engine. Product behavior enters as facts; versioned TypeScript definitions explain what those facts mean; the state engine computes what is true for each customer now.
events + current traits + configuration
|
v
state engine
|
v
lifecycle, journeys, segments, health, rule logs, and emissionsCustomer Success as Code
Activation, risk, and health are product logic. In Kite, that logic lives in source control rather than hidden dashboard settings.
This makes definitions:
- explicit: each outcome has concrete conditions;
- reviewable: changes appear in pull requests;
- versioned: deployed snapshots are immutable and auditable;
- testable: events can be evaluated locally or in
test; - replayable: retained history can be recomputed under a pinned version;
- explainable: state changes retain their trigger and rule context.
Configuration deployment changes interpretation; it does not rewrite raw product history.
Facts and interpretation
Kite separates what happened from what it means.
| Layer | Example | Behavior |
|---|---|---|
| Event | report.exported at a specific time | Immutable historical fact |
| Trait | plan: "growth" | Current customer attribute |
| Definition | Three exports complete an outcome | Versioned interpretation |
| Derived state | Journey complete, health 82 | Computed result |
Events have occurrence timestamps and can be replayed. Traits are shallow-merged current state; they are not timestamped historical facts. During recompute, current traits apply across the retained event history.
See Identity and event taxonomy before choosing IDs, traits, and event contracts.
One customer boundary
A Kite customer is normally one account, workspace, or tenant identified by customerId. Every
event, trait update, and derived state is scoped to that ID, project, and environment.
Kite does not merge aliases or infer a user-to-account hierarchy. Choose a stable customer boundary in the source system and use it consistently across producers.
Configuration primitives
The primitives answer different questions and should not be treated as interchangeable.
Lifecycle
Lifecycle answers: Which one stage is the customer in?
States are mutually exclusive. A customer starts in initialState; matching enteredWhen
conditions transition it to another state. exitWhen returns to the previous valid state, and a
terminal state is not left automatically.
Use lifecycle for durable stages such as new, trial, activated, or cancelled, not for every
temporary operational label.
Journeys
Journeys answer: How far has the customer progressed through an ordered outcome?
A journey starts from a condition, advances required steps in order, can complete optional steps opportunistically, and may expire. Completed and expired instances do not restart automatically.
Use journeys for onboarding, implementation, adoption, or renewal paths with identifiable milestones.
Segments
Segments answer: Which non-exclusive cohorts match now?
A customer can belong to many segments simultaneously. Membership is recomputed from lifecycle, health, events, traits, and other conditions when relevant triggers occur.
Use segments for queues such as at_risk, high_intent, or expansion_candidate.
Health
Health answers: What continuous score summarizes selected behavior?
Weighted components produce a current score from event frequency, feature adoption, inverse event counts, or deterministic custom formulas. Health is an explainable summary, not a prediction.
Only configured event, schedule, or manual triggers recompute health. Time does not update a score without evaluation.
Rules
Rules answer: When this trigger occurs and these conditions are true, what action follows?
Rules run on matching events, journey changes, or schedules. A passing rule can transition
lifecycle, add a customer to a segment, or emit a named signal. Each evaluation produces a rule
log with pass or skip.
Signals and emissions
An emission is a named internal timeline event produced by lifecycle, journey, segment, or rule behavior. A matching webhook can deliver that event externally.
Declarative defineSignals definitions register signal IDs and detection metadata. Automatic
first-occurrence and average-based signal detection is not currently executed by the state engine;
rules can emit registered signals explicitly.
Shared conditions
Lifecycle, journeys, segments, and rules share a composable condition language:
{
all: [
{ lifecycle: 'trial' },
{ eventCount: { event: 'feature.used', days: 7, min: 3 } },
{ not: { traits: { plan: 'free' } } },
],
}Conditions describe truth, but evaluation still needs a trigger. For example, inactivity becomes true as time passes, but state changes only when scheduled or event/recompute processing evaluates that condition.
Evaluation model
For each event, Kite updates facts and evaluates dependent state in a deterministic sequence. The engine can process lifecycle, journey progress, matching rules, health triggers, and segment membership from the same event.
The important contract is not a specific internal call order; it is that the same inputs produce the same result:
same retained events
+ same current traits
+ same config version
+ same evaluation time
= same recomputed stateEvents are ordered by occurrence timestamp and then event ID during recompute. Custom health
formulas cannot use external bindings or nondeterministic values such as Date.now() and
Math.random().
Current state, history, and timeline
These records serve different purposes:
| Record | Purpose |
|---|---|
| Raw events | Immutable product facts used for replay |
| Current state | Fast answer to what is true now |
| Lifecycle and rule history | Explanation of transitions and evaluations |
| Timeline events | Named operational facts and emissions |
| Webhook delivery | At-least-once transport of eligible timeline events |
Recompute rebuilds derived state from retained raw events, but it does not make every history type equivalent. It may also append corrective emissions without deleting older timeline rows. See Backfill and recomputation for exact persistence behavior.
Idempotency
Retries must not duplicate product activity. A track idempotency key is scoped to project and environment.
- Same key and canonical payload: return the original event as a duplicate.
- Same key with a different customer, event, properties, or timestamp: return
409 IDEMPOTENCY_CONFLICT. - Conflict inside a batch: reject the whole batch atomically.
The Node.js SDK generates keys when retries are enabled. Supply a stable business key when the source operation already has one so deduplication also works across processes.
Webhook idempotency is separate: receivers deduplicate the stable Kite-Event-Id because delivery
is at least once.
Configuration versions
The CLI compiles authored TypeScript into a stable snapshot. Each deployment creates an immutable version for one environment.
source files -> validate -> compiled snapshot -> test version -> live promotionPromotion copies the exact stored test snapshot to live; it does not recompile local source. Rollback activates an existing version for future evaluation. Neither operation automatically recomputes existing customers.
See CI/CD and environment delivery for the release workflow.
Test and live
test and live isolate:
- API keys;
- customer identities and event history;
- active configuration versions;
- computed state and webhook subscriptions.
Keys encode the environment with kt_test_ or kt_live_. Develop and exercise models in test,
then promote an immutable tested version deliberately.
Local, test, and live
| Mode | Use | Persistence |
|---|---|---|
kite dev | Fast event-to-state feedback | In-memory and disposable |
test | Shared integration and historical impact testing | Persistent, isolated cloud data |
live | Production evaluation and delivery | Persistent production data |
Local state resets when kite dev stops. A successful local result proves model behavior, not
cloud authentication, billing, workers, or webhook delivery.
Next steps
- Build a local model with the 5-minute quickstart.
- Learn each field in the Config Reference.
- Choose stable facts with Identity and event taxonomy.
- Model one outcome with Activation, churn, and expansion.