<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pluto</title>
    <description>The latest articles on DEV Community by Pluto (@mars_peakul).</description>
    <link>https://dev.to/mars_peakul</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4181312%2F0ffae6e3-1922-4a01-b900-828b6ef353e9.jpg</url>
      <title>DEV Community: Pluto</title>
      <link>https://dev.to/mars_peakul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mars_peakul"/>
    <language>en</language>
    <item>
      <title>Stop asking AI to “write tests for this” — 5 prompt changes that make generated tests catch bugs</title>
      <dc:creator>Pluto</dc:creator>
      <pubDate>Wed, 14 Oct 2026 02:40:01 +0000</pubDate>
      <link>https://dev.to/mars_peakul/stop-asking-ai-to-write-tests-for-this-5-prompt-changes-that-make-generated-tests-catch-bugs-3n2n</link>
      <guid>https://dev.to/mars_peakul/stop-asking-ai-to-write-tests-for-this-5-prompt-changes-that-make-generated-tests-catch-bugs-3n2n</guid>
      <description>&lt;p&gt;AI coding tools can write a test file in seconds. Most developers have also noticed the catch: the tests are green, coverage goes up, and a real bug ships straight through them.&lt;/p&gt;

&lt;p&gt;That usually isn’t the model being bad at testing. It’s the prompt leaving out everything that makes a test valuable. Here are five changes I now make to every testing prompt — in Cursor, Claude Code, ChatGPT or Copilot Chat — and why each one matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Give it the intent, not just the code
&lt;/h2&gt;

&lt;p&gt;If the only input is the implementation, the implementation becomes the spec. The model reads what the code &lt;em&gt;does&lt;/em&gt; and asserts exactly that — including any bug.&lt;/p&gt;

&lt;p&gt;Add one or two sentences of intent, in your own words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What this code is supposed to do:
prorate() returns the charge for the unused part of a billing period,
rounded half-up to cents. It never returns a negative amount.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the model has something to test &lt;em&gt;against&lt;/em&gt;. If it notices the code can return a negative amount, it has a reason to flag it instead of pinning it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Ask for a plan before any code
&lt;/h2&gt;

&lt;p&gt;“Write tests” invites volume. Ask for a behaviour inventory and a case table first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before writing any code:
1. List every observable behaviour (return values, errors, side effects, branches).
   Mark anything that looks like a bug with [SUSPECT].
2. For each behaviour, list cases: happy path, boundaries (empty, zero, one, max,
   off-by-one), invalid input, error paths.
Show me both. Then write the tests.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A case table takes ten seconds to review. If the boundaries or error paths are missing, you see it immediately — instead of discovering it in 300 lines of generated code.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Attach one existing test file
&lt;/h2&gt;

&lt;p&gt;Describing your conventions (“we use Vitest, factories live in &lt;code&gt;tests/factories&lt;/code&gt;, we name tests like…”) works poorly. Showing them works well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conventions to copy: tests/billing/invoice.test.ts
Match its imports, helpers, file location and naming.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one line stops most of the “new assertion library, different folder, duplicate fixtures” problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Write the rules the model would otherwise break
&lt;/h2&gt;

&lt;p&gt;Models take the shortest path to green. State the boundaries explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rules:
- Do not change production code to make tests pass. If the code seems wrong, report it.
- Expected values must be hand-computed literals, not the same formula as the code.
- Only stub true boundaries: clock, randomness, network, third-party APIs.
- No fixed sleeps. Freeze time and seed randomness explicitly.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second rule alone removes a whole class of “mirror tests” — tests that agree with the implementation by construction and can never fail for the reason you care about.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Make it justify every test
&lt;/h2&gt;

&lt;p&gt;End with a self-check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For each test, state in one line the specific bug it would catch.
Delete any test whose answer is "none" or "same as another test".
List behaviours from the case table that still have no test.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then do the human version: break the code on purpose (flip a &lt;code&gt;&amp;lt;&lt;/code&gt; to &lt;code&gt;&amp;lt;=&lt;/code&gt;, return early) and see whether anything goes red. If nothing does, the tests are decoration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different jobs need different prompts
&lt;/h2&gt;

