<?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: Adrian Studio</title>
    <description>The latest articles on DEV Community by Adrian Studio (@adrianstudio).</description>
    <link>https://dev.to/adrianstudio</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%2F4181100%2Ff05bdfa8-fd46-4ba6-8ea9-df2b37f1c0e7.png</url>
      <title>DEV Community: Adrian Studio</title>
      <link>https://dev.to/adrianstudio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adrianstudio"/>
    <language>en</language>
    <item>
      <title>15 Ways AI Coding Agents Fail in Real Repos (and the Guardrails That Fix Them)</title>
      <dc:creator>Adrian Studio</dc:creator>
      <pubDate>Tue, 13 Oct 2026 05:37:38 +0000</pubDate>
      <link>https://dev.to/adrianstudio/15-ways-ai-coding-agents-fail-in-real-repos-and-the-guardrails-that-fix-them-3316</link>
      <guid>https://dev.to/adrianstudio/15-ways-ai-coding-agents-fail-in-real-repos-and-the-guardrails-that-fix-them-3316</guid>
      <description>&lt;p&gt;Around week three of using coding agents, most teams hit the same wall. The agent is clearly &lt;em&gt;busy&lt;/em&gt;: long transcripts, dozens of edited files, confident summaries. But ask "what shipped, and is it correct?" and the answer gets fuzzy.&lt;/p&gt;

&lt;p&gt;After running Claude Code, Codex CLI and Gemini CLI side by side on real projects, I've seen the same 15 failures over and over. Almost none of them are model-quality problems. They are operations problems, and each one has a boring, file-based fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four root causes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Root cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Done", but nothing works end to end&lt;/td&gt;
&lt;td&gt;No definition of done that requires evidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Each tool behaves differently on the same repo&lt;/td&gt;
&lt;td&gt;Instructions duplicated and drifting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You're afraid to let it run, so you babysit&lt;/td&gt;
&lt;td&gt;Permissions designed in the prompt instead of in config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;It re-learns the same facts every session&lt;/td&gt;
&lt;td&gt;No durable memory, or memory that only grows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here are the 15 failures, grouped by cause.&lt;/p&gt;




&lt;h2&gt;
  
  
  A. Evidence failures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. "Done", but the feature is broken
&lt;/h3&gt;

&lt;p&gt;Agents narrate intent as outcome: "I've updated the handler to retry." Fix it by putting a definition of done in your &lt;code&gt;AGENTS.md&lt;/code&gt; that requires &lt;em&gt;evidence&lt;/em&gt;:&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="gu"&gt;## Definition of done&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; The behaviour exists AND you ran something that demonstrates it.
&lt;span class="p"&gt;2.&lt;/span&gt; Tests covering the change pass; none deleted, skipped or weakened.
&lt;span class="p"&gt;3.&lt;/span&gt; Lint and type check pass.
&lt;span class="p"&gt;4.&lt;/span&gt; Final message lists: files changed, commands run WITH results,
   what you could not verify, decisions you made without being asked.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test for a report: could a stranger reproduce the claim? "Tests pass" fails. "&lt;code&gt;make test T=billing&lt;/code&gt; → 42 passed in 6.1s" passes.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The agent deleted the failing test
&lt;/h3&gt;

&lt;p&gt;This is what an unbounded retry loop does. Cap it: &lt;strong&gt;three attempts, then stop and report what was tried.&lt;/strong&gt; Have a reviewer check specifically for removed or skipped tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Lots of activity, flat output
&lt;/h3&gt;

&lt;p&gt;If the agent is busy but accepted changes aren't going up, the tasks are too big and have no acceptance check. Every delegated task gets one line before any code is written:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Acceptance check:&lt;/strong&gt; &lt;code&gt;test_duplicate_returns_409&lt;/code&gt; passes and &lt;code&gt;make lint&lt;/code&gt; is clean.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you can't write that line, the task isn't ready to delegate.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Scope creep: "while I was here, I also..."
&lt;/h3&gt;

&lt;p&gt;Add an explicit &lt;strong&gt;Out:&lt;/strong&gt; list to every task brief, and have the reviewer flag any file changed outside &lt;strong&gt;In:&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  B. Drift failures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5. Different behaviour per tool
&lt;/h3&gt;

&lt;p&gt;You have &lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;GEMINI.md&lt;/code&gt; and &lt;code&gt;AGENTS.md&lt;/code&gt;, each slightly different. Keep &lt;strong&gt;one&lt;/strong&gt; contract and make the others thin adapters:&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;span class="gu"&gt;## Claude-specific&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use the reviewer subagent before declaring multi-file changes done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Gemini CLI, load the contract directly in &lt;code&gt;.gemini/settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"fileName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"AGENTS.md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GEMINI.md"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Codex reads &lt;code&gt;AGENTS.md&lt;/code&gt; natively. Then add a two-line CI check so drift fails the build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"AGENTS.md"&lt;/span&gt; CLAUDE.md GEMINI.md &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"adapter lost its pointer"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; CLAUDE.md&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-le&lt;/span&gt; 40 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"move rules to AGENTS.md"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. The contract gets ignored
&lt;/h3&gt;

&lt;p&gt;Usually because it's 400 lines of vague prose. Keep it to 80-150 lines and make every rule &lt;em&gt;checkable&lt;/em&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Weak&lt;/th&gt;
&lt;th&gt;Strong&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Write good tests."&lt;/td&gt;
&lt;td&gt;"Every bug fix adds a test that fails before the fix."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Be careful with the DB."&lt;/td&gt;
&lt;td&gt;"Never run migrations against anything but localhost."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Keep code clean."&lt;/td&gt;
&lt;td&gt;"&lt;code&gt;src/domain/**&lt;/code&gt; must not import &lt;code&gt;src/web/**&lt;/code&gt;; &lt;code&gt;make lint&lt;/code&gt; enforces it."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If a linter can enforce a rule, configure the linter and delete the sentence.&lt;/p&gt;




&lt;h2&gt;
  
  
  C. Permission failures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7. "I set it to never ask, and the overnight job did nothing"
&lt;/h3&gt;

&lt;p&gt;Sandbox and approval are &lt;strong&gt;two different dials&lt;/strong&gt;. The sandbox is the &lt;em&gt;boundary&lt;/em&gt; (files, network). The approval policy is the &lt;em&gt;procedure&lt;/em&gt; when an action would cross it. In Codex:&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;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="c"&gt;# read-only | workspace-write | danger-full-access&lt;/span&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="c"&gt;# on-request (interactive) | never (batch)&lt;/span&gt;

&lt;span class="nn"&gt;[sandbox_workspace_write]&lt;/span&gt;
&lt;span class="py"&gt;network_access&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;never&lt;/code&gt; doesn't widen the boundary. It makes boundary-crossing actions &lt;em&gt;fail&lt;/em&gt; instead of waiting. That's correct for batch runs, and it's exactly why the job "did nothing". Read the failure log and widen the sandbox for that one profile only.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. The agent bypassed a block through another tool
&lt;/h3&gt;

&lt;p&gt;You denied &lt;code&gt;git push&lt;/code&gt;, so it tried &lt;code&gt;curl&lt;/code&gt; against the API. Deny the &lt;em&gt;capability&lt;/em&gt; (network, a path), not just one command name. A blocked action should be reported, never retried another way.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Secrets ended up in a transcript
&lt;/h3&gt;

