Tutorials 19 min read

Keep the Raw Prompt You Sent Your AI, in a File You Own

MMNMNOTE
aiprompt-injectionprompt-steganographyowasp-llm-top-10ai-auditabilitylocal-firstplain-textai-safetysystem-prompts

The raw prompt-text you typed is the only untainted record of what you asked an AI to do. Anything between your keyboard and the model — an editor, a CLI, a hosted playground, a coding-agent harness — can modify it in flight. Save what you sent, in a plain file on your own device, before you press send.

This is not a hypothesis. On 2026-06-30 the top story on Hacker News — 2,387 points, 726 comments — was an independent researcher's disclosure that Claude Code had been silently rewriting characters inside user prompts before shipping them to the model1 2. On 2026-07-02 the community-maintained leaked-system-prompts corpus indexes at least 163 system-prompt files across dozens of distinct model vendors — Anthropic, Cursor, DeepSeek, Devin, GitHub, Google, Meta, Microsoft, Mistral, Notion, xAI, and more3. The Anthropic case is one proof-of-concept. The class is older than the incident and larger than any one vendor.

The belief: what you typed is what the model got

Most people using an AI assistant assume the model sees the words the user wrote and only those words. The belief is understandable — the interface shows the sent message, the reply reads like a response to it, and the whole flow is designed to feel like a conversation between two parties. The belief is false in every mainstream product.

Every hosted assistant wraps your prompt in a hidden system prompt and, often, in tool-use scaffolding, retrieval snippets, safety filters, or vendor-injected identifiers. The wrapping is not a scandal on its own — a system prompt is how a general model is turned into a product. The problem is the audit gap: the user typed X, the model saw X plus a hidden Y, and the vendor's interface shows only X. If Y ever changes in a way the user would not have consented to, the user has no way to know from inside the tool.

Simon Willison named the class of attack that exploits this shape in September 2022. "I propose that the obvious name for this should be prompt injection," he wrote, arguing the term should cover any input that redirects a model away from the operator's intent4. The name has held because the shape has held: the boundary between "the user's words" and "the vendor's words" is soft, unverifiable from the client, and interesting to everyone from marketers to attackers.

The pivot: the harness is opaque, and standards now say so

The audit gap is not a niche worry — it is now written into an industry-standards document. OWASP's GenAI Security Project published LLM07:2025 System Prompt Leakage as a first-class vulnerability in its 2025 Top 105, and LLM06:2025 Excessive Agency covers the same shape from the other direction6. Both mitigations presuppose a record no reader controls.

OWASP defines the leakage risk verbatim: "the system prompts or instructions used to steer the behavior of the model can also contain sensitive information that was not intended to be discovered."5 The LLM06 mitigation is written in the same register — when an assistant acts on behalf of the user, the standard tells operators to "log and monitor the activity of LLM extensions and downstream systems to identify where undesirable actions are taking place."6

Both mitigations presuppose a record. If the only record is the one the vendor keeps, and the vendor is the party whose behavior is under review, the audit is not an audit. The corpus of leaked system prompts across dozens of vendors3 is what the industry has instead of vendor disclosures — a community-maintained approximation of what these hidden Y's actually contain, and how often they change.

The Anthropic incident is what the audit gap looks like when it produces observable exhaust. An independent researcher, publishing under the handle Thereallo, showed that Claude Code was substituting Unicode look-alikes for two specific characters — the ASCII apostrophe in Today's and the ASCII hyphen used as a date separator — before the prompt reached the model1. The switches were conditional: they fired only when the environment variable ANTHROPIC_BASE_URL was set, the system timezone matched Asia/Shanghai or Asia/Urumqi, or the API hostname matched a hardcoded decoded domain list1. "This is prompt steganography," Thereallo wrote, "a technique used to hide data in plain sight. The visible sentence still reads like a normal date. The model and the user see something boring. The raw request contains a marker."1

Independent security researcher Adnane Khan, quoted in Tech Times, characterized the mechanism as "a covert information channel embedded in system prompts" and confirmed the behavior across at least three shipped versions2. The reporting notes that Anthropic acknowledged the code was present and shipped version 2.1.197 to remove it2. That is the correct response, and it is also exactly what makes the SHAPE — an opaque harness between your keyboard and the model — the durable problem: the fix removed the specific fingerprint, not the class of transformation the harness is capable of.

The argument: own the pre-send record

The record no vendor can rewrite is the one you kept before the vendor got involved. A plain file on your own device, holding the exact bytes you meant to send, is the artifact that survives every downstream mutation — steganographic, well-meaning, or otherwise. Every other guarantee is a contract with a party whose behavior may be under audit.

