For AI agentsA Markdown index of these docs is at /llms.txt. Every page is also Markdown: add .md to its address.

Guides

When your agent says "done" but the code is broken

Why coding agents call broken code finished, and how to check their work: type checks, tests, a Stop hook, and callers an edit missed.

A coding agent can end a turn when the code looks finished, not when it is proven to work. Check the work in three steps: run the type checker and tests, gate the turn with a Stop hook, and list the callers the edit missed.

Why it happens

When you ask an agent to change a function, say adding a required parameter, it has to answer one question before it's finished: who else calls this? An agent can answer it the cheapest way it has: a text search for the name.

A text search has three blind spots:

  1. It finds names, not calls. If two functions share a name, the search returns both, mixed together. The agent has to guess which lines matter.
  2. It misses calls that don't spell the name. A function passed around as a value, stored in a dictionary, or called through an alias doesn't show up as name(.
  3. It doesn't tell the agent when to stop. Nothing in the result says "that's all of them". The agent fixes what it saw and moves on.

Then the agent says "done", because from where it stands, it is.

What it looks like

Here's a real case on the open-source library requests (v2.32.3). An agent was asked to change super_len(o) to super_len(o, strict) and not to touch any other file. When it tried to finish, a stop check printed this (middle lines trimmed, marked with dots):

LLMGRAPH: 8 calls break because of your edits: src/requests/models.py:526 PreparedRequest.prepare_body: misses "strict" src/requests/models.py:575 PreparedRequest.prepare_content_length: misses "strict" tests/test_utils.py:62 TestSuperLen.test_io_streams: misses "strict" ... Fix them, or tell the user why each is fine.

Of the eight calls it listed, two were in the library itself and six were in tests. Without a check, the edit would have left them for you to discover.

Check the work in three steps

1. Run the type checker and the tests. In typed Python or TypeScript, a missing argument is a type error. A checker catches it in files the agent never opened, as long as the call's types are known. Tests catch broken callers that are tested; they don't catch untested ones, and they only help if the agent runs them before it stops.

2. Gate the turn with a Stop hook. Agents don't always use the tools you give them. A hook that runs when the agent tries to finish can hold it until the problem is fixed or explained. How to write a Stop hook for Claude Code.

3. List the callers the edit missed. Before changing a signature, ask the agent to list every caller and how it found each one: you'll see what it searched for, which tells you what it might have missed. After the edit, ask again and compare. That is the question check_my_changes answers.

Where LLMGRAPH fits

LLMGRAPH is a local tool that answers your agent's questions about your own code: who calls this, what breaks if it changes, and which callers an edit missed. Every answer line is labelled by how far it's proven (certain, exactly_these, within_these, maybe_more, cannot_see), and what it can't see is named, not dropped. Each label is explained in the glossary.

Its Claude Code plugin adds the stop check from the example above. When the agent ends a turn after editing, it holds the agent once if calls are certain to break, names them by file and line, and says how many more aren't confirmed yet. It never blocks on anything weaker, and you can switch it off. The details are on the stop check.

It does not replace your tests or your type checker. It adds an answer they cannot always give: which callers did this edit miss, and how sure is that?

See real answers, unedited · Windows x64; Python and TypeScript/JavaScript.

For agentsthis page as Markdown/guides/agent-says-done-but-code-is-broken.mdllms.txt