Skip to content

Reference is the disk, not what the agent was shown: "unchanged" is returned for ranges it never saw #11

Description

@Nyarlathoteppppp

What happens

cachebro decides "unchanged" by comparing the file on disk against its own cache. But the cache records what cachebro has seen, not what the agent has been shown. When the agent reads a different range of a file that has not changed on disk, cachebro answers with a stub for lines the agent has never seen:

1. agent reads src/app.ts lines 1-100     → cachebro caches the whole file, passes the read through
2. agent reads src/app.ts lines 300-350   → file unchanged on disk
   → "[cachebro: unchanged in lines 300-350 of 800, ~9000 tokens saved]"

The agent asked for lines 300–350, was told they are "unchanged", and never received them. It has no way to notice: from its point of view the read succeeded.

The same applies to the whole-file path: if the first read was partial (offset/limit) the cache still holds the full file, so a later full read can be answered [unchanged, N lines] although the agent only ever saw a slice.

How often, on real sessions

I replayed 22 real coding-agent sessions (10,162 tool results, 3,837 reads) and counted where this rule would fire:

re-reads of a file already read earlier 2,819
…where cachebro would answer "unchanged" (no edit to that file in between) 2,301
…of those, where more than half of the requested lines had never been shown to the agent 598 (25%)
content in those 598 cases that the agent would never see ~458,000 tokens

The reason it is so common: 97% of re-reads in these sessions use different offset/limit arguments. Re-reading the exact same range is the rare case, not the common one.

Suggested fix

Make the reference "what has been shown to this agent in this conversation", not "what is on disk":

  • record the line ranges (or the exact text) actually returned to the agent;
  • answer "unchanged" only for lines the agent has already received;
  • for a range it has not seen, return the content even when the file is unchanged.

A stricter version that needs no range bookkeeping: only answer "unchanged" when the current call's arguments match a previous call's arguments exactly.

Context

I hit this while building a pi extension that does the same kind of de-duplication, and I switched the reference to the conversation for exactly this reason. Measurement scripts and the write-up are here, in case they are useful: https://github.com/Nyarlathoteppppp/pi-jev-context/blob/main/docs/FINDINGS.md#f20--deterministic-read-de-duplication-reference-the-context-not-the-disk

Happy to open a PR if you would like the fix in this shape.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions