Skip to content
LinkState
Go back

Tuning Approval Thresholds by Measured Cost

#Define Workloads and Incident Classes to Measure the Tradeoff Between Slower Human Approvals, False Positive Auto‑Fixes, and Missed Remediation Windows

Introduction to Workloads and Incident Classes

Defining Workloads

A workload is the observable demand placed on a system by users, applications, or internal processes over a defined time interval. In network‑centric observability a workload can be expressed as the tuple

W = (λ, σ, ν)

Workloads are measured at the data‑plane (e.g., gNMI telemetry of interface counters) and the control‑plane (e.g., BGP update rate, telemetry subscription load). Defining workloads enables quantitative comparison of “how much” work the system must handle versus “how fast” it can react to incidents.

Categorizing Incident Classes

An incident class groups failures that share a common root cause, impact profile, and remediation path. Typical network‑oriented incident classes include:

ClassTypical SymptomsPrimary Telemetry SignalsRemediation Path
Link FlapRapid up/down transitions, increased CRC errorsifOperStatus, ifInErrors, ifOutErrors (gNMI)Automatic link‑debounce, then manual inspection if > N flaps/min
Congestion CollapseSustained queue occupancy > 90 %, increased latencyifHCInOctets, ifHCOutOctets, qDepth (model‑driven)Dynamic QoS re‑profile, traffic engineering reroute
Control‑Plane OverloadBGP/IS‑IS update storms, high CPU on route‑processorbgpPeerState, cpuUtilization, memUtilization (SNMP/Telemetry)Rate‑limit updates, enable graceful restart, manual peer reset
Security AnomalySpike in dropped packets, ACL hit countsaclDropCount, flowDeny, ipfix flow recordsAuto‑quarantine offending prefix, SOC ticket creation
Configuration DriftMismatch between intended and running config, failed commitsnetconfCommitSuccess, yangDatastoreDiff (gNMI)Auto‑rollback to last known good, then change‑management review

Each class receives a severity (impact on SLA), priority (order of handling), and an expected remediation window (maximum allowable time to restore service before SLA breach).

Understanding the Tradeoff

Human Approvals: Benefits and Drawbacks

Benefits

Drawbacks

Auto‑Fixes: False Positives and Their Impact

Auto‑fix mechanisms execute remediation without waiting for human consent. Performance is measured by:

Impact of False Positives

Missed Remediation Windows: Consequences and Mitigation

A missed remediation window occurs when the time from incident detection to service restoration exceeds the class‑specific SLA threshold (T_max). Consequences include:

Mitigation Strategies

Defining Metrics for Evaluation

Workload Metrics: Volume, Velocity, and Variety

MetricDefinitionTypical Collection MethodExample PromQL
Workload Volume (V)Count of work items observed in interval ΔtInterface packet counters, flow export, API request logssum(rate(ifInOctets[5m])) / avg(packetSize)
Workload Velocity (Ṽ)First derivative of volume – rate of changeSame as volume, computed over sliding windowderivative(sum(rate(ifInOctets[5m]))[5m])
Workload Variety (𝒱)Shannon entropy of categorical labels (e.g., dst_port, tenant_id)Enriched flow records (IPFIX, sFlow)- sum(label_value * log2(label_value)) where label_value = count(label)/total

These metrics feed into a Workload Intensity Score (WIS):

WIS = α·norm(V) + β·norm(Ṽ) + γ·norm(𝒱)

with α+β+γ=1, tuned per incident class.

Incident Class Metrics: Severity, Priority, and Frequency

MetricDefinitionCollection
Severity (S)Normalized impact score (0‑1) based on SLA breach magnitude, customer count, revenue at risk.Derived from SLA DB + incident ticket fields.
Priority (P)Ordering weight (e.g., P1‑P4) derived from S × (1 / T_max).Static mapping in incident‑management system.
Frequency (F)Average occurrences per unit time (e.g., incidents/hour).Count of tickets per class over rolling window.

A Risk Exposure (RE) can be expressed as:

RE = S × P × F

Higher RE warrants tighter automation thresholds.

Approval and Auto‑Fix Metrics: Accuracy, Speed, and Reliability

MetricFormulaInterpretation
Mean Time To Approve (MTTA)Σ(approval_timestamp – detection_timestamp) / N_approvalsLatency of human gate.
Approval Accuracy (AA)TP_approval / (TP_approval + FN_approval)Fraction of correct human decisions (true positives + true negatives).
Auto‑Fix Precision (AFP)TP_auto / (TP_auto + FP_auto)Reliability of automated remediation.
Auto‑Fix Recall (AFR)TP_auto / (TP_auto + FN_auto)Coverage of incidents by auto‑fix.
Mean Time To Remediate (MTTR)Σ(restore_timestamp – detection_timestamp) / N_incidentsEnd‑to‑end recovery speed.
False Positive Rate (FPR)FP_auto / (FP_auto + TN_auto)Undesired actions per benign state.

These metrics are visualized in a Tradeoff Dashboard (see Implementation section) where axes are MTTA (x) vs. FPR (y) and bubble size encodes RE.

Troubleshooting Common Issues

