Docket Health Metrics & SLAs

Docket-health metrics are the small set of precisely-defined numbers a docketing team commits to hitting — on-time-completion rate, aging distribution, coverage, acknowledgment latency, and breach count — each paired with a service-level target and an error budget that says exactly how much slack remains before the target is at risk. This page fixes the definitions so tightly that two teams computing the same metric from the same ledger get the same number, then computes them all in one function.

These are the concrete definitions behind the Docket Audit Dashboards & Metrics reference: where that page covers the dashboard architecture and threshold wiring, this one pins the arithmetic and the target values. Every metric is derived from the append-only ledger of the Core Docketing Architecture & Deadline Types reference and reads the effective deadlines the rule engine sealed — it never recomputes a date.

Metric Definitions

A metric is only useful if its definition is unambiguous. The table below fixes each one as a formula over ledger events for a review window. Two definitions carry the most subtlety and cause the most disagreement in practice: the on-time denominator is deadlines due in the window, not deadlines acted on; and coverage’s denominator is the full matter population from matter management, not the set of matters that happen to appear in the ledger.

Metric Formula Notes
On-time-completion rate met_on_time ÷ due due = deadlines whose effective date falls in the window; met_on_time = those met on or before it
Breach count missed + met_late Absolute count, never a rate; every breach is an incident to review individually
Coverage percentage matters_tracked ÷ matter_population × 100 Denominator from matter management; surfaces untracked matters
Acknowledgment latency (p90) 90th-percentile(ack_time − first_reminder_time) Percentile, not mean, so a slow tail stays visible
Escalation rate escalated ÷ due Share of due deadlines that needed the safety net
Aging distribution count of open deadlines per time-to-due bucket Bucketed on the effective (rolled) date, keyed by deadline category

The on-time rate is the headline number, but on its own it is a lagging indicator: it only moves after a deadline has already been missed. The aging distribution and acknowledgment latency are the leading indicators that let a team act before the on-time rate can ever drop — the pressure shows up in the aging buckets and the latency tail first. Reminder timing that keeps deadlines out of the danger buckets is governed by the Deadline Reminder Cadence Engines layer.

Docket-health SLA scorecard with an error-budget bar Four key-performance tiles across the top show each metric's current value against its target: on-time-completion rate at 99.94 percent against a 99.9 percent target (met), coverage at 100 percent against a 100 percent target (met), acknowledgment latency 90th percentile at 16 hours against a 24-hour target (met), and escalation rate at 6.2 percent against a 5 percent-or-lower target (breached). Below the tiles a horizontal error-budget bar for the on-time metric shows 60 percent of the monthly 0.1 percent miss budget consumed, with 40 percent remaining. A met tile carries a teal status dot; the breached escalation tile carries a plum dot. DOCKET-HEALTH SLA SCORECARD On-time completion 99.94% target ≥ 99.9% MET Coverage 100% target = 100% MET Ack latency p90 16h target ≤ 24h MET Escalation rate 6.2% target ≤ 5% BREACHED ERROR BUDGET — ON-TIME COMPLETION (0.1% MONTHLY) 60% consumed 40% remaining

SLA Targets & Error Budgets

An SLA target is a commitment, and every commitment implies an error budget — the amount of failure the target tolerates before it is breached. In a legal-deadline domain the budgets are deliberately tiny, because a single missed statutory date can be an unrecoverable malpractice event, but they are not zero: an on-time target of 100.000% is operationally meaningless because it leaves no room to distinguish a system under mild strain from one in crisis. A 99.9% on-time target over a monthly window of, say, 1,000 due deadlines permits exactly one late completion before the budget is exhausted — a threshold tight enough to force review of every near-miss while still being measurable.

Metric Target (SLO) Error budget Rationale
On-time-completion rate ≥ 99.9% 0.1% of due deadlines / month Every budget-consuming late completion triggers a near-miss review
Coverage percentage 100% of active matters 0 untracked matters An untracked matter has no safety net at all; no tolerance
Acknowledgment latency (p90) ≤ 24 hours p90 headroom to 24h One business day to confirm receipt of an alert
Escalation rate ≤ 5% of due deadlines 5% ceiling A higher rate means owners are relying on the safety net, not working the cadence
Breach count 0 statutory / month 0 for statutory Statutory misses are generally unrecoverable; procedural breaches reviewed individually

The error-budget framing — borrowing the discipline documented in the Google SRE service-level-objectives chapter — turns an abstract target into an operational gauge. When the on-time budget is 60% consumed halfway through a month, the team knows to slow discretionary change and tighten escalation before the budget runs out, exactly as the scorecard above shows. Coverage is the one metric with a genuinely zero budget: an active matter that is not under tracking has no reminder cadence, no escalation ladder, and no safety net, so a single untracked matter is a breach regardless of how the rest of the portfolio looks.

Targets differ by deadline category. A statutory bar date carries a zero breach budget because a miss is generally unrecoverable except through narrow petition mechanisms, while a procedural response with an available extension warrants a small but non-zero tolerance. Bucketing and thresholds are therefore keyed to the category taxonomy in the Core Docketing Architecture & Deadline Types reference, and a threshold breach hands off to the Escalation Routing Workflows layer rather than being resolved on the dashboard.

Computing the Metrics from Ledger Data

One function computes the whole scorecard from a window of ledger entries. It is pure — same entries, same window, same matter population yields the same result — and it reads only the effective deadlines and terminal events the ledger already sealed. It never applies its own date arithmetic.

from __future__ import annotations

import math
from collections import Counter
from dataclasses import dataclass
from datetime import date, datetime
from zoneinfo import ZoneInfo

from pydantic import BaseModel, Field

UTC = ZoneInfo("UTC")


class DeadlineFact(BaseModel):
    """One deadline's terminal facts for a review window, read from the ledger."""
    deadline_id: str
    matter_id: str
    category: str = Field(pattern=r"^(statutory|procedural|discretionary)$")
    effective_deadline: date                        # already rolled off non-working days
    due_in_window: bool                             # effective date falls in the window
    outcome: str = Field(pattern=r"^(met_on_time|met_late|missed|open)$")
    escalated: bool = False
    ack_latency_hours: float | None = None          # None if never acknowledged


@dataclass
class DocketHealth:
    due: int
    on_time_rate: float
    breach_count: int
    coverage_pct: float
    escalation_rate: float
    ack_latency_p90: float | None
    aging_histogram: dict[str, int]
    statutory_breaches: int

    def within_slo(self) -> bool:
        # The scorecard is green only when statutory breaches are zero, coverage
        # is full, and the on-time rate clears its target.
        return (self.statutory_breaches == 0
                and self.coverage_pct >= 100.0
                and self.on_time_rate >= 0.999)


def _p90(values: list[float]) -> float | None:
    if not values:
        return None
    ordered = sorted(values)
    rank = min(len(ordered), max(1, math.ceil(0.90 * len(ordered))))
    return round(ordered[rank - 1], 2)


def _bucket_label(days: int, boundaries: list[int]) -> str:
    if days < 0:
        return "overdue"
    prev = 0
    for b in boundaries:
        if days <= b:
            return f"{prev + 1}-{b}d" if prev else f"<={b}d"
        prev = b
    return f">{boundaries[-1]}d"


def compute_docket_health(facts: list[DeadlineFact], matter_population: int,
                          as_of: datetime, aging_boundaries: list[int]) -> DocketHealth:
    """Compute the full docket-health scorecard from sealed ledger facts."""
    if as_of.tzinfo is None:
        raise ValueError("as_of must be timezone-aware (UTC)")
    today = as_of.astimezone(UTC).date()

    due = [f for f in facts if f.due_in_window]
    met_on_time = sum(1 for f in due if f.outcome == "met_on_time")
    breaches = [f for f in due if f.outcome in ("met_late", "missed")]
    escalated = sum(1 for f in due if f.escalated)

    tracked_matters = {f.matter_id for f in facts if f.outcome != "open" or f.escalated}
    latencies = [f.ack_latency_hours for f in facts if f.ack_latency_hours is not None]

    histogram = Counter(
        _bucket_label((f.effective_deadline - today).days, aging_boundaries)
        for f in facts if f.outcome == "open"
    )

    n_due = len(due)
    return DocketHealth(
        due=n_due,
        on_time_rate=round(met_on_time / n_due, 5) if n_due else 1.0,
        breach_count=len(breaches),
        coverage_pct=round(100.0 * len(tracked_matters) / matter_population, 2)
        if matter_population else 0.0,
        escalation_rate=round(escalated / n_due, 5) if n_due else 0.0,
        ack_latency_p90=_p90(latencies),
        aging_histogram=dict(histogram),
        statutory_breaches=sum(1 for f in breaches if f.category == "statutory"),
    )