&lt;p&gt;The agent could read &lt;code&gt;.env&lt;/code&gt;. In Claude Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Read(./.env)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Read(./.env.*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Read(./secrets/**)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inject a credential into one command's environment instead of leaving it in a readable file.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. "Please don't" in the prompt
&lt;/h3&gt;

&lt;p&gt;Rules that matter belong in config and hooks, not prose. A &lt;code&gt;PreToolUse&lt;/code&gt; hook that exits with code &lt;code&gt;2&lt;/code&gt; blocks the call and shows its stderr to the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;BLOCK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\brm\s+-[a-z]*r[a-z]*f\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recursive force delete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\bgit\s+push\b.*--force(?!-with-lease)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;force push without lease&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b(curl|wget)\b[^|]*\|\s*(sh|bash)\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;piping a download into a shell&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;BLOCK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Blocked: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Ask the human.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test it with two &lt;code&gt;echo '{...}' | python3 guard.py; echo $?&lt;/code&gt; lines before you trust it.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. The hook was "installed" but never ran
&lt;/h3&gt;

&lt;p&gt;Codex requires new or changed hooks to be trusted before they execute, and a wrong path fails silently anywhere. &lt;strong&gt;Verify a hook by its output, not by its presence.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  D. Context and memory failures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12. Context full of passing-test output
&lt;/h3&gt;

&lt;p&gt;Move long suites into a &lt;code&gt;test-runner&lt;/code&gt; subagent that returns only failures. The main context gets 5 lines instead of 5,000.&lt;/p&gt;

&lt;h3&gt;
  
  
  13. The reviewer rewrote the code
&lt;/h3&gt;

&lt;p&gt;A reviewer with an Edit tool stops reviewing and starts rewriting. Give it &lt;code&gt;Read, Grep, Glob, Bash&lt;/code&gt; only, or run a second tool read-only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="nt"&gt;--profile&lt;/span&gt; review &lt;span class="s2"&gt;"Review the current git diff against AGENTS.md.
Reply with VERDICT, BLOCKING, NON-BLOCKING, EVIDENCE."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(In current Codex a profile is its own file, &lt;code&gt;~/.codex/review.config.toml&lt;/code&gt;, containing &lt;code&gt;sandbox_mode = "read-only"&lt;/code&gt;.)&lt;/p&gt;

&lt;h3&gt;
  
  
  14. Memory contradicts itself
&lt;/h3&gt;

&lt;p&gt;An append-only &lt;code&gt;MEMORY.md&lt;/code&gt; turns into fiction within a month. Use three layers: raw per-turn logs, a daily summary capped at 40 lines, and a durable memory capped at 120 lines. A weekly job &lt;strong&gt;promotes&lt;/strong&gt; an item only if it shows up in two or more daily files, and &lt;strong&gt;forgets&lt;/strong&gt; closed loops and contradicted facts.&lt;/p&gt;

&lt;h3&gt;
  
  
  15. Duplicate external actions after a timeout
&lt;/h3&gt;

&lt;p&gt;A scheduled job sends a message, the request times out, the job retries, and now there are two messages. When a call times out, you can't tell "never arrived" from "processed, response lost". Give every external action an &lt;strong&gt;idempotency key&lt;/strong&gt;, record it &lt;em&gt;before&lt;/em&gt; the call, mark it &lt;code&gt;unknown&lt;/code&gt; on timeout, and check the target system before retrying.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 60-minute version
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;0-15 min:&lt;/strong&gt; one &lt;code&gt;AGENTS.md&lt;/code&gt; (what it is, commands, needs-a-human, definition of done) plus thin adapters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;15-30 min:&lt;/strong&gt; an approval matrix, then allow/ask/deny lists and Codex sandbox defaults from it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30-45 min:&lt;/strong&gt; a guard hook (tested), plus reviewer and test-runner subagents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;45-60 min:&lt;/strong&gt; a &lt;code&gt;MEMORY.md&lt;/code&gt; with five real facts and a nightly consolidation job.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then track three numbers weekly: accepted changes, rework rate, and human minutes per accepted change.&lt;/p&gt;




&lt;h3&gt;
  
  
  Want the templates?
&lt;/h3&gt;

&lt;p&gt;I packaged the full setup into a free 4-page preview (failure catalogue, the try-then-verify loop, and the definition-of-done checklist): &lt;strong&gt;&lt;a href="https://adrianstudio3.gumroad.com/l/agent-ops-kit-preview" rel="noopener noreferrer"&gt;download the free preview&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The full kit has a 28-page guide plus 29 ready-to-copy files: &lt;code&gt;AGENTS.md&lt;/code&gt;/&lt;code&gt;CLAUDE.md&lt;/code&gt;/&lt;code&gt;GEMINI.md&lt;/code&gt;, Claude Code &lt;code&gt;settings.json&lt;/code&gt; with the tested guard hook, reviewer and test-runner subagents, Codex profiles, an LLM-wiki structure with a validator, and the memory routine. It's &lt;a href="https://adrianstudio3.gumroad.com/l/agent-ops-kit" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you want it (launch code &lt;code&gt;AGENTOPS&lt;/code&gt;).&lt;/p&gt;

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