&lt;p&gt;The five changes above are the skeleton. The &lt;em&gt;process&lt;/em&gt; section should change with the job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integration/API tests:&lt;/strong&gt; rank scenarios by risk — contract, validation, auth (including another tenant’s resource), persistence, idempotency, downstream failure — and forbid mocking the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E2E:&lt;/strong&gt; separate checkpoints worth asserting from incidental UI, use role/label locators, and ask for an explicit flake review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legacy code:&lt;/strong&gt; write &lt;em&gt;characterization&lt;/em&gt; tests that pin current behaviour, bugs included, before you change anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flaky tests:&lt;/strong&gt; ask for ranked hypotheses with evidence and a reproduction step. Retries and longer sleeps are not fixes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coverage:&lt;/strong&gt; treat the percentage as one input to a risk-based plan, not the goal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The shape that works
&lt;/h2&gt;

&lt;p&gt;Every good testing prompt I use has the same five parts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Role&lt;/td&gt;
&lt;td&gt;“Senior engineer writing tests a skeptical reviewer will accept”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context&lt;/td&gt;
&lt;td&gt;Target, intent/spec, framework, one example test, what not to touch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process&lt;/td&gt;
&lt;td&gt;Numbered steps, plan before code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output contract&lt;/td&gt;
&lt;td&gt;Exact sections and tables to return&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rules&lt;/td&gt;
&lt;td&gt;The shortcuts the model must not take&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Try it on a function you know well. If the case table finds an edge case you hadn’t written down, it’s working.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I packaged the eight prompts I use for this — unit, spec-first, integration/API, E2E, characterization, flaky diagnosis, coverage planning and mock boundaries — plus two checklists, a Cursor rule and a PDF guide, as the **AI Test Generation Prompt Pack&lt;/em&gt;&lt;em&gt;: &lt;a href="https://lirenplr.gumroad.com/l/cuofwr" rel="noopener noreferrer"&gt;https://lirenplr.gumroad.com/l/cuofwr&lt;/a&gt;. Everything above works without it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Pluto · &lt;a href="https://x.com/Mars_Peakul" rel="noopener noreferrer"&gt;@Mars_Peakul&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stop asking AI to "review this PR" — use a risk map instead</title>
      <dc:creator>Pluto</dc:creator>
      <pubDate>Tue, 13 Oct 2026 14:03:00 +0000</pubDate>
      <link>https://dev.to/mars_peakul/stop-asking-ai-to-review-this-pr-use-a-risk-map-instead-26kl</link>
      <guid>https://dev.to/mars_peakul/stop-asking-ai-to-review-this-pr-use-a-risk-map-instead-26kl</guid>
      <description>&lt;p&gt;If you paste a pull request into ChatGPT, Claude, Cursor, or Copilot Chat and say “review this,” you usually get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a summary of what the diff already shows&lt;/li&gt;
&lt;li&gt;a handful of style opinions&lt;/li&gt;
&lt;li&gt;a generic reminder about “validating inputs”&lt;/li&gt;
&lt;li&gt;a friendly “looks good overall”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not a review. That is a book report.&lt;/p&gt;

&lt;p&gt;After enough of those, people either stop using AI for review or — worse — start treating the essay as approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually goes wrong
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No intent.&lt;/strong&gt; Without one sentence on &lt;em&gt;why&lt;/em&gt; the change exists, the model cannot tell a deliberate behaviour change from a bug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No priority.&lt;/strong&gt; Naming nits compete with authz bugs for the same paragraph budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No output contract.&lt;/strong&gt; Free-form prose hides severity. You want &lt;strong&gt;Must fix&lt;/strong&gt; / &lt;strong&gt;Should fix&lt;/strong&gt; / &lt;strong&gt;Nit&lt;/strong&gt;, locations, and a verdict.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Equal time for unequal risk.&lt;/strong&gt; Renames and payment-path changes should not get the same depth.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better default loop
&lt;/h2&gt;

&lt;p&gt;Use four steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Diff + intent&lt;/strong&gt; — skim &lt;code&gt;--stat&lt;/code&gt;, write one sentence of purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk map&lt;/strong&gt; — ask the model &lt;em&gt;only&lt;/em&gt; which areas deserve depth (auth, money, migrations, public API, supply chain, hot paths).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep dives&lt;/strong&gt; — new prompts (or new turns) on those areas: security, tests, API breaks, migrations, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human verdict&lt;/strong&gt; — dedupe, drop wrong nits, you own merge.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The important part is splitting &lt;strong&gt;map&lt;/strong&gt; from &lt;strong&gt;deep dive&lt;/strong&gt;. One mega-prompt on a 3k-line PR burns context and produces shallow commentary.&lt;/p&gt;

