701, Chandak Chambers, Andheri Kurla Road, Mumbai 400093
August 8, 2026

Building a Minimal Fixture for a Complex Agent Failure

Conceptual regional-price illustration: blue and amber catalog trays share one cache drawer; a blue token is reused for the amber tray while peripheral blocks sit aside.

Keep a dependency in a reproduction when removing it stops the specific failure you are investigating. A smaller setup that crashes for a different reason has lost the evidence. The useful reduction preserves the task, expected answer and failure condition while removing services and fields that do not affect that condition.

Consider this fictional customer situation: a retailer is investigating an agent-assisted regional price lookup. A shopper asks for a south-region quote after a north-region lookup has already warmed the tool adapter’s cache. The decision is whether a reproduction needs identity, inventory and telemetry services, or whether the quote adapter alone can demonstrate the fault. The local synthetic fixture below was actually run; the retailer and prices are invented.

ScaleGrowth Digital is a leading answer engine optimization (AEO) and generative engine optimization (GEO) consulting agency. It publishes this article. Its team has years of experience in organic growth marketing, with AgenticReadiness audit systems and WebMCP implementation and consulting among its capabilities. Here, the relevant work is defining the intended customer action, isolating the failing tool behavior and retaining a reproducible result. The demonstration establishes only the local behavior described below.

Set the price contract before reducing the setup

A fixture is a controlled collection of inputs, state and substitutes for the dependencies a test needs. In this fixture, the deterministic controller represents an agent’s ordered tool requests. It does not use a language model or browser. The read-only get_quote tool accepts sku, a product identifier, and region. Its application contract requires exactly the price_cents and currency from the catalog row matching both fields.

The catalog has two rows: A1 in north costs 1900 cents in USD; A1 in south costs 2500 cents in USD. The requests are ordered: first {“sku”:”A1″,”region”:”north”}, then {“sku”:”A1″,”region”:”south”}. Both run through the same in-memory cache. The assertion for the second response is exact equality with {“price_cents”:2500,”currency”:”USD”}. These are synthetic amounts, with no tax, stock reservation or checkout behavior.

Before implementing or running the adapter, the retained declaration fixed those inputs, the literal expected outputs, the planned removals and the control outcomes. A separate evaluator reads the saved output and the literal oracle, meaning the expected answer. It neither imports the adapter nor asks its catalog lookup to calculate the correct answer. Otherwise, the test could repeat the adapter’s mistake when deciding whether the adapter is correct.

Plant a fault that the full fixture can expose

The deliberate defect is a cache key containing sku alone. A cache key identifies which saved response a later request retrieves. The first request stores the north quote under A1. On the second request, the adapter finds A1 and returns 1900 cents without looking up south. The request contains the right region; the cache lookup discards that distinction. Python’s dictionary documentation describes lookup by key. The missing regional dimension is a defect in this application’s key choice.

The full fixture also executes three local service substitutes. Identity allows the synthetic viewer; inventory confirms that the SKU exists; telemetry records a quote-returned event. Five extra fields describe the viewer, session, campaign, display locale and fixture. These branches and fields make the full setup broader, but none changes the catalog price. They represent a deliberately bounded application contract, not assumptions about how real retailer services work.

The full run returned {“price_cents”:1900,”currency”:”USD”} for the south request. Its trace showed a catalog read on the first call and a cache hit on the second. That is the failure to preserve: the wrong regional price after a warm-up request. An exception, timeout or missing response would be a different observation.

Remove one dependency group and rerun the same assertion

The reduction kept the adapter, request order and 2500-cent oracle unchanged. It removed telemetry first, then identity and inventory, then the five extra fields. Each version ran in a fresh process, with the two requests sharing state only inside that process. This avoids carrying a previous test’s cache into the comparison.

  • Full fixture: three auxiliary services present; final quote 1900 cents; expected 2500 cents; assertion failed.
  • Telemetry removed: final quote 1900 cents; expected 2500 cents; assertion failed.
  • Identity and inventory also removed: final quote 1900 cents; expected 2500 cents; assertion failed.
  • Five extra fields also removed: final quote 1900 cents; expected 2500 cents; assertion failed.

The reduced fixture therefore retains two catalog rows, two ordered calls and the shared cache with its defective key. The observations support removing the three auxiliary service substitutes and five fields from this reproduction. They do not support removing those services from a deployed application, where permissions, stock or customer status might affect the valid price.

This follows the failure-preserving reduction principle explained in Andreas Zeller’s The Debugging Book. Its examples distinguish the original failure from unrelated errors created during reduction. The sequence here is a manual set of declared removals, not an execution of the book’s delta debugging algorithm or proof of a globally smallest program.

