Skip to content

Build1 publisher3 min readPublished

A CLAUDE.md template replaces its style adjectives with four Avoid/Preferred code blocks

A dev.to template for CLAUDE.md and AGENTS.md swaps style adjectives for Avoid/Preferred code pairs that name the exact helper an agent should call, on the argument that a code shape is the only part a model can imitate.

The Engineer · Build desk

What happened

  • A dev.to post argues that most CLAUDE.md and AGENTS.md files are vague prose of the "write clean code" and "follow best practices" kind, and that agents duly ignore half of what they say.
  • Its template fixes six sections in order: metadata header, project context, coding conventions, testing requirements, a do-not-touch list, and a command reference.
  • The project context example spells out choices a model would otherwise guess, including raw SQL via pg with no ORM per ADR-014, pnpm workspaces, and iron-session sessions instead of JWTs.
  • The template caps coding conventions at three to five, on the grounds that a longer list turns into context rot.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint A three-to-five cap means the team has to rank its repeated corrections, and everything below the line stays a human review comment forever.
  • cost Naming helpers inside the Preferred blocks makes a rename a two-file change, and skipping the second file breaks nothing until an agent writes the call.
  • decision Teams now choose whether these files are advisory documentation or a spec they gate merges on, because the template itself leaves every check to CI.
  • precedent Putting an owner and a review date on agent context sets the expectation that such files get maintained like code, and that an unreviewed one can be treated as untrustworthy.

Start with the two catch blocks. The Avoid version is `catch (e) { console.log(e); }`. The Preferred version calls `logger.error('checkout.payment_failed', { orderId, cause: e })` and then throws `new PaymentError(orderId, e)` [3]. The post describes the second as giving the model an actual pattern to match against: a logger call with a namespaced event, structured metadata, and a typed error thrown upward [4]. It puts the general rule in one line: "That's the single biggest lever in this whole exercise: replace adjectives with code blocks." [5] The case against the prose version is that "vague prose doesn't change agent behavior any more than it changes a new hire's behavior on day one" [2].

For a Preferred block to produce code that compiles, the repo has to contain the names inside it. The conventions section shows four pairs: `successResponse` wrapping API responses, `asyncHandler` wrapping async route handlers, full words instead of `d` and `u` in naming, and an `OrdersRepository` passed as a default parameter so tests can substitute a fake [12]. Each block is an instruction to call one specific function. Rename that function without editing the file and the agent starts writing calls to something that is gone.

The writing cost is small, and the post states it: about 30 seconds per pair, against re-explaining the same point in code review indefinitely [13]. Four pairs is roughly two minutes of typing [14]. Keeping the file true costs more, which is what the front matter is for: `last_updated: 2026-09-14`, `owner: platform-team`, `review_cadence: quarterly` [7]. The post calls that header the difference between a file that rots silently and one that gets maintained, and says whoever finds an outdated rule knows exactly who to ping [8].

None of it is checked by a tool. The testing section says every new route handler needs an integration test in `tests/api/`, following the pattern in `tests/api/users.test.ts`, and that `pnpm test:unit` should run before any change is considered complete [15]. Whether that happened is settled by CI, not by the sentence. The do-not-touch list, which the post calls the fastest way to prevent a confidently wrong 200-line diff [16], works by asking, which is about the enforcement class of a DO NOT EDIT comment at the top of a generated file. The command reference is there so the agent is not guessing or hallucinating flags [17].

The post lays out the template and the reasoning behind each section without a before-and-after measurement of agent output [18]. The central claim rests on the author's experience. One supporting observation is cheap to test on your own repo: the post says any model trained broadly will default to reaching for an ORM the moment it touches a database [10]. For the template to transfer, a stack needs several constraints of that shape, where the model's default and the repo's choice reliably differ.

What to watch

  • A before-and-after comparison of agent diffs on one repo, with and without the Preferred/Avoid pairs, would show whether the code shape is what moves output.
  • Whether any agent harness starts parsing sections of these files as machine-checked rules instead of free-text prompt content.
  • Whether the template's own last_updated field moves off 2026-09-14 at the quarterly review it prescribes.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories