Write the rule.
Chalk brings the data.
This live demo lets you watch a rules engine request exactly the features that fraud and risk rules reference from Chalk: windowed aggregations, lookups, enrichments and a model score, computed at decision time.
See a rule pull only the features it needs
Choose an event, inspect its decision, then change one rule to see the data request change.
Try this experiment · expected results
1Inspect a login decision
Select a login event and compare fired rules, feature values, and the query.
Expected: The request contains the features needed by enabled rules.
2Enable the model rule
Turn on takeover_model and run the same event again.
Expected: The model feature joins the request and can contribute to the decision without a separate feature pipeline.
Select an event and inspect the decision and matching rule. Chalk computes the features that enabled rules need; editing a rule changes the next evaluation.
Built on Chalk
Keep the rules your risk team owns, and give them every signal you can define.
No feature pipeline per rule
A new rule that needs new data needs a Chalk feature, not a new job, table or cache. Every rule can use every feature as soon as it is deployed.
Only what is needed
Unused features are never computed. A login decision never scans payout history; a payout decision never calls the IP-reputation lookup.
Windows at decision time
Counts and averages over the last ten minutes, day or ninety days are computed against the moment of the decision, not a nightly snapshot.
Models are features too
A rule can threshold a model score the same way it thresholds a count. Chalk computes the model's inputs and the score in the same query.
Features in Chalk, logic in your rules
Define the signals your rules use as Chalk features: aggregations over event history, lookups, enrichments and model scores. The rules engine keeps a map from rule names to feature names and requests only the ones its enabled rules reference.
In this demo the engine is a few hundred lines of Python on a Chalk scaling group, and the features are a small Chalk project. In the decisions you run, Chalk typically executes in 30 to 250 milliseconds.
from chalk import DataFrame, Windowed, windowed
from chalk.features import _, features, has_many, has_one
@features
class User:
id: str
signup_at: datetime
payouts: DataFrame[Payout] = has_many(lambda: Payout.user_id == User.id)
logins: DataFrame[Login] = has_many(lambda: Login.user_id == User.id)
account_age_days: float
# Windowed aggregations, computed at query time over the user's history.
avg_payout: Windowed[float] = windowed(
"30d", expression=_.payouts[_.amount, _.ts > _.chalk_window].mean(),
)
payout_count: Windowed[int] = windowed(
"1d", "7d", expression=_.payouts[_.ts > _.chalk_window].count(), default=0,
)
@features
class RiskEvent:
id: str
user_id: str
amount: float
device_id: str
ip: str
user: User = has_one(lambda: User.id == RiskEvent.user_id)
is_new_device: bool # derived from the user's login history
geo_velocity_kmh: float # derived from the last login's location
ip_risk: float # enrichment from a network-intelligence lookup
ato_risk_score: float # model-backed: an account-takeover modelImplementation details
How the example works
Rules declare their data
A rule is one expression over named features. The engine parses it before it runs, so it knows exactly which features each enabled rule references.
Chalk computes on demand
The engine sends one query whose outputs are only those features. Chalk plans just the resolvers they need: windowed aggregations, lookups, enrichments and a model.
Decide in one pass
Each rule is evaluated against the returned values, and the most severe action wins. The demo shows every value, where it came from and what Chalk ran.
More capabilities
Safe to edit
Rules are a restricted expression language: comparisons, arithmetic and boolean logic over known features. No code runs, and sizes are capped.
Explainable decisions
Every decision carries the values each rule saw and the resolver that produced them, so an analyst can see exactly why a payout was held.
Give your rules the data they ask for
Talk to an engineer about feeding your decision rules with features computed at decision time.