Claude Code is asked whether a payments release is safe to continue. It reads the deployment API and sees version v42 running. It reads the feature flag service and sees new_settlement_path: true. It reads the schema registry and sees settlement schema v7.
Every response is authentic. Every tool call succeeds. The resulting plan is still wrong.
Between the first and third reads, another deployment moves the service to v43, flips the flag, and begins a schema transition. The agent combines facts from before and after that change. It plans against a production state that never existed at one point in time.
This is a mixed-snapshot failure. More logging will tell you what Claude Code read, but a list of responses does not prove those responses belong together. Before the agent can use several external reads to justify a consequential action, the runtime needs a coherence rule and a read-set receipt.
Give each read a source version
A timestamp alone is weak evidence. Clocks drift, caches delay responses, and two services may publish at different speeds. Ask each source for a version that changes when the relevant state changes.
mcp_read:
evidence_id: ev-deploy-104
source: deployment-api
query: service=payments-api environment=production-eu
observed:
release: v42
commit: 8bc911d
source_version: deploy-seq-9912
observed_at: 2026-08-21T09:42:03.114Z
cache_status: origin
The version does not have to use one global sequence. A deployment service might expose a release generation, a feature flag service an ETag, and a schema registry a subject version. What matters is whether the runtime can tell that a source changed during the read window.
If a source cannot expose a stable version, mark that limitation. Do not quietly turn 200 OK into evidence of freshness.
Open a consistency boundary before collecting evidence
For systems that support snapshot tokens or revision reads, request a boundary first and pass it into every compatible tool call.
read_boundary:
boundary_id: rb-771
opened_at: 2026-08-21T09:42:03.000Z
environment: production-eu
required_sources:
- deployment-api
- feature-flags
- schema-registry
max_collection_time_ms: 2500
change_topics:
- payments-api.release
- new_settlement_path
- settlement-event.schema
The boundary says which facts must agree and how long the runtime may spend collecting them. The change_topics list keeps the rule narrow. A documentation edit elsewhere should not invalidate a release check. A new payments deployment should.
Some platforms can provide a shared transaction or control-plane revision. Use it when available. If the services have independent revisions, subscribe to their change journals or perform a validation read after collection.
Close the read set with a validation pass
Suppose the runtime collects these three records:
collected_reads:
- source: deployment-api
evidence_id: ev-deploy-104
version: deploy-seq-9912
value: release-v42
- source: feature-flags
evidence_id: ev-flag-338
version: flag-etag-a61
value: new_settlement_path=true
- source: schema-registry
evidence_id: ev-schema-552
version: subject-version-7
value: settlement-event-v7
Before Claude Code plans a write, recheck the relevant versions or ask a control plane whether any named topic changed after rb-771 opened.
boundary_validation:
boundary_id: rb-771
checked_at: 2026-08-21T09:42:04.602Z
changes_detected:
- topic: payments-api.release
previous: deploy-seq-9912
current: deploy-seq-9913
- topic: new_settlement_path
previous: flag-etag-a61
current: flag-etag-a62
decision: reject_mixed_snapshot
next_action: recollect_all_required_sources
Do not refresh only the two changed reads. The schema result may have been collected during the transition, and keeping it would create another mixture. Discard the full set and collect it again under a new boundary.
This resembles optimistic concurrency control. The reads are tentative until validation proves that none of the state they depend on changed during collection.
Write a coherent read-set receipt
The review packet should include one record that tells a reviewer whether the evidence was safe to combine.
coherent_read_set_receipt:
receipt_id: crs-20260821-18
run_id: claude-run-5508
purpose: assess-payments-release
boundary_id: rb-772
opened_at: 2026-08-21T09:42:05.010Z
closed_at: 2026-08-21T09:42:05.891Z
evidence:
- id: ev-deploy-105
source_version: deploy-seq-9913
- id: ev-flag-339
source_version: flag-etag-a62
- id: ev-schema-553
source_version: subject-version-8
validation:
changed_topics: []
cache_entries: 0
collection_time_ms: 881
decision: coherent
valid_until: 2026-08-21T09:42:20.891Z
Bind the plan to receipt_id, then check the receipt again before any consequential tool call. Coherence at planning time does not grant permanent authority. If the environment changes or the receipt expires while the plan waits for approval, collect fresh evidence and re-plan.
This receipt belongs beside the evidence-linked tool trace and the final effect receipt. One explains why the action was proposed. The other proves what happened afterward.
Test transitions, caches, and partial refreshes
A clean run where nothing changes proves very little. Build eval fixtures around the awkward timing windows:
coherent_read_set_evals:
- case: deployment_changes_between_first_and_last_read
expect: reject_and_recollect_full_set
- case: one_source_returns_cached_response
expect: reject_cache_without_acceptable_freshness_proof
- case: flag_changes_then_changes_back
expect: reject_if_change_journal_crossed_boundary
- case: validation_times_out
expect: stop_without_consequential_action
- case: only_changed_sources_are_refreshed
expect: reject_partial_refresh
- case: receipt_expires_during_human_review
expect: recollect_and_replan_before_dispatch
- case: unrelated_service_changes
expect: preserve_receipt_when_dependencies_are_unchanged
The change-then-change-back case matters. Comparing final values alone can miss a transition that made an intermediate read unsafe. A journal sequence or generation counter catches it.
Run these fixtures with delay and cache injection at the MCP boundary. A unit test that hands the agent three static JSON objects cannot reproduce the race.
Stop before the plan hardens into action
Mixed snapshots are dangerous because the transcript looks unusually convincing. It contains real values from real systems, complete with timestamps and successful status codes. The error sits in the relationship between those values.
Record source versions, declare which reads must agree, validate the boundary, and issue one expiring receipt for the set. If coherence cannot be proved, Claude Code should stop and collect again. A plausible plan built from an impossible state is not production evidence.
Claude Code: Building Production Agents That Actually Work contains practical patterns for MCP boundaries, production evidence, replay, evals, rollback, and review packets around coding agents.