← writing
·3 min read

Shared instruction files are the env vars of AI agents

Last week I found 23,000 lines of TypeScript that no HTML page references. Eighty source files, a 398-line bash orchestrator, a JSON schema defining agent enums — all generated by an AI coding tool following instructions meant for a different AI coding tool.

I use Claude Code and Codex CLI. Claude Code is interactive — agent teams, skill routing, sub-agent spawning. Codex is headless — single-pass, no sub-agents, no team tools. Each should read its own config, the way staging and production read their own .env. Same keys where appropriate, different values where the systems diverge. You wouldn't point both environments at the same .env and add IF production, don't use the test database. You'd have two files.

I had one file. My CLAUDE.md told both tools: "Route every prompt through the agent-routing skill. Everything routes through the agent team." Claude Code can do this. Codex cannot. Codex's response was to build the infrastructure anyway — a multi-phase orchestration plan it cannot execute, a parallel agent spawner it cannot run. The instructions said to route through agents, so it tried. An env var pointing at the wrong database gives you a connection error. An instruction file pointing at wrong capabilities gives you 23,000 lines of dead code.

The same file said the stack was "TypeScript 5.x" and "NEVER: Edit js/*.js." The frontend is vanilla JS. Codex followed this literally — eighty TypeScript files, zero wired into the app. I tried fixing it with a conditional section explaining how Codex should "simulate the team in a single run." Now the file taught workarounds for missing capabilities. Two hours later, during an unrelated UI task, Codex deleted CLAUDE.md and .claude/settings.json entirely. Neither deletion appeared in the commit message.

The instinct after this is conditional sections — ## Interactive Only, ## Headless Only — carving lanes in a shared file. Writing "IF headless, don't do X" confesses that your system hands agents instructions they shouldn't have. It's if os.environ["ENV"] == "production": dont_use_test_db() — a runtime check for something that should never be possible.

Two files, no conditions. CLAUDE.md for Claude Code: "route prompts through agent-routing." AGENTS.md for Codex: "frontend is vanilla JS, no TypeScript files, max 15 files per commit." Shared rules — safety, code style, testing — sync via diff + rsync across parallel directories. The shared subset syncs. Capabilities diverge. Design, not drift.

Negative instructions — "don't edit X," "never call Y" — are a code smell for missing constraints. Use allowlists and capability gates to make the wrong action impossible. Don't rely on the agent reading a sentence and choosing to comply.

Instructions are for judgment. Constraints are for enforcement.

Env vars taught us to scope config per environment. Instruction files need the same discipline — scope per tool, or watch your agent build infrastructure it cannot use.