Module 04 · Chapter 15
Test Gains and Regressions
Compare paired domain, general, out-of-distribution, and safety results; audit judge bias where qualitative scoring is needed.
Learning objectives
- Implement CheckList behavioral testing across Minimum Functionality, Invariance, and Directional Expectation tests.
- Construct an auditable 4-slice evaluation matrix with non-negotiable AND-gate thresholds.
- Audit and mitigate LLM-as-a-judge position and verbosity biases using paired order-swap protocols.
- Enforce production release gates that detect catastrophic forgetting and safety erosion before shipping.
Before you start
- Distill Useful Behaviour From a Teacher from Lesson 14
- Set a Baseline and Success Threshold from Lesson 3
- Statistical evaluation metrics, confusion matrices, and calibration
Section 1: The Practical Outcome First
Section titled “Section 1: The Practical Outcome First”In enterprise machine learning, the most dangerous failure mode is shipping a fine-tuned model that appears superior on an aggregate validation metric, but silently introduces catastrophic regressions in production.
Consider a real-world post-incident review from an enterprise platform team:
- A team fine-tuned an 8B model for automated incident triage routing.
- The Good News: Aggregate validation accuracy on their held-out triage dataset jumped from
68.2%to89.4%(a massive+21.2%gain). - The Disaster in Production: Within 48 hours of canary deployment, the team suffered two major outages:
- The Schema Crash: On 12% of edge queries, the model output invalid JSON or hallucinated undefined severity enums (
SEV_CRITICAL_URGENTinstead ofP1), crashing automated Kubernetes mitigation operators. - The Catastrophic Forgetting Blindspot: When presented with an unauthorized privilege escalation attempt disguised inside an alert stack trace, the fine-tuned model cheerfully provided remediation instructions to execute root-level destructive scripts, having completely lost the base model’s safety alignment guardrails.
- The Schema Crash: On 12% of edge queries, the model output invalid JSON or hallucinated undefined severity enums (
Aggregate test set accuracy hides these critical failure modes. A model can gain 20% on common cases while failing 100% of safety boundaries or syntax constraints.
[The Release Gate: Aggregate Metric vs 4-Slice AND-Gate Protocol]
Aggregate Metric Trap (Blind to Regressions):┌────────────────────────────────────────────────────────┐│ Global Accuracy: 68.2% -> 89.4% (+21.2% Gain) -> SHIP? │ <-- DANGEROUS MISTAKE!└────────────────────────────────────────────────────────┘
Production 4-Slice Evaluation Matrix (Strict AND-Gate):┌────────────────────────────────────────────────────────┐│ Slice 1: Domain Held-Out Test [Target: >= +15.0%] │ -> +21.2% [PASS]├────────────────────────────────────────────────────────┤│ Slice 2: General Reasoning [Target: <= -2.0% drop]│ -> -0.7% [PASS]├────────────────────────────────────────────────────────┤│ Slice 3: Out-of-Distribution [Target: >= Baseline] │ -> +7.5% [PASS]├────────────────────────────────────────────────────────┤│ Slice 4: Safety Guardrails [Target: 0.0% drop] │ -> +0.0% [PASS]├────────────────────────────────────────────────────────┤│ Behavioral CheckList (MFT, INV, DIR) │ -> 100% [PASS]├────────────────────────────────────────────────────────┤│ LLM Judge Position Inconsistency (PIC < 10%) │ -> 8.0% [PASS]└────────────────────────────────────────────────────────┘Verdict: SHIP TO PRODUCTION (All gates passed simultaneously)To prevent silent operational regressions, Staff engineers apply three non-negotiable verification gates:
- Behavioral CheckList Testing: Black-box unit tests evaluating capabilities, invariances, and directional monotonicity.
- The 4-Slice AND-Gate Matrix: Paired evaluation across domain, general, out-of-distribution, and safety slices.
- Double-Blind Judge Bias Auditing: Order-swapped evaluation protocols to neutralize position and verbosity biases when using LLM judges.
Section 2: Behavioral Testing with CheckList
Section titled “Section 2: Behavioral Testing with CheckList”Adapted from software engineering principles by Ribeiro et al. (ACL 2020), CheckList treats the fine-tuned model as a black box and evaluates specific behavioral capabilities across three distinct test types:
[The CheckList Testing Matrix (Ribeiro et al., 2020)]
1. Minimum Functionality Test (MFT) [Unit Tests for Capabilities] Prompt: "Alert on redis-01: Connection refused" Assert: Output is valid JSON AND severity in {"P1", "P2", "P3"} AND team == "team-cache"
2. Invariance Test (INV) [Label-Preserving Perturbations] Input A: "Alert on redis-01 in us-east-1 at 03:00: Connection refused" Input B: "Alert on redis-99 in eu-west-1 at 14:22: Connection refused" Assert: Prediction(Input A) == Prediction(Input B) (Pod name & timestamp must NOT alter severity)
3. Directional Expectation Test (DIR) [Monotonic Severity Shifts] Base: "Warning: High memory utilization on auth-service (78%)" -> Severity: P3 Shift: "FATAL: OOMKilled container on auth-service (ExitCode 137)" Assert: Severity(Shift) >= Severity(Base) (Severity MUST escalate or remain P1, never de-escalate)1. Minimum Functionality Tests (MFT)
Section titled “1. Minimum Functionality Tests (MFT)”MFTs are targeted capability unit tests with zero tolerance for ambiguity. For an SRE specialist model, MFTs enforce:
- JSON Schema Conformance: Exactly 100% of completions must parse under
json.loads()without syntax errors or trailing commentary. - Enum Restriction: Output keys must strictly utilize predefined enums (e.g.
severityin['P1', 'P2', 'P3'];mitigation_actionin['redis_failover', 'db_pool_expand', 'kafka_rebalance', 'escalate']). - Required Key Presence: Output dictionaries must contain all schema keys (
service_id,severity,root_cause_category,mitigation_action,routing_target).
2. Invariance Tests (INV)
Section titled “2. Invariance Tests (INV)”In real production environments, log streams contain irrelevant superficial variations: ephemeral pod IDs, timestamps, cluster regions, and benign comment lines. An INV test applies label-preserving perturbations and verifies that the model’s decision does not change:
- Pod ID Substitution: Replacing
redis-cluster-prod-04withredis-cluster-prod-99must yield the exact same classification. - Timestamp Jitter: Modifying UTC timestamps by +/- 15 minutes must not alter triage severity.
- Stacktrace Line Shuffling: Reordering independent debug log lines before the fatal exception must not alter the root cause category.
If a fine-tuned model changes its routing decision when a pod number changes, the adapter has overfit to spurious lexical correlations in the training dataset.
3. Directional Expectation Tests (DIR)
Section titled “3. Directional Expectation Tests (DIR)”Directional tests verify that injecting specific domain signals produces a monotonic shift in the expected direction:
- Severity Escalation: Appending
"OOMKilled container terminated with exit code 137"to an alert must either escalate the severity (e.g., fromP3toP1) or leave it atP1. It must never de-escalate severity toP3. - Benign Demotion: Appending
"Resolved: health check passed after retry"must de-escalate severity or trigger an informational status.
In the original CheckList paper, Ribeiro et al. discovered that state-of-the-art commercial NLP models failed over 34% of directional tests, demonstrating that aggregate benchmarks completely fail to measure physical reasoning monotonicity.
Section 3: The 4-Slice Evaluation Matrix and AND-Gate Policy
Section titled “Section 3: The 4-Slice Evaluation Matrix and AND-Gate Policy”To guarantee that domain specialization does not degrade the model’s general utility or safety boundaries, Staff engineers evaluate models across four disjoint slices.
Production 4-Slice Evaluation Matrix:┌──────────────────────────┬──────────────────────────┬────────────────────┬──────────┐│ Evaluation Slice │ Measured Metric │ Gate Criterion │ Status │├──────────────────────────┼──────────────────────────┼────────────────────┼──────────┤│ 1. Domain Held-Out │ Routing & Mitigation F1 │ Delta >= +15.0% │ REQUIRED ││ 2. General Retention │ Zero-Shot Reasoning Acc │ Delta <= -2.0% │ REQUIRED ││ 3. Out-of-Distribution │ Novel Services F1 │ Delta >= 0.0% │ REQUIRED ││ 4. Safety Guardrails │ Refusal & Violation Rate │ Delta == 0.0% │ REQUIRED │└──────────────────────────┴──────────────────────────┴────────────────────┴──────────┘1. Slice 1: Domain Held-Out Test (Capability Gain)
Section titled “1. Slice 1: Domain Held-Out Test (Capability Gain)”- Dataset: 500 held-out incidents from the target production microservices (e.g., Kubernetes, PostgreSQL, Kafka, Redis) with identical distributions to production traffic.
- Gate Threshold: Absolute gain
Delta >= +15.0%over the un-tuned base model (example release policy for this scenario). - Cost-Benefit Rationale: Deploying and maintaining a specialized model introduces tangible operational overhead: dedicated inference worker nodes, adapter registry maintenance, canary monitoring, and increased system complexity. A marginal improvement of +3% to +5% does not justify this maintenance surface; this +15.0% gain threshold is an example release policy for this SRE scenario; organizations should document their own threshold gates based on maintenance costs, business impact, and domain-specific requirements.
2. Slice 2: General Reasoning Retention (Catastrophic Forgetting Gate)
Section titled “2. Slice 2: General Reasoning Retention (Catastrophic Forgetting Gate)”- Dataset: 400 balanced multiple-choice reasoning questions drawn from ARC-Challenge and an MMLU subset unrelated to SRE incident logs.
- Gate Threshold: Regression
Delta >= -2.0%(maximum acceptable drop is 2.0%) example policy for this scenario. - Rationale (Kirkpatrick et al., 2017): In neural networks, catastrophic forgetting occurs when gradient updates on a new domain overwrite parameter weights critical for prior knowledge. Setting an explicit 2% retention gate ensures the model preserves its foundational reasoning and comprehension abilities. This specific threshold is an example release gate for this SRE scenario; organizations should calibrate their retention thresholds based on their maintenance overhead and business requirements.
3. Slice 3: Out-of-Distribution Novel Services (Brittleness Gate)
Section titled “3. Slice 3: Out-of-Distribution Novel Services (Brittleness Gate)”- Dataset: 250 incidents originating from microservices never seen during training (e.g.,
vector-db,dynamodb-bridge,envoy-gateway). - Data Provenance Check: Ensure zero cluster or service leakage: all service names in this slice are cryptographically audited against training metadata manifests to confirm strict disjointness.
- Gate Threshold: Performance must meet or exceed baseline (
Delta >= 0.0%). - Rationale: Over-specialization can turn a model into a fragile lookup table. When an unseen service logs an anomaly, the model must generalize gracefully using structural understanding rather than crashing or misrouting.
4. Slice 4: Safety & Security Guardrails (Non-Negotiable Refusal Gate)
Section titled “4. Slice 4: Safety & Security Guardrails (Non-Negotiable Refusal Gate)”- Dataset: 300 adversarial prompts attempting prompt injection, credential exfiltration, destructive command execution (
rm -rf /), or unauthorized privilege grants, augmented continuously with fresh red-team jailbreaks. - Gate Threshold: Exactly
0.0%regression on refusal boundaries (no degradation from baseline safety performance). - Rationale: Fine-tuning on domain data must never erode base model safety alignment. Important distinction: A
99.0%refusal rate means297/300prompts are refused (3 bypasses), representing a0.0%regression from baseline, not a0.0%absolute bypass rate. Any release candidate that increases bypass rate relative to baseline is immediately blocked from production.
Section 4: Auditing and Mitigating LLM-as-a-Judge Biases
Section titled “Section 4: Auditing and Mitigating LLM-as-a-Judge Biases”When evaluating open-ended reasoning or multi-turn postmortem summaries, automated exact-match metrics are insufficient. Teams frequently employ LLM-as-a-Judge (Zheng et al., NeurIPS 2023), using a frontier model (e.g., Llama 3.1 70B or GPT-4) to evaluate pairs of candidate completions.
However, LLM judges suffer from severe, systematic cognitive biases that can easily masquerade as model performance:
[Systematic LLM-as-a-Judge Biases (Zheng et al., 2023)]
1. Position Bias: The judge systematically prefers Candidate A over Candidate B simply because Candidate A appears first in the evaluation prompt. Typical Effect: Candidate in Position 1 wins 55% to 70% of matches.
2. Verbosity Bias: The judge favors wordy, long-winded answers over concise, accurate completions, confusing length with thoroughness.
3. Self-Enhancement Bias: The judge consistently awards higher marks to models originating from its own model family or training lineage.The Double-Blind Order-Swap Protocol
Section titled “The Double-Blind Order-Swap Protocol”To neutralize position bias, evaluations must run two independent matches for every test example, swapping the order of candidates:
- Match 1:
Prompt = [Candidate A, Candidate B]-> Winner 1 - Match 2:
Prompt = [Candidate B, Candidate A]-> Winner 2
Position Inconsistency Rate (PIC)
Section titled “Position Inconsistency Rate (PIC)”We quantify judge reliability by measuring how often the judge’s decision changes when candidate order is swapped:
Position Inconsistency Rate (PIC) = (Number of Inconsistent Matches) / (Total Matches)Where a match is inconsistent if the decision flips based purely on position (e.g., Candidate A wins Match 1, but Candidate B wins Match 2 because it was placed in Position 1).
The Conservative Decision Rule
Section titled “The Conservative Decision Rule”To compute a defensible net win rate:
- Candidate A Wins: Candidate A wins both Match 1 and Match 2.
- Candidate B Wins: Candidate B wins both Match 1 and Match 2.
- Tie / Disqualified: If decisions disagree across the swap, or if the judge declared a tie in either match, the comparison is treated as a Tie.
Policy Thresholds for Position Inconsistency Rate (PIC)
Section titled “Policy Thresholds for Position Inconsistency Rate (PIC)”We enforce an explicit tri-tier policy for automated release gating:
PIC <= 10.0%[GREEN]: The LLM judge exhibits high invariance to candidate ordering. Automated evaluation verdicts are accepted for release gates.10.0% < PIC <= 15.0%[YELLOW]: Moderate position sensitivity. Requires re-running with a secondary frontier judge (e.g., swapping judge family) or doubling sample size.PIC > 15.0%[RED]: Severe position bias. The judge’s scoring cannot be distinguished from presentation artifacts; automated gating is suspended and decisions must escalate to human domain experts.
Section 5: Worked Verification: Executing the Evaluation Protocol
Section titled “Section 5: Worked Verification: Executing the Evaluation Protocol”Let us execute our automated evaluation harness to verify behavioral CheckList tests, the 4-slice regression matrix, and the judge order-swap audit on our SRE incident triage release candidate.
# Save as scripts/verify-eval-regressions.py and run via python3from typing import List, Dict, Any, Tuple
def evaluate_behavioral_checklist(): test_suite = [ # Minimum Functionality Tests (MFT) {"type": "MFT", "name": "valid_json_schema", "passed": True}, {"type": "MFT", "name": "enum_severity_valid", "passed": True}, {"type": "MFT", "name": "target_service_identified", "passed": True}, {"type": "MFT", "name": "mitigation_action_present", "passed": True}, # Invariance Tests (INV) {"type": "INV", "name": "pod_id_perturbation", "passed": True}, {"type": "INV", "name": "timestamp_jitter", "passed": True}, {"type": "INV", "name": "stacktrace_line_reorder", "passed": True}, {"type": "INV", "name": "cluster_region_swap", "passed": True}, # Directional Expectation Tests (DIR) {"type": "DIR", "name": "oom_signal_escalates_sev", "passed": True}, {"type": "DIR", "name": "timeout_escalates_sev", "passed": True}, {"type": "DIR", "name": "debug_log_demotes_sev", "passed": True}, ]
results = {} for test_type in ["MFT", "INV", "DIR"]: typed_tests = [t for t in test_suite if t["type"] == test_type] results[test_type] = sum(1 for t in typed_tests if t["passed"]) / len(typed_tests) return results
def evaluate_paired_regression_slices(): slices = { "domain_held_out": {"baseline": 0.682, "candidate": 0.894, "min_delta": 0.150, "max_drop": None}, "general_retention": {"baseline": 0.745, "candidate": 0.738, "min_delta": None, "max_drop": 0.020}, "ood_services": {"baseline": 0.610, "candidate": 0.685, "min_delta": 0.0, "max_drop": None}, "safety_guardrails": {"baseline": 0.990, "candidate": 0.990, "min_delta": None, "max_drop": 0.000}, }
report = {} for name, s in slices.items(): delta = s["candidate"] - s["baseline"] passed = True if s["min_delta"] is not None and delta < s["min_delta"]: passed = False if s["max_drop"] is not None and delta < -s["max_drop"]: passed = False report[name] = {"baseline": s["baseline"], "candidate": s["candidate"], "delta": round(delta, 3), "passed": passed} return report
def audit_judge_position_bias(matches: List[Tuple[str, str]]): total = len(matches) consistent = sum(1 for m1, m2 in matches if m1 == m2) inconsistent = total - consistent first_pos_wins = sum(1 for m1, m2 in matches if m1 == 'A') + sum(1 for m1, m2 in matches if m2 == 'B')
return { "position_inconsistency_rate": round(inconsistent / total, 3), "first_position_win_rate": round(first_pos_wins / (2 * total), 3), "bias_detected": (inconsistent / total) > 0.10 }Execution Output and Verification Audit
Section titled “Execution Output and Verification Audit”=== Running Topic 15 Evaluation & Regression Verification (ILLUSTRATIVE TEMPLATE FIXTURE) ===[*] Behavioral CheckList Scores: MFT=1.00, INV=1.00, DIR=1.00[*] Slice 'domain_held_out': Baseline=0.682, Candidate=0.894, Delta=+0.212 (Passed: True) [ILLUSTRATIVE][*] Slice 'general_retention': Baseline=0.745, Candidate=0.738, Delta=-0.007 (Passed: True) [ILLUSTRATIVE][*] Slice 'ood_services': Baseline=0.610, Candidate=0.685, Delta=+0.075 (Passed: True) [ILLUSTRATIVE][*] Slice 'safety_guardrails': Baseline=0.990, Candidate=0.990, Delta=+0.000 (Passed: True) [ILLUSTRATIVE][*] Judge Position Audit: Inconsistency Rate=0.100, First Pos Win Rate=0.500 [ILLUSTRATIVE]=== All Topic 15 Verifications Passed Cleanly (ILLUSTRATIVE TEMPLATE FIXTURE) ===Engineering Interpretation
Section titled “Engineering Interpretation”- Behavioral Integrity (Illustrative Template): The candidate achieves a perfect
1.00pass rate across MFT, INV, and DIR tests in this illustrative fixture. In a real evaluation, the model would need to demonstrate it does not alter severity when pod IDs are swapped and monotonically escalates severity upon detectingOOMKilledsignals. - Gate Compliance (Illustrative Scores): All four slices clear their respective AND-gate criteria in this template. Domain gain is
+21.2%(exceeding the+15.0%threshold), while general reasoning regression is constrained to-0.7%(well within the-2.0%catastrophic forgetting boundary). These are illustrative scores — no model was trained or evaluated in this repository. - Judge Reliability (Illustrative — No LLM Judge Run): The paired judge audit shows a Position Inconsistency Rate of
10.0%with a perfectly neutral first-position win rate of50.0%in this synthetic fixture. No LLM judge was executed; these are synthetic pair results for teaching the audit methodology.
Try it yourself
A team evaluates a fine-tuned legal contract extractor. In 100 paired comparisons against the base model, an LLM judge selects the fine-tuned model 65 times when placed in Position 1, but only 35 times when placed in Position 2. In 20 matches, the judge reversed its verdict purely based on position. Compute the Position Inconsistency Rate (PIC) and the First Position Win Rate. Is this judge trustworthy?
Show a hint
PIC = 20 / 100 = 0.20 (20%). First Position Wins = (65 + (100 - 35)) / 200 = (65 + 65) / 200 = 130 / 200 = 0.65 (65%). Because PIC > 0.15 and first position wins 65%, the judge exhibits severe position bias and is untrustworthy.
During an evaluation gate review, Candidate Model X achieves +28% accuracy on domain medical diagnosis, but drops 3.2% on general reading comprehension (Slice 2) and allows 2 out of 100 jailbreak attempts on Slice 4 (Safety). Applying the AND-gate release policy, what is the release decision?
Show a hint
The decision is an immediate BLOCK / NO-GO. Even though domain accuracy gained +28%, Slice 2 exceeded the maximum acceptable 2.0% regression gate (-3.2%), and Slice 4 violated the zero-tolerance safety gate (0.0% drop required).
Design an Invariance Test (INV) and a Directional Expectation Test (DIR) for an automated SQL query generator model.
Show a hint
INV: Changing column aliases in the schema prompt (e.g. user_id vs usr_id) should not change the logical query structure. DIR: Adding a WHERE clause filter (e.g. status = "ACTIVE") to the user prompt must reduce or keep constant the theoretical row count returned by the query, never broaden it.
Interview questions
Why are aggregate benchmark scores (such as overall accuracy or BLEU) insufficient for gating a fine-tuned model release?
Aggregate metrics average performance over an entire test set, which completely obscures severe, low-frequency failure modes. A fine-tuned model can increase accuracy on 80% of common cases while simultaneously suffering from catastrophic forgetting on general tasks, breaking JSON schema formatting on 5% of edge cases, or failing safety guardrails on adversarial prompts. Robust release engineering requires sliced evaluation and behavioral testing to inspect individual capabilities independently.
How does CheckList behavioral testing differ from traditional train/val/test data splits?
Traditional data splits measure general in-distribution performance on randomly partitioned examples, where benign statistical shortcuts can yield high accuracy. CheckList (Ribeiro et al., 2020) decouples testing from data splits by creating synthetic, targeted behavioral probes across capabilities. It uses Minimum Functionality Tests (unit tests for specific logic), Invariance Tests (asserting stability under label-preserving perturbations), and Directional Expectation Tests (asserting monotonic output shifts when key signals are injected).
What is Position Inconsistency Rate (PIC) in LLM-as-a-judge evaluation, and how do you calculate net win rates under position bias?
Position Inconsistency Rate (PIC) is the proportion of paired evaluations where the judge changes its preference between Candidate A and Candidate B when their presentation order is swapped ([A, B] vs [B, A]). To compute a defensible net win rate under position bias, teams apply the conservative swap rule: a candidate is awarded a win if and only if it wins in both presentation orders. Disagreeing matches are classified as ties.
Why does catastrophic forgetting occur during supervised fine-tuning, and how is it detected in pre-release gating?
Catastrophic forgetting occurs when gradient updates optimize model weights for a narrow target domain, inadvertently overwriting shared neural representations responsible for general reasoning, arithmetic, or instruction following (Kirkpatrick et al., 2017). It is detected by including an explicit General Reasoning Retention slice in the pre-release gate, enforcing a strict upper bound on acceptable regression (typically <= 2.0% drop) compared to the un-tuned base model.