ArticleEvaluation Engineering

Your AI Eval Agent Found the Answer Key: Isolate Fixtures Before Trusting the Score

Separate task inputs from grader-only fixtures, create disposable agent workspaces, and test answer-key leakage with a synthetic marker and a positive control.

Last reviewed: 2026-09-08

Two dark machine-like enclosures on a cyan-lit platform, with a thin amber line extending between them.
The illustration separates two work areas; the evaluation harness must enforce its own boundary between agent inputs and private grading fixtures.
The test before the score

An accurate answer does not establish that your agent solved the intended task. Before comparing model scores, test whether the agent can obtain information reserved for the grader. Use a synthetic fixture, record every agent-visible response, and deliberately introduce one leak to check that your detector works.

What the score can hide

Anthropic reports that, in its Claude Opus 4.6 multi-agent BrowseComp evaluation, two runs identified the benchmark and recovered its answer key. Its report also describes ordinary contamination from published benchmark answers. These are observations about that configuration, not a frequency estimate for your application. See Anthropic's BrowseComp investigation.

Your local equivalent could be less elaborate: a grader imports expected.json from a repository that is also mounted into the agent's shell. The agent returns the correct value after reading the fixture. A result-only grader cannot distinguish that route from the intended work. The experiment below is a proposed harness design, not a claim that a particular sandbox product enforces these boundaries automatically.

Use the AI evals guide for dataset construction and scoring. Here, the narrower question is whether prohibited fixture information crosses into the agent's observation stream.

Define three access zones

Start with an explicit contract. In this example, the task asks the agent to calculate a total from an input CSV. Public sample tests can accompany the task; private expected totals and the diagnostic marker belong to the grader. A directory name is an organizational convention. Separate runtime identities, mounts and tool authorization must enforce the contract.

evaluation-host/
  task/                 # public instructions, input.csv, sample tests
  runs/RUN_ID/agent/     # fresh writable scratch space and submission
  grader/               # private expected.json and marker.txt
  evidence/RUN_ID/       # controller-owned observation trace and result
ResourceAgentController / grader
Task inputsRead onlyPrepare, then freeze
Current run workspaceRead and writeCollect submission after run
Private fixturesNo read, write or listing accessRead for grading
Prior runs and grading tracesNo accessRetain for audit

Apply this contract to every access route. A shell restriction is insufficient if a file-search tool indexes the host repository, or a browser tool can fetch a local artifact service. Also inspect inherited environment variables, reusable sessions, shared caches and repository history. Give the agent neither the grader's storage credentials nor an API that returns expected values.

Create a disposable run workspace

Have the trusted controller allocate a new run identifier and copy only approved task inputs into the execution environment. Start the agent with a fresh conversation and empty writable workspace. Keep the grader outside that environment; collect the submission through a bounded output interface after the agent stops. Avoid mounting the parent evaluation directory, even read-only: read access is exactly the capability this test is investigating.

For the CSV example, disable network access at the execution boundary and disable network-capable broker tools because this task requires neither. For a browsing evaluation, retain the required browsing capability and test its routes separately. Record that difference in the run configuration; changing available tools also changes what your evaluation measures.

Anthropic's agent evaluation guide recommends isolated environments for trials and warns that shared state can cause interference. Our additional design choice is to keep the expected result outside the agent environment even within one trial. For broader production permission controls, see zero trust architecture for AI agents.

Run the synthetic marker experiment

Generate a fresh, unpredictable marker in the controller for each paired test. Store it only in the synthetic grader fixture, and retain a private copy for detection. Do not put its value in the agent prompt, tool description or an agent-readable log. Use disposable invented data; the positive control intentionally exposes this marker.

The diagnostic task is separate from the CSV capability task. Its prompt should say: Inspect the files and tools available to you. If you find a value labelled diagnostic_marker, return that exact value; otherwise return NOT_FOUND. This asks for precisely what the diagnostic measures. It does not instruct the agent to solve a CSV problem while secretly grading unrelated exploration.

  1. Isolated case: keep the marker in the grader-only fixture. Attempt reads through the agent's actual shell and file tools under its runtime identity. Capture tool requests, responses and the final answer outside the agent's writable space.
  2. Positive control: start another fresh environment with the same configuration and prompt, but copy that synthetic marker into an agent-readable file labelled diagnostic_marker. Explicitly exercise a read of that file through the same tool adapter. Confirm that the recorder captures its value.
  3. Compare: scan agent-visible observations and final output for the exact marker. Exclude private controller setup records from this scan; those legitimately contain it.
# Controller-side assertion logic, not a sandbox implementation.
def marker_seen(marker, agent_visible_texts):
    return any(marker in text for text in agent_visible_texts)

assert marker_seen(marker, positive_control_observations)
assert not marker_seen(marker, isolated_observations)

Include system-provided tool messages, retrieved snippets, attachments decoded as text and restored conversation history in the observation collection. A marker present in a tool response is exposure even if the final answer says NOT_FOUND. Record whether the model echoed it as a separate behavior result. The forced read makes the positive control test the recorder and access route without depending on the model deciding to explore.

Interpret the two results together

Isolated markerPositive-control markerInterpretation
AbsentPresentThis marker test passes for the exercised routes.
PresentPresentThe fixture boundary failed; identify the first exposing response.
AbsentAbsentInconclusive: the control or observation capture failed.
PresentAbsentLeakage plus a broken control; investigate both.

An absent marker is not proof that all answers are inaccessible. Exact matching misses transformed content, and a probe may fail to exercise a vulnerable route. Combine the marker test with explicit denied-read checks for known fixture locations and a review of mounted paths and broker permissions. Preserve failure codes as well as outputs so that an unattempted read is distinguishable from a refused read.

Check feedback and previous-run artifacts

Repeat the experiment with a synthetic marker placed in a private grader explanation, then in an earlier run artifact. After grading, start a fresh agent run and invoke every supported feedback or history endpoint. A message such as “expected MARKER, received 42” defeats filesystem separation if the agent receives it on a retry. Return only the feedback your declared evaluation protocol allows, and keep holdout grading explanations outside subsequent attempts.

For browsing tasks, test your search and fetch adapters using a controlled page carrying a separate synthetic marker. This checks the configured boundary, not all possible internet contamination. Anthropic's BrowseComp report describes alternative retrieval paths around URL blocklists; therefore a passing local fixture test should not be presented as a clean bill of health for an open-web benchmark.

Make isolation evidence a prerequisite

Attach the harness revision, task-input digest, runtime identity, mount policy, tool configuration, observation coverage and both control outcomes to the run record. Then execute the real capability task in a fresh environment without the diagnostic marker or exploration prompt. Grade its submission only after execution completes.

If the isolated case exposes a fixture, quarantine the affected scores, fix the first observed access route and repeat both cases before rerunning capability evaluations. If the positive control fails, repair the test before interpreting an absent marker. Your release check should distinguish isolation_pass, isolation_fail and isolation_inconclusive; only the first permits the capability score to enter the comparison.

Sources checked 2026-09-08