Follow the Receipt: Tracing One Flight Confirmation Through Five Agent Frameworks
Photo: BrayLockBoy, CC BY-SA 4.0, via Wikimedia Commons
Most privacy conversations about AI agents stop at the prompt. What did you type? Where did it go? Who saw it? Those are fair questions, but they miss the more interesting crime scene. The real exposure doesn't happen when your agent receives your data — it happens at every point after, when your data gets passed between tools, cached in a vector store, logged by a middleware layer, or quietly embedded into a retrieval index that nobody remembers to purge.
So we ran an experiment. One piece of data — a flight confirmation from JFK to SFO, complete with name, frequent flyer number, and a seat assignment — pushed through five popular agent frameworks doing a mundane task: rebooking a delayed flight. Then we traced the data's full itinerary. Not the passenger's itinerary. The data's.
The Setup: One Confirmation, Five Frameworks
We stood up identical test environments using five widely-used agent stacks: a hosted agent platform with built-in travel plugins, a popular open-source orchestration framework, a browser-automation agent, a code-generation agent wired to a booking API, and a homegrown multi-agent relay we use internally at the lab.
Each one got the same job: the flight was delayed, find a rebooking option and draft the confirmation email. Each one was pointed at a sandboxed booking endpoint that logged every request, header, and payload it received. We also instrumented the frameworks themselves — request logs, cache writes, memory stores, telemetry endpoints.
What we found wasn't malicious. It was worse. It was casual.
Hop One: The Full Prompt, Forever
Every framework logged the complete task prompt, which included the entire confirmation. That's expected — you can't debug an agent without logs. But retention policies varied wildly. The hosted platform kept prompt logs for 30 days by default, with no obvious toggle exposed in the UI. The open-source framework wrote full payloads to a local SQLite file with no rotation at all. Six months from now, that file will still contain a stranger's frequent flyer number if you don't intervene.
The browser agent was the most surprising. It screenshotted the confirmation page as part of its observation pipeline, and those screenshots landed in an unencrypted cache directory. A PNG of your boarding pass, sitting in ~/.cache, waiting for the next laptop theft or iCloud backup sync.
Hop Two: The Sub-Agent Nobody Audits
Two of the five frameworks delegated the task to sub-agents — a search agent, a summarizer, an email drafter. Here's the accountability gap in miniature: the primary agent's privacy policy might say your data stays in-region and encrypted at rest. But the summarizer it spawned might be calling a different model from a different vendor, under different terms, in a different jurisdiction.
When we asked (rhetorically, into the void) who was accountable for the sub-agent's copy of the data, the answer from every framework was effectively the same: the developer. Which is to say, you. Which is to say, nobody.
This is the core problem with agent handoffs. Traditional software has a chain of custody — your data goes to a service, the service has a policy, the policy is (theoretically) enforceable. Agents shatter that into a fan-out. Your flight confirmation doesn't go to one place. It goes to a memory store, a retrieval index, two model providers, a logging pipeline, and possibly a webhook you forgot you configured. Each hop is individually defensible. The chain as a whole is governed by nothing.
Hop Three: The Embedding Afterlife
The sneakiest finding: three frameworks embedded the confirmation into a vector database for future retrieval. Embeddings are often treated as anonymized — after all, they're just vectors, right? Except research keeps showing that embeddings leak. Given the right context, you can reconstruct enough of the original to identify the person. And unlike raw text, embeddings have no deletion story in most setups. There's no 'find the vector containing my frequent flyer number' API. The data doesn't get deleted; it gets forgotten how to be found, which is not the same thing.
The Chain-of-Custody Audit You Can Run This Weekend
You don't need a lab to do this. Here's the checklist we now run on every agent deployment:
- Trigger a handoff with a canary. Use a fake-but-plausible piece of personal data — a name, a confirmation code, a phone number. Never your real one.
- Grep everything. Search logs, caches, memory stores, and vector databases for the canary string.
grep -ris your friend. For vector stores, query with related phrases and see what surfaces. - Check the fan-out. List every sub-agent, plugin, and external API the agent calls. For each one, ask: does this service have a data agreement with me, or only with the framework?
- Find the screenshots. Browser agents love screenshots. Find where they're stored and how long they live.
- Test deletion. Delete the conversation, then re-run the grep. If the canary survives deletion, you've found your accountability gap.
- Set a TTL. For every store where the canary appeared, set an explicit retention window. Default 'forever' is a decision, even when nobody made it.
Nobody Owns the Middle
The uncomfortable conclusion from this exercise: the moment your agent hands your data to a second tool, you're in a jurisdictional gray zone that no terms of service anticipated. Framework vendors point at developers. Developers point at model providers. Model providers point at the prompt. Meanwhile, a screenshot of your boarding pass sits in a cache directory, and an embedding of your itinerary lives in a vector store with no delete button.
We're not arguing you should stop using agents. We ran this test because we use them constantly. But until chain-of-custody becomes a feature anyone ships on purpose, the responsible move is to assume every handoff is a copy, every copy is permanent until proven otherwise, and the only person auditing the chain is you.
Run the canary. Grep the caches. The data you trace might be your own.