&lt;h2&gt;
  
  
  A skeleton that works across tools
&lt;/h2&gt;

&lt;p&gt;You can adapt this in Cursor, Claude Code, ChatGPT, or Copilot Chat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a senior engineer doing a pre-merge review. Do not edit files.

## Context
- Intent: &amp;lt;one sentence&amp;gt;
- Diffstat: &amp;lt;paste&amp;gt;
- Risk notes: &amp;lt;auth? migration? public API?&amp;gt;

## Process
1. Risk map (area → why → files)
2. Correctness vs intent
3. Security (authz, injection, secrets)
4. Tests (new behaviour covered? tests weakened?)
5. Only then maintainability that hides real risk

## Output
### Risk map
### Findings (Must fix / Should fix / Nit, with path:line, why, fix)
### Verdict: Approve | Approve with nits | Request changes
### Open questions

Do not invent issues. If nothing serious, say so.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the output contract. It is doing more work than the adjectives in the role line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specialist passes beat one giant checklist
&lt;/h2&gt;

&lt;p&gt;Once you have a risk map, fan out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trust boundary → security threat model + Pass/Fail evidence&lt;/li&gt;
&lt;li&gt;Behaviour change → behaviour↔test matrix (watch for deleted or loosened tests)&lt;/li&gt;
&lt;li&gt;Schema → expand/contract and lock risk&lt;/li&gt;
&lt;li&gt;Manifest/lockfile → necessity and install scripts, not only &lt;code&gt;audit&lt;/code&gt; noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You rarely need every pass. Two deep dives on the real risks beat eight shallow ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Team norms that keep this healthy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Human owns merge.&lt;/strong&gt; The model is a junior reviewer, not a gate bot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared severity words.&lt;/strong&gt; Must fix means blocks merge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read-only review chats.&lt;/strong&gt; Implement fixes in a separate turn so “findings” do not silently become a rewrite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authors can paste a risk map into the PR&lt;/strong&gt; to save reviewers’ discovery time — without requiring them to accept every nit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Privacy reminder
&lt;/h2&gt;

&lt;p&gt;If your company forbids pasting code into a given tool, these prompts do not override that. Use whatever surface policy allows (including self-hosted options).&lt;/p&gt;

&lt;h2&gt;
  
  
  Soft close
&lt;/h2&gt;

&lt;p&gt;I’ve been packaging this loop as a small set of copy-paste prompts and checklists (full PR, security, performance, tests, API, migrations, frontend a11y, dependencies) for people who already live in AI coding tools and just want reviews that surface real risk.&lt;/p&gt;

&lt;p&gt;If you try the risk-map-first skeleton above on your next non-trivial PR, watch whether the Must-fix list gets shorter and more serious. That feedback loop matters more than any tool brand.&lt;/p&gt;

&lt;p&gt;— Pluto · &lt;a href="https://x.com/Mars_Peakul" rel="noopener noreferrer"&gt;@Mars_Peakul&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codequality</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>One AGENTS.md to rule Claude Code, Cursor and Codex</title>
      <dc:creator>Pluto</dc:creator>
      <pubDate>Tue, 13 Oct 2026 06:48:38 +0000</pubDate>
      <link>https://dev.to/mars_peakul/one-agentsmd-to-rule-claude-code-cursor-and-codex-3jmi</link>
      <guid>https://dev.to/mars_peakul/one-agentsmd-to-rule-claude-code-cursor-and-codex-3jmi</guid>
      <description>&lt;p&gt;If you use more than one AI coding agent, you've probably ended up with three instruction files: a &lt;code&gt;CLAUDE.md&lt;/code&gt; for Claude Code, a pile of &lt;code&gt;.cursor/rules&lt;/code&gt; for Cursor, and an &lt;code&gt;AGENTS.md&lt;/code&gt; for Codex. They start out identical. A month later one still says &lt;code&gt;npm&lt;/code&gt;, another says &lt;code&gt;pnpm&lt;/code&gt;, and the third forgot that tests live next to the code.&lt;/p&gt;

