{{ error }}

Rule deployed to shadow successfully!

{{ shadowDeployError }}

Rule rollout updated successfully!

{{ rolloutDeployError }}

Rule saved successfully!

You are viewing Revision {{ revisionNumber }} of this rule (read-only).

Go to latest version

Rule Details

Shadow version active {{ rolloutEntry.traffic_percent }}% rollout active

{{ saveError }}

{{ rule.rid }}
{{ rule.description }}

Field warnings

  • {{ warning }}
{{ formatDate(rule.created_at) }}

Test Rule

Reason: {{ testResult.reason }}

Rule Result: {{ testResult.rule_outcome | json }}

{{ testError }}

Backtest Changes

Compare the current rule logic against your proposed changes using recent event data.

{{ backtestError }}

Backtest Results

Backtest is running...

{{ getTaskResult(bt.task_id)?.error || 'Backtest failed' }}

Logic Changes

{{ change.value }}

Outcome Comparison

Outcome Current Proposed Delta
{{ outcome }} {{ taskResult.stored_result?.[outcome] || 0 }} ({{ (taskResult.stored_result_rate?.[outcome] || 0) | number:'1.1-1' }}%) {{ taskResult.proposed_result?.[outcome] || 0 }} ({{ (taskResult.proposed_result_rate?.[outcome] || 0) | number:'1.1-1' }}%) {{ (taskResult.proposed_result?.[outcome] || 0) - (taskResult.stored_result?.[outcome] || 0) > 0 ? '+' : '' }}{{ (taskResult.proposed_result?.[outcome] || 0) - (taskResult.stored_result?.[outcome] || 0) }}
Total records evaluated {{ taskResult.total_records }}

Evaluated {{ taskResult.eligible_records || taskResult.total_records || 0 }} records and skipped {{ taskResult.skipped_records }} older records that were not eligible for the common comparison set.

  • {{ warning }}

Historical Labels

Total records: {{ taskResult.total_records || 0 }}

Labeled records: {{ taskResult.labeled_records || 0 }}

Coverage: {{ getLabeledShare(taskResult) | number:'1.1-1' }}%

Current Quality

Pairs scored: {{ getQualitySummary(taskResult, 'stored')?.pair_count || 0 }}

Avg precision: {{ formatQualityMetric(getQualitySummary(taskResult, 'stored')?.average_precision) }}

Avg recall: {{ formatQualityMetric(getQualitySummary(taskResult, 'stored')?.average_recall) }}

Avg F1: {{ formatQualityMetric(getQualitySummary(taskResult, 'stored')?.average_f1) }}

Best pair: {{ getQualitySummary(taskResult, 'stored')?.best_pair || '—' }}

Proposed Quality

Pairs scored: {{ getQualitySummary(taskResult, 'proposed')?.pair_count || 0 }}

Avg precision: {{ formatQualityMetric(getQualitySummary(taskResult, 'proposed')?.average_precision) }}

Avg recall: {{ formatQualityMetric(getQualitySummary(taskResult, 'proposed')?.average_recall) }}

Avg F1: {{ formatQualityMetric(getQualitySummary(taskResult, 'proposed')?.average_f1) }}

Best pair: {{ getQualitySummary(taskResult, 'proposed')?.best_pair || '—' }}

Ground Truth Labels

Label Count Share of labeled
{{ label }} {{ taskResult.label_counts?.[label] || 0 }} {{ (((taskResult.label_counts?.[label] || 0) * 100) / (taskResult.labeled_records || 1)) | number:'1.1-1' }}%

Outcome vs Label Quality

Support columns show TP / FP / FN for each outcome→label pair.

Outcome Label Current P Current R Current F1 Current TP / FP / FN Proposed P Proposed R Proposed F1 Proposed TP / FP / FN
{{ pair.outcome }} {{ pair.label }} {{ formatQualityMetric(getQualityMetric(taskResult, 'stored', pair.outcome, pair.label)?.precision) }} {{ formatQualityMetric(getQualityMetric(taskResult, 'stored', pair.outcome, pair.label)?.recall) }} {{ formatQualityMetric(getQualityMetric(taskResult, 'stored', pair.outcome, pair.label)?.f1) }} {{ getQualityMetric(taskResult, 'stored', pair.outcome, pair.label)?.true_positive || 0 }} / {{ getQualityMetric(taskResult, 'stored', pair.outcome, pair.label)?.false_positive || 0 }} / {{ getQualityMetric(taskResult, 'stored', pair.outcome, pair.label)?.false_negative || 0 }} {{ formatQualityMetric(getQualityMetric(taskResult, 'proposed', pair.outcome, pair.label)?.precision) }} {{ formatQualityMetric(getQualityMetric(taskResult, 'proposed', pair.outcome, pair.label)?.recall) }} {{ formatQualityMetric(getQualityMetric(taskResult, 'proposed', pair.outcome, pair.label)?.f1) }} {{ getQualityMetric(taskResult, 'proposed', pair.outcome, pair.label)?.true_positive || 0 }} / {{ getQualityMetric(taskResult, 'proposed', pair.outcome, pair.label)?.false_positive || 0 }} / {{ getQualityMetric(taskResult, 'proposed', pair.outcome, pair.label)?.false_negative || 0 }}
No labeled events were found in the backtest window, so precision and recall are unavailable for this run.

Deploy to Shadow

No shadow version exists for this rule. The following logic will be deployed to shadow:

A shadow version is already running. The diff below shows what will change in shadow:

{{ editedLogic }}
Current shadow Incoming
{{ change.value }}

{{ rolloutEntry ? 'Update Rollout' : 'Start Rollout' }}

Serve this candidate version to a stable percentage of live traffic while the current production version remains the control.

Logic changes (production → candidate):

Logic is identical to the current production version.

production candidate
{{ chunk.added ? '+' : chunk.removed ? '-' : ' ' }}{{ chunk.value }}