# Agent Rules: writing code coding agents can follow

> Each page answers one question about code that coding agents edit. It gives the rule in one sentence, why agents fail without it, a bad and a good example, and how to enforce it. Each page has a Markdown copy.

## Rules

### Names and imports

- [AR-01: Why do star imports make my coding agent miss callers?](https://beta.llmgraph.in/agent-readable/ar-01.md): Import names explicitly. Don't use from module import * in code that agents edit.
- [AR-02: Do barrel files hide calls from coding agents?](https://beta.llmgraph.in/agent-readable/ar-02.md): Re-export through an explicit list (__all__, named export { }), not export * chains.
- [AR-03: What happens when two functions share a name?](https://beta.llmgraph.in/agent-readable/ar-03.md): One public name, one definition: don't define the same function name in two modules a file can import together.
- [AR-04: Do import aliases confuse coding agents?](https://beta.llmgraph.in/agent-readable/ar-04.md): Alias imports only to resolve a real clash, and never alias a module to a one-letter name in shared code.
- [AR-05: Why do fallback imports make agents edit the wrong code?](https://beta.llmgraph.in/agent-readable/ar-05.md): No conditional imports that bind the same name to different objects (try/except ImportError fallbacks get a typed shim).
- [AR-06: Why does my agent not see what importing this module does?](https://beta.llmgraph.in/agent-readable/ar-06.md): Keep import side effects out of modules; registration happens in an explicit setup call.

### Dispatch and reflection

- [AR-07: Why does my coding agent miss calls made through getattr?](https://beta.llmgraph.in/agent-readable/ar-07.md): Don't build method names as strings (getattr(obj, f\"handle_{x}\"), obj[name]()).
- [AR-08: How do I write dispatch that type checkers can follow?](https://beta.llmgraph.in/agent-readable/ar-08.md): Dispatch over a closed set with a typed mapping keyed by a literal type, or an explicit match.
- [AR-09: How should plugin registries be written for coding agents?](https://beta.llmgraph.in/agent-readable/ar-09.md): For open sets (plugins), register explicitly into a typed registry next to a typed contract.
- [AR-10: Why can't any tool see calls made through eval?](https://beta.llmgraph.in/agent-readable/ar-10.md): No eval/exec/Function() to call code.
- [AR-11: Why does my agent break calls that go through **kwargs?](https://beta.llmgraph.in/agent-readable/ar-11.md): Avoid **kwargs/...args pass-through layers that hide the real signature; spell the parameters or use ParamSpec/Parameters<>.
- [AR-12: Do decorators hide function signatures from coding agents?](https://beta.llmgraph.in/agent-readable/ar-12.md): Use functools.wraps / preserve signatures in decorators; don't let decorators replace a function with a different shape.

### Types and contracts

- [AR-13: Why is Any a blind spot for coding agents?](https://beta.llmgraph.in/agent-readable/ar-13.md): Annotate public function parameters and returns. Use Any/any only at a documented boundary.
- [AR-14: How should I type callbacks so agents can follow them?](https://beta.llmgraph.in/agent-readable/ar-14.md): Type callback and handler parameters (Callable[...], function types), not object/Function.
- [AR-15: How do I make duck typing visible to type checkers?](https://beta.llmgraph.in/agent-readable/ar-15.md): Use Protocol/interfaces for duck-typed parameters.
- [AR-16: Why do dict-shaped objects make agents guess?](https://beta.llmgraph.in/agent-readable/ar-16.md): Prefer dataclasses/TypedDict/interfaces over free-form dicts for structured data passed between modules.
- [AR-17: Which type checker settings make code easier for agents?](https://beta.llmgraph.in/agent-readable/ar-17.md): Turn on strict type checking in the paths agents edit (pyright strict / mypy strict / tsconfig strict).
- [AR-18: Why does monkeypatching break agent edits?](https://beta.llmgraph.in/agent-readable/ar-18.md): No monkeypatching in production code. In tests, patch through the fixture/mock API at the import site.

### Structure and state

- [AR-19: Why does reassigning methods hide callers from agents?](https://beta.llmgraph.in/agent-readable/ar-19.md): Keep a function's callers findable: don't assign functions onto objects at runtime (obj.method = other).
- [AR-20: Where should a registry live so coding agents can find it?](https://beta.llmgraph.in/agent-readable/ar-20.md): No hidden global registries mutated from many modules; one module owns the registry.
- [AR-21: Do metaclasses hide code from coding agents?](https://beta.llmgraph.in/agent-readable/ar-21.md): Keep metaclass and __init_subclass__ generation out of edit paths; when you use it, document what it generates.
- [AR-22: Why do __getattr__ proxies confuse coding agents?](https://beta.llmgraph.in/agent-readable/ar-22.md): Avoid __getattr__ (and JavaScript Proxy) forwarding on domain objects; expose explicit methods.
- [AR-23: How should generated code be handled for coding agents?](https://beta.llmgraph.in/agent-readable/ar-23.md): Generated code is committed, or its generator is in the repo with the command to run it. Mark it, and tell agents to edit the source.

### Agent workflow

- [AR-25: What to check before changing a function signature?](https://beta.llmgraph.in/agent-readable/ar-25.md): Before changing a signature, list every caller and the dynamic sites that might reach it.
- [AR-26: How does an agent know an edit is finished?](https://beta.llmgraph.in/agent-readable/ar-26.md): After an edit, re-check the callers of every changed function before declaring the task done.
- [AR-27: Is a list of callers ever the full list?](https://beta.llmgraph.in/agent-readable/ar-27.md): Treat \"callers found\" as the full list only when the tool says the list is full.
- [AR-28: Why is find-and-replace a bad rename for coding agents?](https://beta.llmgraph.in/agent-readable/ar-28.md): Rename through the language server's rename, not text replace.
- [AR-29: What should a coding agent run before finishing?](https://beta.llmgraph.in/agent-readable/ar-29.md): Run the type checker and the affected tests before saying \"done\".
- [AR-30: What should an agent report when it can't verify an edit?](https://beta.llmgraph.in/agent-readable/ar-30.md): Write down what you couldn't verify in the final message.

### Frameworks

- [AR-31: Why does my coding agent miss Django signal receivers?](https://beta.llmgraph.in/agent-readable/ar-31.md): Connect Django signals with an explicit sender, and keep the receivers in one signals.py per app, imported in AppConfig.ready().
- [AR-32: Do string model references hide dependencies in Django?](https://beta.llmgraph.in/agent-readable/ar-32.md): Import models directly when no import cycle forces a string. When a string is needed, use the absolute form \"app_label.ModelName\" and say why.
- [AR-33: How do I keep FastAPI routes visible to coding agents?](https://beta.llmgraph.in/agent-readable/ar-33.md): Declare dependencies as typed functions used through Annotated[..., Depends(fn)], and write routes as decorated functions on an APIRouter. Don't build routes in loops from strings.
- [AR-34: Why does my agent break pytest fixtures it can't see?](https://beta.llmgraph.in/agent-readable/ar-34.md): Keep fixtures in the nearest conftest.py, name them for what they return, and don't use autouse to change behaviour.
- [AR-35: Where should I patch in pytest?](https://beta.llmgraph.in/agent-readable/ar-35.md): Patch the name the code under test looks up, through monkeypatch or mocker, on the module object. Don't reassign module globals in a test.
- [AR-36: Do higher-order components hide props from coding agents?](https://beta.llmgraph.in/agent-readable/ar-36.md): In React, prefer hooks and explicit props over higher-order components that inject props.
- [AR-37: Why does my agent miss dynamically imported components?](https://beta.llmgraph.in/agent-readable/ar-37.md): In React and Next.js, don't call import() with a computed path for components agents edit.
- [AR-38: How should Express routes be organised for coding agents?](https://beta.llmgraph.in/agent-readable/ar-38.md): Register Express routes and middleware explicitly in one router module. Don't require route files by computed path.
- [AR-39: How do I make event emitters traceable for coding agents?](https://beta.llmgraph.in/agent-readable/ar-39.md): Declare event names as a typed union or enum with typed payloads. Don't emit free strings with any arguments.
- [AR-40: How do DI containers hide calls from coding agents?](https://beta.llmgraph.in/agent-readable/ar-40.md): Bind interfaces to implementations in one container module, using typed tokens and constructor injection.

## Chimeras

- [CH-01: Why does my Django signal break after a refactor?](https://beta.llmgraph.in/agent-readable/ch-01.md): Django
- [CH-02: Why do my pytest tests pass for a reason I can't see?](https://beta.llmgraph.in/agent-readable/ch-02.md): pytest
- [CH-03: Why did my plugin registry lose a format after an edit?](https://beta.llmgraph.in/agent-readable/ch-03.md): Python (__init_subclass__ registry)
- [CH-04: Why does a React prop stop arriving after a rename?](https://beta.llmgraph.in/agent-readable/ch-04.md): React (higher-order component, barrel)

## For agents

- [All rules as JSON](https://beta.llmgraph.in/agent-readable/rules.json)
- [RSS feed](https://beta.llmgraph.in/agent-readable/feed.xml)
- [llms.txt](https://beta.llmgraph.in/llms.txt)
