Rules
The orishare.rule/v1 document: triggers, conditions, limits, actions, versions.
A rule is a JSON document validated on create and again on publish. Publishing writes an
immutable version; pausing, resuming and archiving change status without touching versions;
rollback publishes an older definition as a new version. The JSON Schema is available from the
rule-schema package and every validation error carries a rule_invalid.* code and a path.
{
"schema": "orishare.rule/v1",
"trigger": { "event": "order.paid" },
"conditions": {
"all": [
{ "path": "event.properties.total_cents", "op": "gte", "value": 5000 },
{ "path": "customer.tier", "op": "in", "value": ["silver", "gold"] }
]
},
"limits": [{ "id": "daily", "scope": ["customer"], "window": "day", "max": 3 }],
"actions": [
{
"type": "points.award",
"currency": "points",
"amount": "floor(event.properties.total_cents / 100)"
},
{ "type": "tier.evaluate", "program": "tp_…" }
]
}Paths
event.id | name | occurred_at | customer_id | properties.<key>, customer.id,
customer.attributes.<key>, customer.balances.<currency>, customer.tier,
customer.segments, customer.counters.<name>, now.
Operators
eq neq gt gte lt lte in not_in contains starts_with exists between within_last. Conditions
nest with all, any, not. A missing or mistyped value makes the leaf false and the trace
records the operand and its issue; unknown never matches, so "no email on file" is
{ "path": "customer.attributes.email", "op": "exists", "value": false }.
Limits
{ id, scope[], window?, max }: scope is any list of customer, event.* or
customer.* paths; window is none | day | week | month | year in the environment's timezone.
Limits are reserved before effects, all-or-nothing per rule, and survive rule edits that keep the
same id.
Actions
points.award / points.deduct (currency, amount as a number or a decimal expression,
optional confirm_after, expires_after, reason), reward.issue (reward),
tier.evaluate (program), attribute.set (attribute, value), webhook.emit (event).
Amount expressions support + - * /, floor, ceil, round, min, max over numeric paths.
Campaigns
A rule may belong to a campaign, which adds a schedule, a priority, an optional exclusive
stacking_group (highest priority wins), a budget shared across customers and an audience of
segments. Campaign checks happen before the rule's own conditions.