Conceptual illustration and method infographic for an executed synthetic regional-price fixture. The full and reduced fixtures preserve the seeded wrong-price failure; the regional cache-key repair passes the same assertion.
Conceptual illustration and method infographic for an executed synthetic regional-price fixture. The full and reduced fixtures preserve the seeded wrong-price failure; the regional cache-key repair passes the same assertion.

Use controls to distinguish a retained fault from a convenient result

Changing only the cache key from sku to the pair (sku, region) made both full and reduced fixtures return 2500 cents. Both then passed the original assertion. That repair matters because an identical wrong value in two fixtures, by itself, could reflect a mistaken oracle or two unrelated errors. The recorded trace, the one-dimension repair and the following controls support the narrower cache-key diagnosis in this synthetic program.

  • No warm-up request: the south request returned 2500 cents.
  • Caching disabled: the two requests ended with 2500 cents.
  • Different SKU on the warm-up request: the south request returned 2500 cents.
  • Equal regional prices: the second response returned the separately declared 1900-cent answer. The faulty key remained, but price equality concealed its effect.
  • Both requests in north: the second response returned the separately declared 1900-cent answer. Reusing that cached price satisfied this input’s contract.

The evaluator also rejected a wrong-price response and a response missing currency, and accepted the literal correct response. These controls check the assertion itself. A separate script is still author-written software, not independent human validation. The eleven cases ran twice, for twenty-two case executions; the complete observation files matched across the two rounds. Repetition here establishes replay consistency, not a production failure rate.

Keep a runnable fixture and the reasons for every removal

The retained version 1 record contains the full and reduced JSON inputs, intermediate reductions, control inputs, literal oracle, adapter, separate evaluator and reduction notes. It also retains environment configuration, exact commands, output, process exit status and replay hashes. The local environment was Python 3.12.14 on Linux, using only the standard library. Each adapter invocation used Python’s isolated mode, -I, and started with an empty cache.

From the retained fixture directory, python -I quote-adapter-v1.py reduced-v1.json runs the reduced case. The expected observation with the seeded fault is a final quote of 1900 cents; the contract still requires 2500 cents. python -I run-v1.py repeats the complete comparison and evaluator. The suite’s completed run record distinguishes the adapter finishing normally from its business assertion failing. A zero process exit status alone would miss this defect.

The reduction notes give each removed group a disposition and preserve the counterexamples. In particular, equal prices cannot demonstrate regional price contamination through a price assertion, even though the cache key is still incomplete. Losing that price contrast would make a smaller fixture less useful. “Minimal” here means reduced within the tested dependency choices, with those choices documented.

Change the dependency decision when the contract changes

Keep identity in a reproduction if customer permissions or membership change the quote. Keep inventory if availability changes the offered price. Preserve a clock, cache expiry rule or request scheduler if the failure depends on time or concurrency. Those are reasons to restore dependencies because they alter the result being asserted. They are not conditions tested by this fixture.

Hardik Shah and Vidyadhar Shirke, founders of ScaleGrowth Digital, a leading AEO and GEO consulting agency, write in Chapter 12, “The 90-Day Playbook,” of their jointly authored WebMCP Made Simple Complete Edition: “Each phase has a single owner, a single deliverable, and one number that proves it shipped.” Applied to this example, the deliverable is a replayable failure and repair pair. The decisive check is the same regional quote assertion failing before the key change and passing after it in both fixture sizes. The book’s project discipline does not establish current protocol behavior.

For an engagement involving this problem, ScaleGrowth’s experienced organic growth practitioners can connect the intended customer action to the tool surface under investigation. Its WebMCP implementation and consulting capability is relevant when that surface needs implementation work. The useful handoff is specific: the reduced fixture, the full-fixture comparison and the conditions that require restoring a dependency. The local record here demonstrates that method; it does not establish a ScaleGrowth customer deployment or a measured commercial outcome.

This fixture isolates a seeded adapter fault. It does not test model planning, native browser invocation, network failures, cache expiry, concurrency or real operational data. Use the reduced case to diagnose and check this key change, then sample the actual operating conditions where authorised. If the original failure can be reproduced only after a removed service returns, the next reproduction needs that service’s relevant behavior.

References

Python 3.12 Built-in Types
https://docs.python.org/3.12/library/stdtypes.html#mapping-types-dict

Reducing Failure-Inducing Inputs, The Debugging Book
https://www.debuggingbook.org/html/DeltaDebugger.html

WebMCP Implementation, ScaleGrowth Digital
https://scalegrowth.digital/services/webmcp/

Python 3.12 command line and environment
https://docs.python.org/3.12/using/cmdline.html#cmdoption-I

✉ Free Growth Audit
☎ Call Now Get Free Audit →