Identifying Bottlenecks in Human Approval Processes

  1. Queue Depth Monitoring – Export approval‑system metrics (e.g., Jira Service Desk approvals_pending) to Prometheus.
    sum by (project) (approvals_pending)
  2. Latency Breakdown – Use distributed tracing (OpenTelemetry) on the approval workflow to isolate stages:
    • ticket_creation → triage → decision → notification.
    • Look for spans > 90th percentile.
  3. Resource Saturation – Check approver CPU/memory via node exporter; high utilization correlates with increased MTTA.
  4. Shift Patterns – Correlate MTTA with approver_on_call label to detect coverage gaps.

Remediation – Introduce auto‑triage rules that route low‑risk incidents to a “fast‑track” queue with pre‑approved actions, reducing load on the human gate.

Debugging Auto‑Fix Algorithms for False Positives

  1. Feature Importance – If the auto‑fix uses an ML model, extract SHAP values per decision to see which telemetry features drove the false positive.
  2. Threshold Sweep – Run a canary experiment varying the decision threshold (τ) and record FPR/Recall:
    for tau in 0.1 0.2 0.3 0.4 0.5; do
        ./run_autofix --threshold $tau --log results_$tau.json
    done
  3. Label Drift Detection – Compare distribution of incoming telemetry (e.g., ifInErrors) against the training set using KL‑divergence; a spike indicates model drift.
  4. Shadow Mode – Deploy the auto‑fix in observation‑only mode; log proposed actions and compare with actual incidents to compute precision without affecting traffic.

Remediation – Adjust thresholds, retrain with recent data, or add a rule‑based guardrail (e.g., never shut down an interface if ifOperStatus already down for > 5 min).

Analyzing Missed Remediation Windows for Root Causes

  1. Timeline Reconstruction – Join detection timestamps (incident_detected), approval timestamps (approval_given), and remediation timestamps (service_restored) in a SQL or TimescaleDB query:
    SELECT
        i.id,
        EXTRACT(EPOCH FROM (a.approval_time - i.detect_time)) AS mtta,
        EXTRACT(EPOCH FROM (r.restore_time - i.detect_time)) AS mttr,
        i.class,
        i.severity
    FROM incidents i
    LEFT JOIN approvals a ON i.id = a.incident_id
    LEFT JOIN remediations r ON i.id = r.incident_id
    WHERE r.restore_time - i.detect_time > i.t_max;
  2. Critical Path Analysis – Identify which stage (detection → approval → action → verification) consumes the majority of excess time.
  3. Contention Metrics – Correlate missed windows with system load (CPU, queue depth) at the time of incident using cross‑correlation.
  4. Escalation Latency – Measure time from first approval request to escalation trigger; high values indicate ineffective escalation policies.

Remediation – Implement predictive pre‑approval for high‑RE classes, or dynamically lower MTTA thresholds when system load exceeds a configured percentile.

Implementing Workload and Incident Class Management

Code Examples: Integrating Approval and Auto‑Fix Workflows

Below is a minimal Python‑based workflow using Temporal.io (durable execution) that demonstrates a decision gate:

import asyncio
from datetime import timedelta
from temporalio import workflow, activity
from temporalio.client import Client
from temporalio.worker import Worker

# ----- Activities -----
@activity.defn
async def detect_incident(telemetry: dict) -> dict | None:
    # Simplified detection logic
    if telemetry.get("ifInErrors_rate", 0) > 100:
        return {
            "incident_id": "inc-123",
            "class": "LinkFlap",
            "severity": 0.9,
            "ifIndex": telemetry.get("ifIndex"),
        }
    return None


@activity.defn
async def request_human_approval(incident: dict) -> bool:
    # Push to approval system (e.g., ServiceNow) and wait for callback
    await approval_system.submit(incident)
    return await approval_system.wait_for_decision(timeout=300)  # 5 min SLA


@activity.defn
async def execute_auto_fix(incident: dict) -> None:
    if incident["class"] == "LinkFlap":
        await netconf.set_interface_state(incident["ifIndex"], "down")
        await asyncio.sleep(2)
        await netconf.set_interface_state(incident["ifIndex"], "up")


# ----- Workflow -----
@workflow.defn
class IncidentResponse:
    @workflow.run
    async def run(self, telemetry: dict) -> None:
        incident = await workflow.execute_activity(
            detect_incident,
            telemetry,
            start_to_close_timeout=timedelta(seconds=5),
        )
        if not incident:
            return

        # Example decision: auto‑fix for low‑severity, otherwise seek approval
        if incident["severity"] < 0.5:
            await workflow.execute_activity(
                execute_auto_fix,
                incident,
                start_to_close_timeout=timedelta(seconds=10),
            )
        else:
            approved = await workflow.execute_activity(
                request_human_approval,
                incident,
                start_to_close_timeout=timedelta(seconds=300),
            )
            if approved:
                await workflow.execute_activity(
                    execute_auto_fix,
                    incident,
                    start_to_close_timeout=timedelta(seconds=10),
                )
            else:
                # Escalate or manual handling
                await workflow.execute_activity(
                    escalate_incident,
                    incident,
                    start_to_close_timeout=timedelta(seconds=60),
                )

Replace approval_system, netconf, and escalate_incident with your actual integrations.


Share this post on:

Previous Post
Safely disabling topology hints during a live incident
Next Post
Diff normalization to kill false canary alarms