Analytics rules as code
Somewhere in your business is a definition of what counts as a conversion. Someone created it. It may have been edited since. There is no history, no export, and no record of why, and no notification of when it changes.
Write it
origin: https://example.com
project: myapp/home
rules:
- rule_id: signup_completed
tag: converted
description: Reached the signup success state
logic: {"in": ["user.signup.success", {"var": "session.actions"}]}
- rule_id: pricing_visitor
tag: pricing
description: Viewed pricing
logic: {"in": ["page_view.pricing", {"var": "session.actions"}]}
Each rule is a condition evaluated against a completed session. A match writes a tag. Tags are what the clientlog digest counts and what triggers notifications.
The conditions are described in JSONLogic.
Commit it
The file lives beside the code it measures.
Rebuild the signup flow and the rule that measures it appears in the same diff. The reviewer sees both. When the flow changes and the rule does not, that is a visible omission in a pull request.
Check the changes
clog plan --file rules.yaml --origin https://example.com --project myapp/home
example.com/myapp/home
comparing rules.yaml against deployed rules
~ signup_completed [modified]
logic: {"in": ["signup.thankyou", ...]}
-> {"in": ["user.signup.success", ...]}
= pricing_visitor [unchanged]
+ trial_started [new - will be created]
- old_funnel_step [removed - will be deleted]
summary: 1 modified, 1 added, 1 removed, 1 unchanged
apply writes it. Exit codes: 0 for no differences, 1 for drift, 2 for a
validation error, 3 for auth failure. --strict fails on any drift, for
pipelines that require the deployed state to match the file.
Drift you did not create is the useful output. Someone edited a rule through the API three weeks ago. Now you know.
Backtest it
clog test --file rules.yaml --rule signup_completed --examples fixtures/sessions.json
The fixtures are sessions exported from your own data. Take one that converted and one that did not. Does the rule match the first and miss the second? We can now include analytics in our CI/CD process.
Rebuild the signup flow now and the test fails in CI, rather than the numbers failing silently for a fortnight.
Log it
commit 4f2a1b9
Exclude hosting-provider signups from the conversion tag
Nine signups last week came from one Chrome 142 / macOS user agent
across five Tor and hosting operators, cycling the three plan
variants in under a second each. They are counted as conversions
and they are not conversions.
Six months later someone asks why the rule has an exclusion.
The answer is one git blame away.
Rules accumulate. Each one is a lesson about your traffic, written down so it applies to every future session. The rules are a record of how people use your product.