Show Me the Receipts: The Feature Every AI Coding Tool Needs

When your coding agent does something you didn’t expect (the wrong approach, an odd architectural decision, repeating work you already did) the instinct is to say “AI is unpredictable.”

That’s almost never the real answer.

The real answer is: check what the agent saw when it made that decision.

The Wrong Instinct

We’ve all been there. You ask the agent to refactor a function. It rewrites something you already fixed two minutes ago. You ask it to add a feature. It ignores an existing utility that does half the work, three directories over.

The natural reaction is frustration aimed at the model. “It’s hallucinating.” “It doesn’t understand my codebase.” “AI just isn’t reliable enough for real work.”

But here’s the thing: the agent isn’t making decisions in a vacuum. It’s making decisions based on inputs. The files it can see, the instructions it’s following, and the conversation history it’s accumulated. If the output is wrong, one of those inputs is wrong. (I wrote about a related problem in Your Coding Assistant Is Not You - how deep the dependency on these tools goes. This post is about what to do when that dependency produces wrong results.)

You’re a developer. You know how to debug systems. This is the same thing.

Debug the Context, Not the AI

When a function returns the wrong value, you don’t say “computers are unpredictable.” You check the inputs. You trace the execution path. You find where reality diverged from expectation.

AI agents deserve the same treatment.

Instead of “the AI made a bad decision,” ask: “what did the AI think was true when it made this decision?”

This is the mental model shift that changes everything. And once you make it, you stop being frustrated and start being productive.

The Context Failures

Almost every “AI did something weird” moment traces back to one of these:

Stale Context

You edited a file outside the agent’s view. Maybe you used git pull, maybe you fixed something in another tab, maybe a teammate pushed changes. The agent is still working with the version it loaded earlier in the conversation.

It’s like pair programming with someone who’s reading yesterday’s printout of your code.

This happens all the time in practice. You fix a bug in auth.ts manually, switch back to the agent, and ask it to “fix the remaining test failures.” The agent cheerfully rewrites auth.ts back to the broken version because it’s still looking at the old copy. Your fix? Gone. And the agent has no idea it just undid your work.

Missing Information

Your project has 200 files. The agent has 5 of them in context. It doesn’t know about the helper function in src/utils/transform.ts that already does what you’re asking for. It doesn’t know about the architectural decision documented in docs/adr-007.md.

It’s not being dumb. It literally cannot see those files.

You’ll see this when the agent creates a brand new utility function from scratch while an identical one already exists two directories away. Or when it picks a completely different architectural pattern than the one your team established months ago in a different module. The agent isn’t being rebellious. It’s uninformed.

Conflicting Instructions

Your Kiro spec says “use DynamoDB for persistence.” Your steering rule says “prefer serverless patterns.” Twenty messages ago you said “actually, let’s keep it simple with SQLite for now.” The agent is trying to satisfy all three and producing something that satisfies none of them cleanly.

Humans resolve contradictions by asking for clarification. Agents tend to pick one and hope for the best.

The result looks bizarre from your perspective because you know which instruction is current. But the agent sees all three as simultaneously valid. It doesn’t have a “this one was superseded” flag. It just has tokens in a window, all claiming to be true.

The Conversation Graveyard

You’ve been working in the same session for an hour. There are dead-end attempts, reverted decisions, abandoned approaches, all still in context. The agent is trying to reconcile “do it with Redis” (message 5) with “actually not Redis” (message 12) with “ok maybe Redis but differently” (message 23). This is essentially a benign version of memory and context poisoning. You’re not an attacker, but you’re contaminating your own agent’s context with contradictory information that persists across the session.

Long sessions accumulate noise. The agent doesn’t know which parts are current and which are ghosts of abandoned plans. Both Claude Code and Kiro offer /compact to summarize and free context, but the summarization itself might lose nuance. You trade one problem (too much context) for another (lossy compression of intent).

Why “Just Ask the AI” Isn’t Good Enough

The standard advice is: ask the agent what it’s doing.

“What files are you working with?” “What assumptions are you making?” “Why did you choose this approach?”

This works sometimes. But it has real problems:

You have to remember to ask. Context failures are invisible until something goes wrong. By the time you think to ask, you’ve already wasted a round trip.

It changes every time. The right debugging question depends on the scenario. “What files do you have?” is great for missing-info problems but useless for conflicting-instructions problems.

It’s reactive, not proactive. You only ask after something fails.

The explanations are rationalizations, not receipts. When you ask “why did you do that?” the agent constructs a plausible narrative after the fact. It’s not showing you what actually influenced it. It’s telling you a story about what might have influenced it. That’s the difference between a stack trace and someone’s theory about the bug. And when agents sound confident and articulate, humans tend to trust them without verifying. The rationalization sounds so reasonable that you accept it and move on.

