16 views
This guide covers AI differential testing with production-focused examples and trade-offs.
AI refactors compile and pass unit tests while quietly changing auth headers, rounding money, or reordering JSON keys that clients hash. Differential testing against shadow production traffic is how you catch behavioral drift before cutover—treat the live service as the oracle, the AI candidate as the suspect.⚡ TL;DR: Mirror a slice of prod requests to the candidate; compare status, headers you care about, and semantic body equality (not byte equality). Quarantine diffs; never auto-cut over on “mostly green.” Pair with AI Migration Assistants: Strangler Fig Cuts and Semantic Diff Review.
Shadow fan-out without doubling write load — AI differential testing
typescript
✅ Read-only shadow by default.// gateway/shadow.ts
export async function shadowCompare(
req: Request,
primary: Handler,
candidate: Handler,
opts: { sampleRate: number; compareWrites: false }
) {
const primaryRes = await primary(req);
if (Math.random() > opts.sampleRate) return primaryRes;
if (req.method !== "GET" && !opts.compareWrites) {
// ❌ Never shadow POST/PUT to a candidate that mutates shared DBs
return primaryRes;
}
// fire-and-forget candidate
void candidate(req.clone()).then((cand) =>
enqueueDiff({ primary: primaryRes, cand, path: req.url })
);
return primaryRes;
}
❌ Shadowing checkout POSTs into a shared DynamoDB table.
Semantic matchers beat deep equality
typescript
Ignore fields the AI was allowed to change (new telemetry headers). Fail hard on import { createHash } from "node:crypto";
type Diff = { field: string; primary: unknown; candidate: unknown };
export function semanticDiff(a: unknown, b: unknown, path = "$"): Diff[] {
const out: Diff[] = [];
if (typeof a !== typeof b) {
out.push({ field: path, primary: a, candidate: b });
return out;
}
if (Array.isArray(a) && Array.isArray(b)) {
// order-insensitive for unordered collections
const sa = [...a].map(stable).sort();
const sb = [...b].map(stable).sort();
if (JSON.stringify(sa) !== JSON.stringify(sb)) {
out.push({ field: path, primary: a, candidate: b });
}
return out;
}
if (a && typeof a === "object") {
const ka = Object.keys(a as object).sort();
const kb = Object.keys(b as object).sort();
for (const k of new Set([...ka, ...kb])) {
out.push(...semanticDiff((a as any)[k], (b as any)[k], `${path}.${k}`));
}
return out;
}
// money: compare cents; timestamps: ignore
if (path.endsWith(".updatedAt")) return out;
if (a !== b) out.push({ field: path, primary: a, candidate: b });
return out;
}
function stable(v: unknown) {
return createHash("sha256").update(JSON.stringify(v)).digest("hex");
}
authorization, totals, and idempotency keys.
Promotion criteria
| Signal | Ship? |
|---|---|
| Diff rate < 0.1% over 24h, no auth/money fields | Canary |
| Diffs only in ignored telemetry | Canary |
| Any money/auth mismatch | Block |
| Candidate 5xx > primary + 0.5pp | Block |
Closing checklist
✅ Dos– ✅ Shadow GET/HEAD (and safe idempotent reads) only unless isolated stores
– ✅ Semantic matchers with allowlisted ignore paths
– ✅ 24h burn-in metrics before cutover
– ✅ Store failing request IDs for replay ❌ Don’ts
– ❌ Don’t byte-compare timestamps or request IDs
– ❌ Don’t auto-cut over from an agent
– ❌ Don’t shadow writes into shared production data
– ❌ Don’t treat “unit tests green” as behavioral equivalence
Related reading
- AI Migration Assistants: Strangler Fig Cuts With Contract Tests
- Semantic Diff Review: AI That Flags Behavioral Drift Only
- Spec-First AI Development: OpenAPI Remains the Only Source of Truth
- Evaluating AI Coding Tools: Blind A/B Tests on Real Tickets
Related: Day 93: SLOs for AI Features · Prompt Engineering for Developers: The Patterns That 10x Your AI Coding Output · Vibe Coding: How Senior Developers Actually Use AI to Write Code Faster
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- Css Animation Performance: Performance-Optimized Motion for Modern UIs
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