&lt;p&gt;That's how instruction files drift apart. The fix is simple: &lt;strong&gt;make &lt;code&gt;AGENTS.md&lt;/code&gt; the single source of truth and keep every tool-specific file thin.&lt;/strong&gt; This post shows the layout, how each tool actually picks up &lt;code&gt;AGENTS.md&lt;/code&gt;, and a template you can copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The layout
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-repo/
├── AGENTS.md            # canonical: commands, layout, conventions, definition of done
├── CLAUDE.md            # "@AGENTS.md" + Claude-only notes
├── .claude/
│   ├── settings.json    # permissions + hooks
│   ├── agents/          # subagents
│   └── skills/          # procedures that load on demand
├── .cursor/
│   ├── rules/           # .mdc rules, with the core rule pointing at AGENTS.md
│   └── cli.json         # permissions for the `agent` CLI
├── .cursorignore
└── .codex/
    ├── config.toml      # sandbox + approval defaults
    └── agents/          # custom agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;AGENTS.md&lt;/code&gt; holds everything every agent needs. The other files hold only what is specific to one tool: its behaviour, permissions and features.&lt;/p&gt;

&lt;h2&gt;
  
  
  How each tool picks up AGENTS.md
&lt;/h2&gt;

&lt;p&gt;This is the part people get wrong, because the three tools load it differently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codex&lt;/strong&gt; builds an instruction chain once per run. It starts with the global file (&lt;code&gt;~/.codex/AGENTS.override.md&lt;/code&gt; or &lt;code&gt;AGENTS.md&lt;/code&gt;), then walks every directory from the project root down to your working directory. In each one it checks &lt;code&gt;AGENTS.override.md&lt;/code&gt;, then &lt;code&gt;AGENTS.md&lt;/code&gt;, then any &lt;code&gt;project_doc_fallback_filenames&lt;/code&gt;, and takes at most one file per directory. Files closer to your working directory come later, so they win when instructions conflict. The combined chain has a default size cap of 32 KiB, and Codex stops adding files once it reaches it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor&lt;/strong&gt; supports &lt;code&gt;AGENTS.md&lt;/code&gt; in the root and in subdirectories. Nested files combine with their parents, and the more specific instructions take precedence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; has the catch. It reads &lt;code&gt;AGENTS.md&lt;/code&gt; directly &lt;strong&gt;only when there's no &lt;code&gt;CLAUDE.md&lt;/code&gt; or &lt;code&gt;CLAUDE.local.md&lt;/code&gt;&lt;/strong&gt; in the working directory or above. Once you add a &lt;code&gt;CLAUDE.md&lt;/code&gt;, put an import at the top so both load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# CLAUDE.md&lt;/span&gt;
@AGENTS.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A personal, uncommitted &lt;code&gt;CLAUDE.local.md&lt;/code&gt; also counts as "a CLAUDE.md exists". So even if you never create a project &lt;code&gt;CLAUDE.md&lt;/code&gt;, adding a local one silently stops Claude reading &lt;code&gt;AGENTS.md&lt;/code&gt;. Keep the explicit &lt;code&gt;@AGENTS.md&lt;/code&gt; import and that can't happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The canonical AGENTS.md
&lt;/h2&gt;

&lt;p&gt;Here's a trimmed version of the template I use. Replace the placeholders with your own stack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# AGENTS.md&lt;/span&gt;

&lt;span class="gu"&gt;## Project snapshot&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; What it is: &lt;span class="nt"&gt;&amp;lt;one&lt;/span&gt; &lt;span class="na"&gt;sentence&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Main language / runtime: &lt;span class="nt"&gt;&amp;lt;TypeScript&lt;/span&gt; &lt;span class="err"&gt;5,&lt;/span&gt; &lt;span class="na"&gt;Node&lt;/span&gt; &lt;span class="err"&gt;22&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Package manager: &lt;span class="nt"&gt;&amp;lt;pnpm&amp;gt;&lt;/span&gt;. Do not use any other package manager.
&lt;span class="p"&gt;-&lt;/span&gt; Layout:
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`apps/web/`&lt;/span&gt;: frontend
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`apps/api/`&lt;/span&gt;: HTTP API (handlers in &lt;span class="sb"&gt;`apps/api/src/handlers/`&lt;/span&gt;)
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`packages/db/`&lt;/span&gt;: schema + migrations