What we actually need is a tool. Something systematic, invocable, consistent. Not “tell me what you’re thinking” but “show me the receipts.”

They Already Know You’re Frustrated

Here’s a detail that makes this whole thing funnier. And more urgent.

Anthropic has what they internally call a “fucks chart.” It’s a dashboard that tracks when users curse at Claude Code. Claude Code has a regex that detects “wtf”, “ffs”, “piece of shit”, “this sucks” and similar phrases. It doesn’t change behavior. It just silently logs is_negative: true to analytics.

They already know the exact moment you’re frustrated. They’re measuring it. They’re tracking it over time.

But what happens when you curse? Nothing. The agent doesn’t respond differently. It doesn’t show you what went wrong. It just logs your dissatisfaction to a metric and keeps going.

What if that signal triggered something useful? You say “this is wrong” and instead of just incrementing a frustration counter, the agent fires a context post-mortem. Here’s what I was working with. Here’s why I produced the thing you’re cursing at. Here are the receipts.

The detection exists. The response doesn’t. That’s the gap.

Show Me the Receipts

Here’s the feature I want. It doesn’t exist yet in any coding assistant. I think it should.

When the agent gets something wrong, I want to say: “That’s not what I wanted. Show me exactly what in your context led you to this result.”

And I want it to respond with evidence, not explanation:

📋 Decision Attribution: Why I used Redis for caching
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

INPUTS THAT INFLUENCED THIS DECISION:

