---
title: "Compare old and new answers before · Agent Wranglers"
url: https://agentwranglers.se/playbook/codebase-takeover/leaving-an-ai-builder/shadow-compare
id: TKO-17
level: Recommended
updated: 2026-10-22
tokens: 1072
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Compare old and new answers before switching a route

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Leaving an AI builder](https://agentwranglers.se/playbook/codebase-takeover/leaving-an-ai-builder.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: TKO-17
- Level: Recommended
- Chapter: [Leaving an AI builder](https://agentwranglers.se/playbook/codebase-takeover/leaving-an-ai-builder.md)
- Rule: Before a route switches to the new system, send copies of its read requests to both systems and compare the answers. Switch only when no difference is left unexplained.
- Check: For each moved route, the comparison log covers at least 1,000 requests or 7 days of traffic before the switch. Every difference in it has a ticket or a written reason.
- How: The proxy or a small script replays read requests against the new system and logs any difference, while visitors still get the old answer. Never replay writes, since they would run twice. Mask fields that always differ, such as request IDs and timestamps, as [Mask volatile parts narrowly](https://agentwranglers.se/playbook/testing/output-comparison/narrow-masks.md) says. Each difference is a bug in the new code or a pinned old bug, as [Keep known bugs pinned until their own fix](https://agentwranglers.se/playbook/codebase-takeover/characterization-tests/pin-known-bugs.md) says. After the switch, follow [Compare the live system before and after each deploy](https://agentwranglers.se/playbook/testing/output-comparison/compare-live-before-and-after.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
const VOLATILE = new Set(['requestId', 'generatedAt']);
const stable = body => JSON.stringify(body, (key, value) => (VOLATILE.has(key) ? undefined : value));

export async function compareRoute(path, headers) {
  const [legacy, next] = await Promise.all([fetch(LEGACY + path, { headers }), fetch(NEW + path, { headers })]);
  const [a, b] = await Promise.all([legacy.json(), next.json()]);
  if (legacy.status !== next.status || stable(a) !== stable(b)) log.warn('route differs', { path });
}
```

### Python example

```python
VOLATILE = {"requestId", "generatedAt"}

def stable(body):
    if isinstance(body, dict):
        return {key: stable(value) for key, value in body.items() if key not in VOLATILE}
    if isinstance(body, list):
        return [stable(item) for item in body]
    return body

def compare_route(path, headers):
    legacy, new = httpx.get(LEGACY + path, headers=headers), httpx.get(NEW + path, headers=headers)
    if legacy.status_code != new.status_code or stable(legacy.json()) != stable(new.json()):
        log.warning("route differs", extra={"path": path})
```

## Related rules

- TST-44 [Mask volatile parts narrowly](https://agentwranglers.se/playbook/testing/output-comparison/narrow-masks.md) in Testing
- TKO-9 [Keep known bugs pinned until their own fix](https://agentwranglers.se/playbook/codebase-takeover/characterization-tests/pin-known-bugs.md) in Codebase takeover
- TST-45 [Compare the live system before and after each deploy](https://agentwranglers.se/playbook/testing/output-comparison/compare-live-before-and-after.md) in Testing

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/codebase-takeover/leaving-an-ai-builder/shadow-compare">Agent Wranglers codebase takeover playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Give each table one writer during the move](https://agentwranglers.se/playbook/codebase-takeover/leaving-an-ai-builder/one-writer-per-table.md)
- Next: [Move users without resetting their passwords](https://agentwranglers.se/playbook/codebase-takeover/leaving-an-ai-builder/move-users-with-hashes.md)
- [Leaving an AI builder](https://agentwranglers.se/playbook/codebase-takeover/leaving-an-ai-builder.md)