&lt;span class="gu"&gt;## Commands&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Install: &lt;span class="sb"&gt;`&amp;lt;pnpm install&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Unit tests (fast, run often): &lt;span class="sb"&gt;`&amp;lt;pnpm test&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Single test file: &lt;span class="sb"&gt;`&amp;lt;pnpm test -- path/to/file.test.ts&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Lint + types: &lt;span class="sb"&gt;`&amp;lt;pnpm lint &amp;amp;&amp;amp; pnpm typecheck&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Build: &lt;span class="sb"&gt;`&amp;lt;pnpm build&amp;gt;`&lt;/span&gt;

&lt;span class="gu"&gt;## Conventions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Named exports, no default exports.
&lt;span class="p"&gt;-&lt;/span&gt; Errors: return &lt;span class="sb"&gt;`{ code, message }`&lt;/span&gt; objects from services; never throw raw strings.
&lt;span class="p"&gt;-&lt;/span&gt; New code needs tests next to it (&lt;span class="sb"&gt;`*.test.ts`&lt;/span&gt;).

&lt;span class="gu"&gt;## Working agreement&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; Restate the task in one or two lines and list the files you expect to touch before editing.
&lt;span class="p"&gt;2.&lt;/span&gt; Make the smallest change that solves the task. No drive-by refactors.
&lt;span class="p"&gt;3.&lt;/span&gt; If requirements are ambiguous, stop and ask. Do not guess on behaviour.
&lt;span class="p"&gt;4.&lt;/span&gt; Never commit secrets, tokens, or &lt;span class="sb"&gt;`.env*`&lt;/span&gt; files.
&lt;span class="p"&gt;5.&lt;/span&gt; Do not run &lt;span class="sb"&gt;`git push`&lt;/span&gt;, &lt;span class="sb"&gt;`git reset --hard`&lt;/span&gt;, &lt;span class="sb"&gt;`git clean -fd`&lt;/span&gt;, force-pushes,
   or destructive DB commands unless explicitly asked.

&lt;span class="gu"&gt;## Definition of done&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Lint + types pass
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Tests pass (and a new test covers the change)
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Diff is limited to files related to the task
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Short summary: what changed, why, how it was verified, open risks

&lt;span class="gu"&gt;## Code Review Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Flag any handler that reads request input without validation.
&lt;span class="p"&gt;-&lt;/span&gt; Flag SQL built with string concatenation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why it's built this way
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Commands come first&lt;/strong&gt; because wrong commands cause most wasted agent turns: &lt;code&gt;npm&lt;/code&gt; instead of &lt;code&gt;pnpm&lt;/code&gt;, or the wrong test runner. The single-file test command also saves tokens, since the agent stops running the whole suite on every iteration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The working agreement&lt;/strong&gt; turns common failure modes, like silent scope creep and guessing, into explicit rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The definition of done&lt;/strong&gt; gives every agent the same exit criteria. Without it you get "Done!" while the tests still fail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;## Code Review Rules&lt;/code&gt;&lt;/strong&gt; is a heading Codex's GitHub code review looks for, so the review guidance comes along for free.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep it short. Leave formatting checks to CI, not the rule file. And write instructions the agent can verify: "Run &lt;code&gt;pnpm test&lt;/code&gt; before finishing" works better than "test your changes".&lt;/p&gt;

&lt;h2&gt;
  
  
  The thin files
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CLAUDE.md
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# CLAUDE.md: project instructions for Claude Code&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Keep this file under ~200 lines. HTML comments are stripped before Claude sees them. --&amp;gt;&lt;/span&gt;

@AGENTS.md

&lt;span class="gu"&gt;## Claude Code specifics&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use plan mode before touching more than 3 files.
&lt;span class="p"&gt;-&lt;/span&gt; For searches that would flood the context, delegate to a subagent
  and ask for a summary with file paths.
&lt;span class="p"&gt;-&lt;/span&gt; Before calling a task done, run the checks in "Definition of done"
  and paste the command output summary.

&lt;span class="gu"&gt;## Things that went wrong before&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Do not "fix" failing tests by loosening assertions or adding &lt;span class="sb"&gt;`.skip`&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details: imports are relative to &lt;code&gt;CLAUDE.md&lt;/code&gt; and can nest up to four hops. Block-level HTML comments are stripped before injection, so notes for humans cost no context. Run &lt;code&gt;/context&lt;/code&gt; to confirm which memory files actually loaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  .cursor/rules/00-core.mdc
&lt;/h3&gt;

&lt;p&gt;Cursor project rules must be &lt;code&gt;.mdc&lt;/code&gt; files in &lt;code&gt;.cursor/rules/&lt;/code&gt;. A plain &lt;code&gt;.md&lt;/code&gt; file there is ignored. The always-on core rule just points to AGENTS.md and adds a few hard limits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Core&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;working&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agreement&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;every&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;chat&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;this&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;repo"&lt;/span&gt;
&lt;span class="na"&gt;alwaysApply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;-&lt;/span&gt; Follow &lt;span class="sb"&gt;`AGENTS.md`&lt;/span&gt; at the repo root for commands, layout and definition of done.
&lt;span class="p"&gt;-&lt;/span&gt; Before editing, list the files you plan to change. Keep the diff limited to the task.
&lt;span class="p"&gt;-&lt;/span&gt; Never read, print, or edit &lt;span class="sb"&gt;`.env*`&lt;/span&gt;, &lt;span class="sb"&gt;`*.pem`&lt;/span&gt;, &lt;span class="sb"&gt;`*.key`&lt;/span&gt; or credential files.
&lt;span class="p"&gt;-&lt;/span&gt; Finish every task with: what changed, how you verified it (exact commands), open risks.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stack-specific rules go in separate &lt;code&gt;.mdc&lt;/code&gt; files that attach by &lt;code&gt;globs&lt;/code&gt;, so they only cost tokens when a matching file is in context.&lt;/p&gt;

&lt;h3&gt;
  
  
  .codex/config.toml
&lt;/h3&gt;

&lt;p&gt;Codex instructions come from &lt;code&gt;AGENTS.md&lt;/code&gt;. &lt;strong&gt;Behaviour&lt;/strong&gt; (sandbox, approvals, subagents) lives in &lt;code&gt;config.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;approval_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"on-request"&lt;/span&gt;
&lt;span class="py"&gt;sandbox_mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"workspace-write"&lt;/span&gt;
&lt;span class="py"&gt;web_search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cached"&lt;/span&gt;

&lt;span class="nn"&gt;[agents]&lt;/span&gt;
&lt;span class="py"&gt;max_concurrent_threads_per_session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Codex loads a project's &lt;code&gt;.codex/&lt;/code&gt; layers only when you trust the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the agent "ignores" the rules
&lt;/h2&gt;

&lt;p&gt;If an agent ignores your conventions, the cause is almost always that the rule file is too long, vague or contradictory, or wasn't loaded at all. Check before rewriting anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code: &lt;code&gt;/context&lt;/code&gt; and &lt;code&gt;/memory&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Codex: &lt;code&gt;/status&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cursor: Customize → Rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then shorten the file, make the instructions verifiable, and remove conflicts. One canonical file makes that much easier, because there's only one place to fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AGENTS.md&lt;/code&gt; is canonical. &lt;code&gt;CLAUDE.md&lt;/code&gt; and &lt;code&gt;.cursor/rules&lt;/code&gt; stay thin and point to it.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;CLAUDE.md&lt;/code&gt;, always add an explicit &lt;code&gt;@AGENTS.md&lt;/code&gt; import.&lt;/li&gt;
&lt;li&gt;Put commands first, use verifiable instructions, and give every agent the same definition of done.&lt;/li&gt;
&lt;li&gt;Keep tool behaviour (permissions, sandbox, hooks) in each tool's own config, not in the instructions.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Free excerpt: &lt;a href="https://lirenplr.gumroad.com/l/zocmzn" rel="noopener noreferrer"&gt;https://lirenplr.gumroad.com/l/zocmzn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is adapted from the **AI Coding Agent Workflow Pack&lt;/em&gt;&lt;em&gt;: a 37-page guide plus a drop-in template bundle (the full AGENTS.md, CLAUDE.md, all four Cursor rule types, Codex config, 10 copy-paste workflows and a security checklist). Every file name and flag was checked against the official docs in October 2026. &lt;a href="https://lirenplr.gumroad.com/l/xymroh" rel="noopener noreferrer"&gt;Get it on Gumroad ($24)&lt;/a&gt;. I post tested agent workflows as &lt;a href="https://x.com/Mars_Peakul" rel="noopener noreferrer"&gt;@Mars_Peakul&lt;/a&gt; on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