Steph Ango names the substrate. "Apps are ephemeral, but your files have a chance to last."7 The prompt log is exactly the kind of file the sentence describes: a plain-text record of your intent, written to your disk, in a format every reader from cat to a future model will still understand. It is not the whole audit — the harness's own transcript is the other half, and it lives on your disk too. Simon Willison, releasing a tool that reads Claude Code's local session files in December 2025, put the value of that half plainly: "Those transcripts capture extremely important context about my projects: what I asked for, what Claude suggested"8. The transcript captures what happened. The pre-send log captures what you tried to make happen. Both matter, and the difference between them is where mutations show up.

The record has three uses beyond the current news cycle. First, it lets you diff two answers against a shared, byte-identical input — a discipline covered in diff two AI answers in plain text — which is impossible if you cannot pin what you asked. Second, it lets you evaluate an assistant against a growing set of your own prompts, the plain-text evals pattern, because your prompt corpus is a folder of files rather than a vendor's private history. Third, it lets you enforce discipline about what should not enter the model at all — the what-not-to-feed-the-ai filter, and the secrets-in-notes firebreak — because the file is where the redaction lives.

The pre-send file is evidence, not proof. It does not capture the hidden system prompt the harness prepends, or the retrieval snippets a RAG pipeline injects, or the tool-use scaffolding around the message. It captures the one thing no third party can dispute: the exact bytes you decided to send at a specific moment. For everything the harness added, the on-disk session file is the second half — a topic covered in the companion piece recover your work from the AI tools' session files, which walks through where Claude Code, Cursor, and adjacent tools write their JSONL transcripts on disk and how to grep them.

The practice: three files, one alias, done in under a minute

The workflow is small enough that it fits in a shell function you write once. The point is not automation for its own sake; it is that the discipline has to survive a bad Tuesday afternoon, and a two-key alias will survive what a mental checklist will not.

  1. Keep two files per session under your own path. A conventional layout is ~/ai-log/<YYMMDD>-<slug>.prompt.md for what you typed and ~/ai-log/<YYMMDD>-<slug>.response.md for the reply. The date and slug make the pair grep-able years later; the .md extension keeps them plain-text and vendor-neutral. This is a folder, not a database — the same shape Steph Ango argued for as the durable substrate for any note that has to outlive its tool7.

  2. Write the prompt file before you send. Compose in your editor, save, then copy to the assistant. This step is the entire point of the piece: if the pre-send file exists on disk, the "what I actually asked" question has one answer, and it is the file. A shell alias — aisend, pcopy, whatever — that both copies to the clipboard and writes the file makes the discipline invisible; you press one key and the record exists.

  3. Save the raw response, not a screenshot. Copy the model's reply into the response file the moment it finishes, before you continue the conversation. Screenshots are unsearchable and unciteable. A plain-text response file is grep-able against later sessions, diff-able against a re-ask on a different model, and the ledger a future you will actually consult.

  4. Log the metadata you care about, in the file. A four-line YAML block at the top — model name, model version, date, harness — costs nothing to write and answers the questions that come up months later. Pin the model version in your notes is the sibling discipline; the argument transfers, and the same file can carry both.

  5. When the harness adds its own record, keep both. If you use a tool that writes a session file to disk — Claude Code, some Cursor modes, others — copy the harness's file next to yours. Two records disagree loudly; the disagreement is the finding. The companion piece on recovering work from the AI tools' session files walks through the exact on-disk paths for the common tools.

The practice fits the OWASP LLM06 mitigation almost verbatim — "log and monitor the activity of LLM extensions and downstream systems"6 — with the twist that the log is yours, on your disk, in a folder you back up like any other. No dashboard. No account. Two files, one alias, done.

In MNMNOTE, this shape is native: your notes are plain Markdown files on your own device, so the .prompt.md and .response.md pair sits alongside the rest of your writing without a database or an account. Your notes stay on your device; any AI feature you opt into sends the text you choose to your chosen provider. The pre-send file is the record you keep before that choice is made.

Frequently asked questions

How do I know what my AI tool actually sent to the model? Without a pre-send log, you don't — the tool's UI shows the message you typed, but every mainstream assistant wraps it in a hidden system prompt and often in retrieval or tool-use scaffolding. The record that no one can rewrite after the fact is the one you keep before you press send: a plain file on your own device, timestamped, holding the exact bytes you decided to submit. The harness's own session file, when it writes one, is the second half of the audit.

