Your agent keeps guessing your conventions. Write the file it actually reads. A developer built ContextForge, a tool that snapshots a repository's file tree and key files to draft agent instruction files such as .cursorrules, CLAUDE.md, AGENTS.md and .github/copilot-instructions.md. The tool runs a deterministic parser before any model call to extract facts like framework, test runner and CI configuration, then tags each statement with provenance (detected, inferred or unknown) so the agent is never given a confidently wrong convention. It returns a Context Score out of 100 and uses explicit HTTP status codes and source labels so rule-based drafts are never presented as AI output. 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.