The function separates the two denominators that cause the most measurement errors: rates divide by due (deadlines whose effective date falls in the window), while coverage divides by matter_population (the full active-matter list from matter management). Mixing them — measuring coverage against the ledger’s matter set, or measuring the on-time rate against deadlines merely touched — is the classic way a scorecard reads healthy while a real gap grows. The statutory_breaches count is broken out separately because it has a zero budget: one statutory breach fails the scorecard regardless of an otherwise perfect on-time rate.

Known Gotchas and Compliance Traps

  • A perfect on-time rate hiding a statutory miss. A single missed statutory deadline can be lost in a 99.9% on-time rate over a large portfolio, yet it may be an unrecoverable malpractice event. statutory_breaches is computed and gated separately so one statutory miss fails the scorecard outright, independent of the aggregate rate.
  • Coverage measured against the ledger. A matter never docketed produces no ledger facts and silently inflates coverage toward 100%. The coverage denominator is the matter population from matter management, so the untracked matter — the case with no safety net at all — is the one the metric exists to catch.
  • Zero-due window returning NaN. A window with no due deadlines must return a defined on-time rate of 1.0 and an escalation rate of 0.0, never divide by zero. A NaN on a compliance scorecard reads as a broken control and undermines trust in every other number.
  • Mean latency instead of p90. Averaging acknowledgment latency buries a never-acknowledged tail. The scorecard reports p90 by nearest rank, so a p90 that blows past 24 hours points straight at the owners who are not actioning their alerts.
  • Aging by nominal instead of effective date. A deadline that rolls forward over a holiday weekend under 37 CFR 1.7(a) or PCT Rule 80.5 has real extra runway. The histogram buckets on the effective date so the aging distribution reflects genuine urgency, not a nominal date the office would itself extend.
  • Error budget treated as a rate to hit rather than spend. The error budget is slack to be consumed deliberately, not a target to run at. A month that consumes 60% of the on-time budget by mid-month is a signal to slow discretionary change, not a licence to keep spending to the ceiling.

Frequently Asked Questions

Why is a 100% on-time target a bad SLA even for legal deadlines?
A 100.000% target leaves no error budget, so it cannot distinguish a system under mild strain from one in crisis — both read as failing. A 99.9% target over a 1,000-deadline month permits exactly one late completion before the budget is exhausted, which is tight enough to force a near-miss review of that one case while still being a measurable, actionable signal. The zero-tolerance discipline belongs on the statutory breach count specifically, which is gated to zero, not on the aggregate on-time rate.
What is the difference between the on-time denominator and the coverage denominator?
On-time rate divides by deadlines due in the window — those whose effective date falls inside it — so it measures how well due work was completed. Coverage divides by the full active-matter population from matter management, so it measures whether every matter is under tracking at all. Mixing them is the classic scorecard error: measuring coverage against the ledger's own matter set hides matters that were never docketed, which are exactly the highest-risk cases with no safety net.
How is an error budget used operationally during the month?
The error budget is the amount of failure a target tolerates before it breaches — for a 99.9% on-time SLO, that is 0.1% of due deadlines. Track how much of it is consumed as the month progresses: at 60% consumed by mid-month, slow discretionary change and tighten escalation before the budget runs out. It is slack to be spent deliberately, not a rate to run at, and it turns an abstract percentage into a gauge the team can steer by.
Should docket-health metrics ever recompute a deadline date?
No. The metrics function reads the effective deadline the rule engine already sealed into the ledger and never applies its own month arithmetic or holiday roll. Keeping measurement free of date computation is a compliance boundary: a reviewer must be able to trust that the aging distribution reflects the dates the system actually computed, not a second, possibly divergent calculation embedded in the dashboard.

↑ Back to Docket Audit Dashboards & Metrics