# Your agent keeps guessing your conventions. Write the file it actually reads.

> Source: <https://dev.to/lixingliangsy/your-agent-keeps-guessing-your-conventions-write-the-file-it-actually-reads-167n>
> Published: 2026-09-26 00:06:23+00:00

Every team I have watched adopt Cursor, Claude Code or Codex hits the same wall in week two.

The agent writes plausible code that does not fit the repo. It invents a test command. It puts a

component in `src/components/` when everything else lives in `app/ui/`. It edits a file that is

generated.

The usual diagnosis is "the model is not smart enough." It usually is not that. The agent was never

told the rules — because nobody wrote them down.

There is a file for this. Cursor reads `.cursorrules`. Claude Code reads `CLAUDE.md`. Codex and most

harnesses read `AGENTS.md`. Copilot reads `.github/copilot-instructions.md`. If those files do not

exist, the agent improvises, and improvising means guessing.

So: write the file. The problem is that writing a good one takes 30–90 minutes per repo, and it rots

the moment you switch test runners.

[ContextForge](https://contextforge.lxsaihub.com) takes a snapshot of your repo — a file tree, plus

optionally one or two key files like `package.json` — and drafts those instruction files for you.

The interesting part is not that it calls a model. Everything calls a model. The interesting part is

**what runs before the model.**

Before any model is involved, a parser reads your tree and extracts facts:

`next.config.*`, `vite.config.*`, `angular.json`…)` vitest.config.*`, `jest.config.*`, `playwright.config.*`…)`.github/workflows/`, `.gitlab-ci.yml`, `Jenkinsfile`…)` pages/index.tsx` and `app/page.tsx` are both Next.js entry
points, but they are different routers, and a naive regex misses both`scripts` in your `package.json`
None of that needs a model. Which means none of it can fail because a model is down.

The model-assisted pass writes readable conventions from those facts. Its prompt forbids invention:

it may only restate what was supplied, and anything marked as a guess has to be written as a question.

Which brings me to the part I care about most.

This is the failure mode nobody warns you about. If your `AGENTS.md` confidently states a convention

your repo does not follow, the agent trusts the instruction **over the code**. An empty file makes the

agent cautious. A wrong file makes it confidently wrong.

So every fact carries a provenance tag:

`detected``"scripts.test": "vitest run"` is a fact.`inferred`
Here is a slice of real output:

```
## Project
- Languages: TypeScript
- Package manager: npm
- Framework: Next.js
- Test runner: Vitest
- CI: GitHub Actions

## Commands
npm run build
npm run lint
- Test command is undetermined
```

That last line is the product working correctly. It did not know, so it said so.

This is where most AI products quietly cheat, so here is the whole behaviour table:

| Situation | Response | 
|---|---|
| Fair-use quota exhausted | `429` — checked*before* the model call | 
| No API key configured | `503 AI_NOT_CONFIGURED` | 
| Upstream model call fails | `502 AI_UPSTREAM_FAILED` | 
| You explicitly asked for a demo | `200` +`demo: true` + "Demo mode — not live AI" | 
| Live success | `200` +`source: Model-assisted` | 
| Model unavailable, rule-based draft | `200` +`source: Rule-based` | 

The last two rows are the point. A rule-based draft is **never** labelled as AI output, and a failed

model call is **never** disguised as a successful one. If the tool cannot tell you something, it says

so rather than filling the gap with something plausible.

(While building this I actually caught myself violating the fourth row: an explicit demo request was

routing through the model, so an upstream outage turned a demo into a 502. A demo must always

succeed. Fixed.)

Every run returns a **Context Score** out of 100, built from what it could actually determine — build

command, test command, lint command, entry points, stack, directory conventions, forbidden paths.

A repo where it found everything scores 100. A repo where you pasted three files scores 40 and hands

you a list of what to fill in. The score is not a quality judgement about your project; it is a

statement about how much evidence the tool had.

The honest limitation I would want to know as a user: the fair-use quota is stored in serverless

memory, so it is per-instance rather than a true global limit. A hard global limit needs shared

storage (KV or Edge Config) and that is not shipped yet.

Paste the output of `git ls-files` into [ContextForge](https://contextforge.lxsaihub.com) and see what

it makes of your repo. The five example outputs are on

[GitHub](https://github.com/lixingliangsy/contextforge) if you want to judge the format before

handing over a tree.

And if the generated file says something your repo does not do — fix it, then re-run. That is the

whole workflow.