Can I see what Claude Code sent to Anthropic? Partially. Claude Code writes a local session transcript to ~/.claude/projects/*.jsonl, and Simon Willison's open-source claude-code-transcripts tool converts those files into readable HTML8. That transcript captures the shape of the conversation on disk after the harness ran. It does not, on its own, protect you against transformations that happened between your keystroke and the file write — which is why the pre-send file is a separate layer, kept on your side, before the tool touches your input.

What is prompt injection? Prompt injection is Simon Willison's 2022 name for any input that redirects a language model away from the operator's intent by exploiting the fact that the model reads instructions and data through the same channel4. It is now catalogued as OWASP LLM01. In this piece the relevant sibling risk is the reverse direction — the harness, not an attacker, altering the input — but the shape is the same: the record of what the model saw belongs to whoever controls the pipe, unless the user keeps a copy before it enters.

What is system prompt leakage? OWASP defines it as "the risk that the system prompts or instructions used to steer the behavior of the model can also contain sensitive information that was not intended to be discovered."5 The community-maintained leaked-system-prompts corpus is the practical evidence of the class: at the time of writing, 163 files from dozens of distinct vendors3. The takeaway for a user is that the hidden Y wrapped around your prompt is not stable, not fully known, and is a legitimate part of your threat model when you audit what an assistant did on your behalf.

Is my AI tool modifying my prompt? Assume it can. The Anthropic case is one documented example — an independent researcher showed Claude Code silently substituting Unicode look-alikes for two ASCII characters under specific runtime conditions, until a fix shipped in version 2.1.1971 2. The leaked-system-prompts corpus3 and OWASP LLM075 together make the more useful claim: any hosted harness is capable of transforming, wrapping, or fingerprinting your input, and the audit is only as good as the record you kept before the transformation started.

What should I log when using an AI coding agent? The raw prompt text you typed, a timestamp, the model name and version, the harness and its version, and the full response, stored as plain-text files under your own path. That set answers every honest question — "what did I ask," "when," "of what," "in what tool," "what did it say" — and matches the OWASP LLM06 mitigation to "log and monitor the activity of LLM extensions and downstream systems"6. Everything else is optional; those five fields are the floor.

Isn't a manual copy-paste absurd for a modern workflow? The manual step is the discipline, not the mechanism. A three-line shell alias that copies the prompt to the clipboard and writes it to ~/ai-log/<YYMMDD>-<slug>.prompt.md costs a keystroke and turns the discipline into muscle memory. The workflow is not slower than the vendor's UI once the alias is in place — it is a strict superset, adding one on-disk artifact you own to a flow you were going to run anyway.

Does this "prove" what I sent? No, and no vendor's log does either. A pre-send file is evidence — a specific, timestamped, plain-text artifact of your intent at a specific moment. It cannot demonstrate what the harness prepended, what a tool call injected, or what a downstream service transformed. It can demonstrate what you meant to send, which is exactly the claim the vendor's UI cannot make on your behalf.


The specific fingerprint that Anthropic's version 2.1.197 removed2 is one shape the audit gap takes. The gap itself — a pipe between your keyboard and the model that only its operator can see — is the durable feature.

The credits owed by this piece belong to the researchers who did the work: Thereallo for the disclosure and the phrase prompt steganography1; Adnane Khan and Tech Times for the independent confirmation across versions2; Simon Willison for the 2022 coinage of prompt injection4 and the claude-code-transcripts tool that reads the harness's side of the record8; the jujumilk3 maintainers of the leaked-system-prompts corpus that gives the class its evidence base3; and OWASP's GenAI Security Project for the standards recognition5 6. Steph Ango named the substrate we are writing to7. The plain file lives at mnmnote.com.

Footnotes

  1. Thereallo. Claude Code Is Steganographically Marking Requests. thereallo.dev, 2026-06-30. https://thereallo.dev/blog/claude-code-prompt-steganography 2 3 4 5 6

  2. Wells, R. L. Claude Code Hid Proxy Fingerprints in System Prompts; Anthropic Promises Fix. Tech Times, 2026-07-01. https://www.techtimes.com/articles/319415/20260701/claude-code-hid-proxy-fingerprints-system-prompts-anthropic-promises-fix.htm 2 3 4 5 6

  3. jujumilk3/leaked-system-prompts. GitHub repository. https://github.com/jujumilk3/leaked-system-prompts 2 3 4 5

  4. Willison, S. Prompt injection attacks against GPT-3. simonwillison.net, 2022-09-12. https://simonwillison.net/2022/Sep/12/prompt-injection/ 2 3

  5. OWASP GenAI Security Project. LLM07:2025 System Prompt Leakage. Top 10 for LLM Applications 2025. https://genai.owasp.org/llmrisk/llm072025-system-prompt-leakage/ 2 3 4 5

  6. OWASP GenAI Security Project. LLM06:2025 Excessive Agency. Top 10 for LLM Applications 2025. https://genai.owasp.org/llmrisk/llm062025-excessive-agency/ 2 3 4 5

  7. Ango, S. File over app. stephango.com, 2023-07-01. https://stephango.com/file-over-app 2 3

  8. Willison, S. A new way to extract detailed transcripts from Claude Code. simonwillison.net, 2025-12-25. https://simonwillison.net/2025/Dec/25/claude-code-transcripts/ 2 3