{"slug": "my-project-docs-aren-t-for-humans-anymore-they-re-for-an-agent-that-re-reads", "title": "My Project Docs Aren't For Humans Anymore. They're For an Agent That Re-Reads Them Every Session.", "summary": "A developer discovered that their project documentation was being read primarily by an AI agent, not humans, leading to a bug when a stale fact in a summary file caused the agent to fail. The developer now writes documentation optimized for LLM consumption, using terse bullet points and separating current facts from historical decisions. The key lesson is that summary fact files act as caches that can go stale silently unless kept in sync with detailed records.", "body_md": "I used to write `docs/`\n\nthe way I was taught: prose paragraphs, a little context, a \"why we did this\" narrative you'd hand to a new hire. Then I noticed something. The only reader opening those files every single day wasn't a human. It was an agent, loading them fresh at the start of every session, with a token budget and zero memory of yesterday.\n\nThat changes what \"good documentation\" means, and I didn't actually update my writing style until a stale line in one of these files caused a real bug.\n\nIn my `my-git-manager`\n\nrepo, `CLAUDE.md`\n\npoints an agent at `docs/project_notes/`\n\non every session start:\n\n```\n## Project Memory System\n\nInstitutional knowledge lives in `docs/project_notes/`. Check before proposing changes.\n\n- **bugs.md** — known bugs and solutions\n- **decisions.md** — why things were built the way they were (ADRs)\n- **key_facts.md** — usernames, API endpoints, file purposes, run commands\n- **issues.md** — work log\n\n**Protocols:**\n- Encountering an error → search `bugs.md` first\n- Proposing an architecture change → check `decisions.md` for conflicts\n- Need a username/endpoint/command → check `key_facts.md`\n- Completing a phase of work → log it in `issues.md`\n```\n\nThat \"Protocols\" block isn't documentation about documentation. It's routing logic. It's the same shape as an `if/else`\n\n— \"on event X, read file Y\" — except the interpreter is an LLM instead of a runtime. I didn't design it that way on purpose at first; I just kept trimming prose paragraphs down until what was left looked like this.\n\nA human skims. They pick up \"roughly what this means\" from surrounding words even if a sentence is slightly out of date, because they're pattern-matching against a mental model they already have. An agent doesn't have that mental model. It takes what's on the page close to literally, weights it as fact, and acts on it — in the same turn, with no time to notice the prose \"feels off.\"\n\nI found this out the hard way. `key_facts.md`\n\nhad this line for weeks:\n\n```\n- Token scopes needed: `repo`, `user`\n```\n\nIt read fine. Nothing about it looked wrong to a human skimming it. But on 2026-06-23, a real OSS fork-and-PR task needed the `workflow`\n\nscope too (pushing a branch that touches `.github/workflows/*.yml`\n\nrequires it), and `bugs.md`\n\ngot an entry documenting the failure — but nobody went back and fixed the *summary* line in `key_facts.md`\n\nthat an agent actually reads at session start. Six weeks later, an agent trusted that stale line, tried a similar push, and hit the same 403 again. The fix existed in the codebase. It just wasn't in the file the agent was actually going to open.\n\n```\n- Token scopes needed: `repo`, `user` — add `delete_repo` if repo deletion via\n  API is required, add `workflow` if you'll ever push a branch that pulls in\n  upstream `.github/workflows/*.yml` changes (fork OSS contributions) —\n  see `bugs.md` 2026-06-23\n```\n\nThe lesson wasn't \"add a workflow scope.\" It was: a summary fact file is a cache, and caches go stale silently unless something forces them to stay in sync with the detailed record. A human would have said \"eh, probably still `repo, user`\n\n, let me just try it.\" An agent read `key_facts.md`\n\n, saw a confident bulleted fact, and acted on it as ground truth. There's no skepticism pass unless you build one in.\n\n**Terse beats narrative.** Every sentence I don't write is a sentence the agent doesn't have to hold in its context window before deciding what to do next. `key_facts.md`\n\nis a table and a bullet list, not paragraphs. If I catch myself writing \"this is because...\" I ask whether the *because* actually changes the agent's next action. If it doesn't, it's a comment for a future human reading the file in a browser, not something the agent needs — and I'll cut it or push it into `decisions.md`\n\nwhere it belongs.\n\n**Facts and rationale live in different files, on purpose.** `key_facts.md`\n\nis current-state-only: what's true right now, no history. `decisions.md`\n\nis append-only ADR entries: why something was built the way it was, including the paths not taken. `bugs.md`\n\nis incident-shaped: symptom, root cause, fix. I stopped trying to write one file that does all three, because an agent searching for \"why does X work this way\" and an agent searching for \"what's the current DEV.to username\" have completely different queries, and mixing them means both searches wade through irrelevant prose.\n\n**Every fact carries its own expiry trigger.** The `workflow`\n\nscope fix above now has `— see bugs.md 2026-06-23`\n\nattached directly to the fact, not just in a changelog somewhere. If it goes stale again, the next agent has a breadcrumb to the incident that produced it, one hop away, without me having to remember to update two files by hand.\n\n**The protocol block is the actual interface.** I stopped thinking of the \"when X, check Y\" list as a nicety at the top of the doc and started treating it as the load-bearing part. It's what turns four static markdown files into something closer to a lookup table the agent consults *before* acting instead of narrating context it happened to skim.\n\nI now ask one question before adding anything to `docs/project_notes/`\n\n: if an agent reads only this line, out of context, with no chance to ask a follow-up, does it have enough to act correctly? If the answer is \"well, it depends, you'd need to know that...\" — that dependency needs to be in the line itself, or the line is a liability waiting for the six-week gap between \"we fixed it\" and \"we told the file we fixed it.\"\n\nWriting for a reader that takes you completely literally and never gets to ask \"wait, is this still true?\" is a different discipline than writing for a colleague. It's closer to writing an API contract than a wiki page. I didn't expect that to be the actual shift \"AI-assisted development\" would force on my documentation habits, but it's the one that's caught real bugs so far.", "url": "https://wpnews.pro/news/my-project-docs-aren-t-for-humans-anymore-they-re-for-an-agent-that-re-reads", "canonical_source": "https://dev.to/enjoy_kumawat/my-project-docs-arent-for-humans-anymore-theyre-for-an-agent-that-re-reads-them-every-session-56a7", "published_at": "2026-07-15 03:35:48+00:00", "updated_at": "2026-07-15 03:56:52.682531+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models"], "entities": ["CLAUDE.md", "my-git-manager"], "alternates": {"html": "https://wpnews.pro/news/my-project-docs-aren-t-for-humans-anymore-they-re-for-an-agent-that-re-reads", "markdown": "https://wpnews.pro/news/my-project-docs-aren-t-for-humans-anymore-they-re-for-an-agent-that-re-reads.md", "text": "https://wpnews.pro/news/my-project-docs-aren-t-for-humans-anymore-they-re-for-an-agent-that-re-reads.txt", "jsonld": "https://wpnews.pro/news/my-project-docs-aren-t-for-humans-anymore-they-re-for-an-agent-that-re-reads.jsonld"}}