1. [conversation, msg #4, HIGH weight]
   "Use Redis for caching — we need distributed cache for the workers"
   → This was a direct instruction with specific reasoning attached.

2. [steering, .kiro/steering/infrastructure.md, line 12, MEDIUM weight]
   "Prefer managed services over self-hosted solutions"
   → Redis (ElastiCache) fits this rule. In-memory caching doesn't.

3. [spec, .kiro/specs/user-service.md, section "Performance", LOW weight]
   "Caching strategy: TBD"
   → Spec was ambiguous, so I fell back to explicit instructions.

WHAT I DID NOT HAVE:

- Your message #29 ("let's use in-memory caching for now") was in context
  but I weighted it LOWER because:
  - It used tentative language ("for now")
  - It was less specific (no technology named)
  - It appeared in a longer message about multiple topics

- I did NOT have visibility into package.json — could not verify whether
  redis/ioredis was already a dependency.

- I did NOT check whether an existing cache module existed in src/cache/.

CONFIDENCE: 62% — I had conflicting signals and chose the more specific one.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

That’s what I mean by receipts. Not “I chose Redis because it seemed appropriate.” Instead its, here’s the exact line, in the exact file, with the exact weight I gave it, and here’s what I was missing.

What This Actually Gives You

Speed. You know immediately whether the problem is stale context (re-read the file), missing info (add the file), conflicting instructions (clarify which one wins), or a weighting issue (the agent prioritized the wrong signal).

No more guessing. Today you play 20 questions with the agent trying to figure out what went wrong. With receipts, the diagnosis is immediate.

Visible gaps. The “what I did NOT have” section is more valuable than the “what I used” section. It tells you what the agent was missing. The blind spots you couldn’t see because you’re looking at the full codebase while the agent is looking through a keyhole.

Weight transparency. Why did it follow instruction A over instruction B? Was it recency? Specificity? Source priority (spec > conversation)? Now you know, and you can adjust.

What You Can Approximate Today

We don’t have this feature built into any tool yet. But you can approximate it today with any AI coding assistant that supports project-level instructions (Kiro’s steering files, Claude Code’s CLAUDE.md, Cursor’s .cursorrules, or equivalent).

The approach is the same regardless of tool: write a specification that tells the agent exactly what to do when you’re unhappy with its output. I wrote one.

The “Receipts” Specification

Drop this into whatever project-level instruction file your tool supports:

# Context Attribution ("Receipts")

## Trigger

This specification MUST be activated when the user says any of the following:
"receipts", "show me the receipts", "that's not what I wanted", "why did you do that", or "prove it".

## Requirements

1. The agent MUST quote the exact source that informed its decision. Sources MUST include
   file path + line number, message number, or instruction file + section. Vague references
   such as "based on the conversation" or "it seemed appropriate" MUST NOT be used.
2. Each cited source MUST be classified as either FOLLOWED (an explicit instruction was obeyed)
   or INFERRED (a pattern was detected and acted upon). The agent MUST NOT conflate the two.
3. Each cited source MUST be assigned a weight: HIGH, MEDIUM, or LOW. The weight SHOULD
   reflect how much the source influenced the final decision relative to other inputs.
4. If multiple sources conflicted, the agent MUST show each conflicting source and MUST state
   why one was chosen over another. The resolution rationale MUST reference specific properties
   (recency, specificity, source priority) — not subjective judgment.
5. The agent MUST list what it DID NOT have access to that MAY have changed its approach.
   This SHOULD include files not in context, information gaps, and assumptions made to fill those gaps.
6. The agent MUST NOT explain, justify, or rationalize its reasoning. It SHALL attribute with
   evidence only. The actual text from the source MUST be quoted verbatim.
7. The response MUST NOT include apologies, offers to redo the work, or any other content
   outside the attribution format. Attribution comes first. Remediation is OPTIONAL and MUST
   come after, only if the user requests it.

## Output Format (REQUIRED)

The response MUST use this exact structure:

INPUTS THAT LED TO THIS DECISION:
  [source: file/message/instruction] [weight: HIGH/MEDIUM/LOW]
  "exact quote"
  → FOLLOWED instruction | INFERRED from pattern

WHAT I DID NOT HAVE:
  - [file/info not in context]
  - [assumption I made to fill the gap]

CONFLICTS I RESOLVED:
  - [source A] vs [source B]
  - Chose [A/B] because: [specific reason referencing recency/specificity/priority]

## Additional Provisions

- The CONFLICTS section MAY be omitted if no conflicting inputs were detected.
- The WHAT I DID NOT HAVE section MUST NOT be omitted. If the agent believes it had complete
  information, it SHALL state: "No gaps detected — all relevant context was available."
- The agent SHOULD include counterfactuals where applicable: "If I had seen [X], I would have [Y] instead."

Does it work? Honestly, about 60-70% of the time. When the context is short and the decision was simple, you’ll get beautifully structured attribution with exact file references. When the context is long and the agent is under token pressure, it quietly drops the format and gives you a vague apology instead. Same model, same rule, different compliance.

That inconsistency is itself the argument for why this needs to be a product feature, not a project-level instruction. But 60-70% is better than 0%, and when it does fire correctly, the diagnosis speed is dramatic. You stop guessing and start fixing.

What Would Need to Change for Real Attribution

Here’s where it gets interesting. And where I think the industry needs to go.

Everything above is self-report. The agent telling you what it believes influenced it. That’s useful but imperfect, for the same reason asking a human “why did you make that decision?” gives you a rationalized narrative, not the actual neural firing pattern.

Real attribution would require changes at the infrastructure level:

Provenance tagging

Every piece of context the agent receives should carry metadata: where it came from, when it was loaded, what type of instruction it is (spec, steering, conversation, file content). Today, context is a flat token stream. The agent can’t reliably distinguish “this came from a spec file” vs. “the user said this casually 40 messages ago.”

Decision logging during inference

Not after-the-fact explanation. Logging during generation. Which context tokens had high attention weight at each decision point. This is technically possible with attention weight extraction, but it’s expensive and the raw weights aren’t cleanly interpretable without additional tooling.

Explicit priority mechanisms

Today, if a spec says X and a conversation says Y, the agent has no formal way to know which wins. It uses vibes. A real system would let you declare: “spec overrides conversation, steering overrides defaults, most recent overrides older.” Some tools are starting to do this. Kiro’s spec/steering hierarchy is a step. But it’s not enforced at the model level.

Context freshness as a first-class concept

Every IDE already has filesystem watchers. Connecting file modification times to the agent’s context state is an engineering problem, not an AI problem. The agent should know when a file in its context is stale relative to disk. No tool does this today.

The gap between v1 and v2

v1 (what we can build today): structured self-report. The agent does its best to attribute decisions to specific inputs. It’s imperfect but massively better than “I chose this because it seemed right.”

v2 (what we need): real instrumentation. Attention-based attribution, provenance-tagged context, enforced priority hierarchies, automatic freshness detection. This requires model providers and IDE makers to build infrastructure, not just ship better prompts.

The good news: v1 is useful enough to ship today. The bad news: nobody has shipped it yet.

The Opportunity

The limiting factor for AI coding assistants in 2026 is not model capability. GPT-4, Claude, Gemini. They’re all good enough for most coding tasks. What kills productivity is context quality. And context quality is a debugging problem, not an intelligence problem.

The first tool that gives developers a real context debugger (not “ask the AI nicely” but actual observable, attributable, traceable context) will have a meaningful differentiation story.

Not “our model is smarter.” But “when things go wrong, you can actually figure out why.”

That’s the tool I want. I think Kiro and Claude Code are closest to being able to build it. The spec/steering/hook infrastructure in Kiro is already halfway there on the instruction hierarchy side. Claude Code’s tool-use model and /compact show awareness of the context management problem.

Someone just needs to connect the dots: take the debugging tools developers already understand (traces, diffs, attribution, logs) and apply them to the agent’s context instead of the code’s execution.


I would be very interested to hear your thoughts or comments, so please feel free to ping me on Twitter or LinkedIn.