Agent Rules
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?Import names explicitly. Don't use
from module import *in code that agents edit. - AR-02 Do barrel files hide calls from coding agents?Re-export through an explicit list (
__all__, namedexport { }), notexport *chains. - AR-03 What happens when two functions share a name?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?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?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?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?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?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?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?No
eval/exec/Function()to call code. - AR-11 Why does my agent break calls that go through **kwargs?Avoid
**kwargs/...argspass-through layers that hide the real signature; spell the parameters or useParamSpec/Parameters<>. - AR-12 Do decorators hide function signatures from coding agents?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?Annotate public function parameters and returns. Use
Any/anyonly at a documented boundary. - AR-14 How should I type callbacks so agents can follow them?Type callback and handler parameters (
Callable[...], function types), notobject/Function. - AR-15 How do I make duck typing visible to type checkers?Use
Protocol/interfaces for duck-typed parameters. - AR-16 Why do dict-shaped objects make agents guess?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?Turn on strict type checking in the paths agents edit (pyright strict / mypy strict / tsconfig strict).
- AR-18 Why does monkeypatching break agent edits?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?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?No hidden global registries mutated from many modules; one module owns the registry.
- AR-21 Do metaclasses hide code from coding agents?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?Avoid
__getattr__(and JavaScriptProxy) forwarding on domain objects; expose explicit methods. - AR-23 How should generated code be handled for coding agents?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?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?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?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?Rename through the language server's rename, not text replace.
- AR-29 What should a coding agent run before finishing?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?Write down what you couldn't verify in the final message.
Frameworks
- AR-31 Why does my coding agent miss Django signal receivers?Connect Django signals with an explicit
sender, and keep the receivers in onesignals.pyper app, imported inAppConfig.ready(). - AR-32 Do string model references hide dependencies in Django?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?Declare dependencies as typed functions used through
Annotated[..., Depends(fn)], and write routes as decorated functions on anAPIRouter. Don't build routes in loops from strings. - AR-34 Why does my agent break pytest fixtures it can't see?Keep fixtures in the nearest
conftest.py, name them for what they return, and don't useautouseto change behaviour. - AR-35 Where should I patch in pytest?Patch the name the code under test looks up, through
monkeypatchormocker, on the module object. Don't reassign module globals in a test. - AR-36 Do higher-order components hide props from coding agents?In React, prefer hooks and explicit props over higher-order components that inject props.
- AR-37 Why does my agent miss dynamically imported components?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?Register Express routes and middleware explicitly in one router module. Don't
requireroute files by computed path. - AR-39 How do I make event emitters traceable for coding agents?Declare event names as a typed union or enum with typed payloads. Don't emit free strings with
anyarguments. - AR-40 How do DI containers hide calls from coding agents?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?Django
- CH-02 Why do my pytest tests pass for a reason I can't see?pytest
- CH-03 Why did my plugin registry lose a format after an edit?Python (__init_subclass__ registry)
- CH-04 Why does a React prop stop arriving after a rename?React (higher-order component, barrel)
For agents
All rules as data: /agent-readable/rules.json. New and changed pages: /agent-readable/feed.xml. A Markdown index of the whole site: /llms.txt.