Ludex — telemetry rules
Rules are studio-defined, deterministic policies scoped to your organization, project, and optionally a specific environment. They tell Ludex how to handle telemetry in well-defined pipeline stages: for example which canonical event type to prefer, how to override mapping lookups, how to route quarantined failures, or how replay should behave.
Rules do not replace schema validation. Invalid payloads are still invalid; rules customize classification, mapping, routing, and replay policy around that truth.
Rule types
rule_type value |
Purpose (customer view) |
|---|---|
classification |
Map raw signals (event name, payload fields, environment, error context) to a Ludex standard event type or candidate before non-deterministic suggestion paths run. |
mapping_override |
Override the default mapping from a source event (or field pattern) to a canonical type when a normal lookup would apply. |
quarantine_routing |
Control how failed or quarantined events are routed — for example forcing manual review, allowing automatic suggestion, or tagging policy metadata on the dead-letter side. |
replay_policy |
Gate replay / recovery: block automatic replay, require human approval, or mark categories ineligible until policy changes. |
escalation |
Raise visibility (for example severity or review requirements) for repeated failures or specific event families. |
Each rule stores structured conditions and actions as JSON, validated when the rule is created or updated.
Conditions and actions
Conditions are evaluated against an event context dictionary: flat keys such as event_name, environment_id, error_code, plus dot paths into nested payload fields (for example payload.mode).
Condition operators
Supported operator values on each condition:
| Operator | Meaning |
|---|---|
equals |
String or scalar equality. |
not_equals |
Negated equality. |
regex |
Full-string match against a regular expression pattern (bounded, deterministic). |
in_list |
Field value is one of a list of allowed values. |
not_in_list |
Field value is not in the list. |
exists |
Key / path is present. |
missing |
Key / path is absent. |
contains |
For two strings: value is a substring of the field. For lists/tuples/sets: value is an element of the collection. For objects (maps) with a string value: the field must have that key. |
Conditions are grouped with logic: "and" (all must match) or "or" (any one matches).
Action types
Supported action_type values include:
| Action type | Typical use |
|---|---|
set_candidate_event_type |
Set the classification candidate (canonical type id or slug your deployment uses). |
set_mapping_override |
Force a mapping outcome for downstream processing. |
route_manual_review |
Send the failure path toward human review. |
route_schema_available |
Route or tag for flows where a schema is already available (policy-specific). |
block_auto_approve |
Prevent automatic approval of suggestions for matching events. |
allow_auto_approve |
Explicitly allow auto-approval where policy permits. |
mark_replay_ineligible |
Mark matching quarantine rows ineligible for replay until rules change. |
require_human_replay_approval |
Replay requires an explicit human gate. |
tag_metadata |
Attach metadata tags for dashboards, audits, or downstream workers. |
raise_severity |
Escalate severity or priority for matching issues. |
Each action carries a value whose shape depends on the action (event type string, metadata object, severity level, and so on).
Example: classification rule
Match a legacy event name and set the candidate Ludex event type:
{
"conditions": {
"logic": "and",
"conditions": [
{ "field": "event_name", "operator": "equals", "value": "player_dead" }
]
},
"actions": [
{
"action_type": "set_candidate_event_type",
"value": "LUDEX_PLAYER_DEATH"
}
]
}
Example: quarantine routing rule
Match a validation error code and force manual review:
{
"conditions": {
"logic": "and",
"conditions": [
{ "field": "error_code", "operator": "equals", "value": "NO_SCHEMA_REGISTERED" },
{ "field": "environment_id", "operator": "equals", "value": "production" }
]
},
"actions": [
{ "action_type": "route_manual_review", "value": { "reason": "missing_schema_in_prod" } }
]
}
(Exact optional keys inside value depend on deployment; keep values JSON-serializable.)
Priority and evaluation
- Rules have a numeric
priority(lower number = higher priority). - At runtime, Ludex evaluates active rules in ascending priority order.
- When multiple rules match, higher-priority rules win for conflicting outcomes; evaluation traces and audit metadata record which rules fired.
- Some actions are terminal (evaluation stops after them); your operator documentation may list which actions stop the chain for each pipeline stage.
Environment scoping: if a rule’s environment_id is null, it applies to all environments in the project (unless superseded by a more specific rule). Otherwise it applies only to that environment.
Lifecycle and governance
Rules are governed artifacts, similar in spirit to schemas and mappings:
- Created in
draft— no production effect until approved. - Approved — becomes active (
is_active/ approved status, depending on API surface) and is picked up by workers (subject to caching TTL on your deployment). - Disabled — stops applying but retains history.
- Archived — terminal state; cannot be re-approved without a new rule or operator workflow.
Every material change should produce audit history (who changed what, when, and optionally why). Version numbers bump on updates so you can correlate pipeline behavior with a specific revision.
Only approved and active rules participate in evaluation; draft, disabled, and archived rules do not.
Where rules are managed
Day-to-day create / edit / approve / test flows are exposed on the operator governance surface (HTTP JSON and HTML admin) your Ludex deployment provides, scoped by internal authentication. That is the authoritative place to list rules for all statuses and to run dry-run tests against sample event contexts.
Studios without direct admin access typically work with their Ludex operator or support channel to add or change rules.
Dashboard API (read-only rules)
The credential-scoped dashboard (Authorization: Bearer with read:dashboard, prefix /v1/dashboard) exposes many read APIs (health, drift, DLQ summaries, schema coverage, and so on).
A dedicated GET /v1/dashboard/rules listing active rules for the key’s org/project/environment is planned for parity with drift and other dashboard reads. It is not guaranteed to be enabled on every deployment or build. If your account team confirms it is available, expect a response shaped like other dashboard routes:
{
"status": "ok",
"message": "…",
"data": [ { "id": "…", "name": "…", "rule_type": "classification", "priority": 10 } ],
"total_count": 0
}
Until then, use governance tools or your operator for rule visibility.
Rules vs schemas
| Schemas | Rules | |
|---|---|---|
| Purpose | Define what valid telemetry looks like (types, required fields, shapes). | Define how Ludex should behave when processing or recovering telemetry (mapping, routing, replay gates). |
| Authority | Deterministic validation is the source of truth for accept/reject. | Rules layer policy on top without falsifying validation outcomes. |
| Lifecycle | Draft → approve → activate with versioning. | Same governed pattern: draft → approve; disable/archive as needed. |
For HTTP ingestion contract details, see contract-reference.md. For validation and HTTP errors at the edge, see error-catalog.md. For grouped validation failures and recovery, see schema-drift.md.