<?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: Edward Izgorodin</title>
    <description>The latest articles on DEV Community by Edward Izgorodin (@izgorodin).</description>
    <link>https://dev.to/izgorodin</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%2F3989589%2F15cb8fb8-9785-496a-be83-65c3061529d2.jpeg</url>
      <title>DEV Community: Edward Izgorodin</title>
      <link>https://dev.to/izgorodin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/izgorodin"/>
    <language>en</language>
    <item>
      <title>How can I let an AI assistant learn from user corrections while keeping context lean?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Mon, 09 Nov 2026 10:56:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/how-can-i-let-an-ai-assistant-learn-from-user-corrections-while-keeping-context-lean-4naj</link>
      <guid>https://dev.to/izgorodin/how-can-i-let-an-ai-assistant-learn-from-user-corrections-while-keeping-context-lean-4naj</guid>
      <description>&lt;p&gt;A correction appended beside an old memory leaves two statements that disagree, and both can enter the context. A correction discarded as a duplicate leaves no correction at all.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write a correction as a replacement that names the memory it replaces, not as a note beside it. The store can then hold one current answer per subject, and the context receives one line instead of two conflicting lines.&lt;/li&gt;
&lt;li&gt;Key each memory by what it describes, using a subject plus a predicate, and treat its sentence as replaceable. A correction then finds its target by key rather than wording similarity, following the scheme &lt;a href="https://dev.to/haoning_kan_20d7ddb19e07c/i-benchmarked-6-ai-agent-memory-strategies-top-score-worst-experience-35gj#comment-3flmj"&gt;Max Quimby described&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A correction can disappear during deduplication, during the assistant's turn, or during retrieval for a broad question. UyLe encountered all three while building a chatbot memory and wrote, &lt;a href="https://medium.com/@lequocuyit/i-gave-my-chatbot-memory-then-gave-the-memory-back-to-the-users-eaba16bb6b86" rel="noopener noreferrer"&gt;"Each needed its own fix."&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lean context depends on what the assistant reads by default, not on deleting history. Serve the current version and retain the replaced versions as a record of what changed, when, and on whose word.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Mnemoverse (the author's company) makes one of the memory systems named below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A correction is a write that says an earlier memory was wrong or out of date and names the memory it replaces.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A memory key is the stable identity of what a memory is about, such as a subject and a predicate, kept apart from the sentence that states it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The current version of a memory is the one no later write has replaced; it is the only version a default read should put into the context.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does appending corrections make the context grow and the answers worse?
&lt;/h2&gt;

&lt;p&gt;Appending preserves both claims as current:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user:editor = "I use VS Code"
user:editor = "I no longer use VS Code. I use Zed."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The assistant must resolve the contradiction each time it reads them. Retrieval can also return the older claim without the newer one.&lt;/p&gt;

&lt;p&gt;Haoning Kan reported this behavior in a NeatMem run while &lt;a href="https://dev.to/haoning_kan_20d7ddb19e07c/i-benchmarked-6-ai-agent-memory-strategies-top-score-worst-experience-35gj"&gt;"running PointWise + Rewrite with recall threshold 0.8"&lt;/a&gt;. After a move from Seattle to Austin, he found that "two contradictory memories coexist in the store". In that run, only pairs above 0.8 received a model judgment. Similarity between the two statements fell between 0.71 and 0.75, so the judgment was skipped and the new statement became another memory. Kan explained the underlying problem: "Contradictory statements are often worded very differently (one says Seattle, the other Austin), so their similarity is naturally low."&lt;/p&gt;

&lt;p&gt;Kiell Tampubolon described a related failure: &lt;a href="https://dev.to/kielltampubolon/comment/3f9a1"&gt;"A correction written from a different angle does not just fail to link to the old entry, it can paraphrase the mistake into a new entry that reads as fresh insight."&lt;/a&gt; Replacement semantics cannot help if the write never identifies what it replaces.&lt;/p&gt;

&lt;p&gt;Prompt space can impose a hard limit. The Hermes Agent documentation says, &lt;a href="https://hermes-agent.nousresearch.com/docs/user-guide/features/memory" rel="noopener noreferrer"&gt;"Memory has strict character limits to keep system prompts bounded".&lt;/a&gt; As documented on 2 November 2026, &lt;code&gt;MEMORY.md&lt;/code&gt; allows &lt;code&gt;2,200 chars (~800 tokens)&lt;/code&gt;, while &lt;code&gt;USER.md&lt;/code&gt; allows &lt;code&gt;1,375 chars (~500 tokens)&lt;/code&gt;. Its documentation also states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Memory does not auto-compact: when a write would exceed the limit, the memory tool returns an error instead of silently dropping entries."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Replacing one value uses less prompt space than appending each correction. For a broader treatment of this rule, see &lt;a href="https://mnemoverse.com/docs/library/ai-assistant-outdated-answers-after-refactoring" rel="noopener noreferrer"&gt;How do I stop my AI assistant giving outdated answers after code refactoring?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How should a correction be written so it replaces the old memory?
&lt;/h2&gt;

&lt;p&gt;A correction needs four fields: the identifier or key of the memory being replaced, the new value, the source of the correction, and the time of the correction. The write should create a replacement record and link it to its predecessor. It should not silently edit the earlier record in place.&lt;/p&gt;

&lt;p&gt;Aryapathak documented what happens when a repair changes the sentence but retains the bad support beneath it: &lt;a href="https://dev.to/aryapathak/i-corrected-my-ais-memory-it-cited-the-original-mistake-as-proof-1l26"&gt;"My memory repair had fixed the sentence and kept the lie underneath it, at confidence: 1.0."&lt;/a&gt; Their correction flow marks the earlier claim as replaced, creates a linked replacement, and updates dependent decisions. The reason is provenance: "A correction isn't an edit. It's a new piece of evidence from a different source, a human reviewer, and it needs its own provenance like any other source."&lt;/p&gt;

&lt;p&gt;A correction should also name the version it read. The ai-memory source describes an optional &lt;code&gt;expected_page_id&lt;/code&gt; that writes only when that page remains current. If the target changed first, &lt;a href="https://github.com/akitaonrails/ai-memory/blob/ef82b7175783092407821b62e67d257a23408a85/docs/ARCHITECTURE.md" rel="noopener noreferrer"&gt;"a failed precondition writes nothing and returns reason: "precondition_failed" with the current version"&lt;/a&gt;. That visible failure prevents one correction from overwriting a later one.&lt;/p&gt;

&lt;p&gt;The replacement must be narrow enough. Hermes Agent documents why it stopped offering a whole-entry replacement action:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"There is no replace action. It overwrote the whole matched entry, and models used it as a find-and-swap, which wiped the other facts in multi-fact entries."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Its &lt;code&gt;patch&lt;/code&gt; action instead "replaces only the old_text span inside the matched entry and keeps everything else." This matters when one entry contains several facts and only one is wrong.&lt;/p&gt;

&lt;p&gt;The word &lt;code&gt;update&lt;/code&gt; can hide distinct operations. &lt;a href="https://mnemoverse.com/docs/library/memory-response-shape" rel="noopener noreferrer"&gt;Memory API response shape: Why one update result is not enough&lt;/a&gt; explains why callers need the operation's actual outcome.&lt;/p&gt;

&lt;p&gt;On the Mnemoverse REST API, a write can &lt;a href="https://mnemoverse.com/docs/api/reference#post-memory-write" rel="noopener noreferrer"&gt;&lt;code&gt;pass supersedes to mark this write as the correction for one or more earlier atoms.&lt;/code&gt;&lt;/a&gt; The target remains fetchable by ID and gains a pointer to the replacement. A write carrying that field is not refused by the novelty check. The caller must first read and identify the target. One limitation matters here: read-side filtering is off by default and must be enabled by the organisation. Until enabled, replaced records can still appear in reads, marked by &lt;code&gt;superseded_by&lt;/code&gt;. Long correction histories also consume storage quota, even when filtering later hides them from search.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should a memory be keyed on so a correction finds its target?
&lt;/h2&gt;

&lt;p&gt;Max Quimby gave an operational rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We key a memory on a stable slug (a normalized subject + predicate) and treat the natural-language body as replaceable."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;key: user:editor
value: "Zed"
replaces: atom_older_editor
source: user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key identifies the question. The value answers it. A write looks up the key before deciding whether to append, replace, or reject.&lt;/p&gt;

&lt;p&gt;Quimby's process merges new wording into the existing record instead of appending another synonym. A model is called only when values conflict, rather than whenever wording differs. The key alone cannot decide whether a statement narrows an earlier fact or contradicts it. As Quimby observed, &lt;code&gt;"works at a startup" vs "works at Acme" aren't dupes and aren't contradictions, and an overwrite loses information either way.&lt;/code&gt; The write operation must express whether the new value refines or replaces the old one.&lt;/p&gt;

&lt;p&gt;Keys create their own failure mode. Heinrich Neb, who disclosed that he works on a competing memory layer for coding agents, wrote: &lt;a href="https://dev.to/heinrichneb/comment/3djp0"&gt;"Misspell the slug and you have created a second truth rather than fixing the first, and nothing anywhere objects."&lt;/a&gt; He added that in his own layer, closely related keys such as &lt;code&gt;deploy:cache&lt;/code&gt; and &lt;code&gt;deploy:caching&lt;/code&gt; may remain separate, with nothing to notice that they name the same subject.&lt;/p&gt;

&lt;p&gt;Ken W Alger proposed narrowing predecessor candidates by stable subject, claim type, or authority domain before semantic comparison. He also argued that the system should preserve what it searched. Otherwise, &lt;a href="https://dev.to/kenwalger/comment/3df5b"&gt;"no predecessor found" can mean either "there wasn't one" or "we looked in the wrong place."&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A practical sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Normalize the subject and predicate.&lt;/li&gt;
&lt;li&gt;Search for a predecessor by that key.&lt;/li&gt;
&lt;li&gt;Use similarity as a secondary check for key spelling or normalization errors.&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;no predecessor found&lt;/code&gt; with the searched key and scope.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where do user corrections get lost, and how do I check each place?
&lt;/h2&gt;

&lt;p&gt;UyLe summarized the problem directly: &lt;a href="https://medium.com/@lequocuyit/i-gave-my-chatbot-memory-then-gave-the-memory-back-to-the-users-eaba16bb6b86" rel="noopener noreferrer"&gt;"Corrections were lost three ways."&lt;/a&gt; This was an observation from UyLe's hippo project, not a cross-system measurement. UyLe reported that since September 22, 12 people had used the chatbot on the web and Telegram, and it had stored 26 memories for them on mainnet.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Place&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Passing result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Deduplication on write&lt;/td&gt;
&lt;td&gt;The correction is discarded as a copy, or admitted beside the old claim&lt;/td&gt;
&lt;td&gt;Write a fact, a similarly worded correction, then a differently worded correction. List every record for the subject&lt;/td&gt;
&lt;td&gt;One current record. The old record is marked as replaced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The assistant's turn&lt;/td&gt;
&lt;td&gt;The model acknowledges the change but stores nothing&lt;/td&gt;
&lt;td&gt;After the acknowledgment, inspect the store rather than the reply&lt;/td&gt;
&lt;td&gt;A new record names the record it replaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The broad question&lt;/td&gt;
&lt;td&gt;A broad query recalls the old fact but misses the correction&lt;/td&gt;
&lt;td&gt;In a fresh session, ask both a broad and a specific question&lt;/td&gt;
&lt;td&gt;Both answers use the correction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;UyLe's concrete deduplication observation was: &lt;code&gt;Dedupe discarded “I no longer use VS Code” as a duplicate of “I use VS Code”, 0.24 apart, because distance cannot see “no”.&lt;/code&gt; That value describes one observation in that project. It is not a general threshold.&lt;/p&gt;

&lt;p&gt;The demo also changed one memory, discarded the conversation, and asked questions in a fresh session. UyLe reported that &lt;code&gt;0 of 5 answers stated pnpm without bun&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A fresh session matters for systems that snapshot memory. Hermes Agent documents: &lt;a href="https://hermes-agent.nousresearch.com/docs/user-guide/features/memory" rel="noopener noreferrer"&gt;"The system prompt injection is captured once at session start and never changes mid-session."&lt;/a&gt; A fact saved during the current session becomes visible to the next session, not to another session that was already running. Testing only in the writing session therefore proves neither success nor failure.&lt;/p&gt;

&lt;p&gt;There is a fourth check before storage: verify the correction itself. &lt;a href="https://dev.to/mihai_leanzero/comment/3f7dn"&gt;Mihai Perdum warned&lt;/a&gt; that a diagnosis can be wrong while still looking plausible for the case that produced it. Ali Khater recommends sending low-confidence contradictions to review rather than silently replacing existing evidence.&lt;/p&gt;

&lt;p&gt;For deeper write-path tests, see &lt;a href="https://mnemoverse.com/docs/library/agent-memory-write-gate" rel="noopener noreferrer"&gt;Write Gate: What Never Gets Stored&lt;/a&gt; and &lt;a href="https://mnemoverse.com/docs/library/rag-vs-agent-memory" rel="noopener noreferrer"&gt;RAG vs agent memory&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens to the old version when a correction is applied or undone?
&lt;/h2&gt;

&lt;p&gt;An undo operation must state which outcome it intends:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep the replacement chain and mark a newer correction.&lt;/li&gt;
&lt;li&gt;Withdraw the correction and restore its predecessor as current.&lt;/li&gt;
&lt;li&gt;Withdraw both versions because neither remains valid.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These outcomes are not interchangeable.&lt;/p&gt;

&lt;p&gt;The Hy-Memory account below is the author's reading of its source at commit &lt;a href="https://github.com/Tencent-Hunyuan/Hy-Memory/blob/fcb1bcd8665322c3500027dae096f8749a61b071/hy_memory/client.py" rel="noopener noreferrer"&gt;&lt;code&gt;fcb1bcd&lt;/code&gt;&lt;/a&gt;, with the same behavior at &lt;a href="https://github.com/Tencent-Hunyuan/Hy-Memory/blob/8f1c4045e913566a6f40eb4451d68218b2307773/hy_memory/client.py" rel="noopener noreferrer"&gt;&lt;code&gt;8f1c404&lt;/code&gt;&lt;/a&gt;, both read on 2 November 2026.&lt;/p&gt;

&lt;p&gt;The update method writes &lt;code&gt;node.content = content&lt;/code&gt;, replacing the text and embedding on the same record. It writes a history entry with &lt;code&gt;change_reason="client.update"&lt;/code&gt; when history is enabled by configuration. In the author's reading of that method, it sets no supersession field.&lt;/p&gt;

&lt;p&gt;A separate data-model comment, in &lt;a href="https://github.com/Tencent-Hunyuan/Hy-Memory/blob/fcb1bcd8665322c3500027dae096f8749a61b071/hy_memory/models/memory.py" rel="noopener noreferrer"&gt;&lt;code&gt;memory.py&lt;/code&gt;&lt;/a&gt; at the same commit, says, in the author's translation, that fact changes are tracked through status transitions and a &lt;code&gt;SUPERSEDED_BY&lt;/code&gt; edge rather than direct content edits. The delete path can repair a chain by restoring the predecessor as current, logging &lt;code&gt;chain repair: restored {pred_id} as chain head&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An update can preserve old text in the optional history journal without leaving a replacement chain on the read path. Deleting a chain head can restore the earlier belief. Restoration is correct when the replacement was the mistake. It is wrong when both claims have become invalid.&lt;/p&gt;

&lt;p&gt;The ai-memory source takes another approach. Its README says, &lt;a href="https://github.com/akitaonrails/ai-memory/blob/ef82b7175783092407821b62e67d257a23408a85/README.md" rel="noopener noreferrer"&gt;"The source of truth is a git-backed wiki of ordinary .md files".&lt;/a&gt; The database is a rebuildable derived index. Marking a page &lt;code&gt;stale&lt;/code&gt; or &lt;code&gt;wrong&lt;/code&gt; lowers its salience without deleting it, and a later rewrite clears that mark. Administrators can list the Git checkpoints that changed a path.&lt;/p&gt;

&lt;p&gt;Raghu Juluri condensed the design requirement: &lt;a href="https://medium.com/@raghuece455/how-to-give-your-coding-agent-a-memory-that-survives-the-session-ca6bd2f70502" rel="noopener noreferrer"&gt;"Memory your agent writes is memory you will eventually need to correct. Pick the format you can correct."&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For six more source-based examples, see &lt;a href="https://mnemoverse.com/docs/library/agent-memory-consolidation-compared" rel="noopener noreferrer"&gt;When a newer memory contradicts an older one, what happens to the older one?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I keep context lean without losing the record of what was corrected?
&lt;/h2&gt;

&lt;p&gt;Default reads should return current records. Historical reads should reconstruct earlier states. Ali Khater describes this split directly: &lt;a href="https://dev.to/alikhatersaibreakroom/comment/3f4fc"&gt;"A contradiction should usually close the old fact's validity window and link it to the replacement, while the default read returns only currently valid facts."&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep each current memory compact. UyLe's project stores each memory as one line with a type tag. The history can retain the longer account of who changed what and why.&lt;/p&gt;

&lt;p&gt;Some corrections apply only to one kind of work. Hermes Agent's documentation says that for a location the agent needs on every run of a recurring task, a skill "is often the better home than a memory entry" because "it loads only when relevant and does not compete for the 2,200-character budget." The documentation discusses locations for recurring tasks. Applying the same placement rule to task-specific corrections is this article's inference.&lt;/p&gt;

&lt;p&gt;The correction record should remain available in storage. It answers why the assistant changed its behavior and helps prevent a rejected decision from returning. See &lt;a href="https://mnemoverse.com/docs/library/ai-agent-memory#agent-forgets-decisions" rel="noopener noreferrer"&gt;AI agent memory and decision records&lt;/a&gt; for that separate problem.&lt;/p&gt;

&lt;p&gt;Automated review may also separate a proposed correction from an active one. &lt;a href="https://github.com/NousResearch/hermes-agent/blob/d05095663342556788cf2a198bfa7844cc7968ab/tools/memory_tool.py" rel="noopener noreferrer"&gt;Hermes Agent's source&lt;/a&gt; says background &lt;code&gt;patch&lt;/code&gt; and &lt;code&gt;remove&lt;/code&gt; operations &lt;code&gt;are never applied unattended&lt;/code&gt;. This is an example of why "stored" and "currently applied" need separate states.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I test this on my own assistant?
&lt;/h2&gt;

&lt;p&gt;Write the expected result before each run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Store &lt;code&gt;I use VS Code&lt;/code&gt;. Then write &lt;code&gt;I no longer use VS Code, I use Zed&lt;/code&gt;. Expect one current editor record, one replaced record, and a replacement link from the new record to the old one.&lt;/li&gt;
&lt;li&gt;Repeat with &lt;code&gt;My editor is Zed now&lt;/code&gt;. If the system uses keys, also introduce a key typo. Check whether it finds the predecessor or creates a second current answer.&lt;/li&gt;
&lt;li&gt;Start a fresh session. Ask &lt;code&gt;Which editor do I use?&lt;/code&gt; and &lt;code&gt;What do you know about me?&lt;/code&gt; Expect Zed in both answers. VS Code should appear only in a history query.&lt;/li&gt;
&lt;li&gt;Undo the correction. Before running the operation, write down which version should become current. Compare the stored result with that expectation.&lt;/li&gt;
&lt;li&gt;Inspect the assembled context and count the editor claims. Expect one current line.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Illustration, not data: the editor names are examples.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article does not claim
&lt;/h2&gt;

&lt;p&gt;No performance figure is presented for any system. The numbers quoted above are practitioners' own runs and observations, with the bounds they stated, and none was rerun here.&lt;/p&gt;

&lt;p&gt;The systems named are examples, not a complete list, and none is ranked. Statements about Hy-Memory, ai-memory, and Hermes Agent source code are the author's reading of the commits linked above, not vendor statements. Those repositories can change after the cited commits.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Every quotation was read on 2 November 2026 with two instruments, a browser-like request and a reader service with its cache off (dev.to also through its API, Medium also through RSS, GitHub files also raw and through jsDelivr at the commits named); a made-up address on each host answered 404 as a control, except Medium, which answers 200 to any address, so there only the post text counts. The text describes those pages and files as of that date, and the numbers are the practitioners' own, with the bounds they stated. A longer version, with every source, is in the Mnemoverse documentation library: &lt;a href="https://mnemoverse.com/docs/library/learn-from-user-corrections" rel="noopener noreferrer"&gt;How can I let an AI assistant learn from user corrections while keeping context lean?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-11-02&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>agents</category>
      <category>llm</category>
    </item>
    <item>
      <title>How to prevent Cursor from repeating past mistakes?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Sun, 08 Nov 2026 10:28:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/how-to-prevent-cursor-from-repeating-past-mistakes-4geb</link>
      <guid>https://dev.to/izgorodin/how-to-prevent-cursor-from-repeating-past-mistakes-4geb</guid>
      <description>&lt;p&gt;Move each correction out of the chat into a rule that the next chat receives, confirm that the rule reached the chat where the mistake came back, and if it did and the mistake came back anyway, stop rewording the rule and put the check into something that runs: a hook, a linter or a test. Cursor's &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules documentation&lt;/a&gt; gives the first step, "Start simple. Add rules only when you notice Agent making the same mistake repeatedly", and the loop after it: "When you see Agent make a mistake, update the rule." Two things decide whether that loop works: a repeated mistake has two causes with different fixes, and Cursor keeps lessons in several places that different parts of the product read.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A correction in chat is not yet a lesson.&lt;/strong&gt; It lives in the thread where you typed it. Put it in a rule; &lt;code&gt;/create-rule&lt;/code&gt; in Agent writes one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two failures, two fixes.&lt;/strong&gt; If the rule never reached this chat (a folder scope, a rule type, a file pattern, a pointer file), fix where and how it is stored. If it was in context and the model chose otherwise, add a check that runs instead of stronger wording. Cursor staff have diagnosed both on the forum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lessons live in separate places.&lt;/strong&gt; Project rules do not apply to Bugbot, and Bugbot's learned rules come from pull request feedback and live in the dashboard. The pages read for this article do not describe those learned rules reaching Agent chat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find out which one before rewording.&lt;/strong&gt; Repeat the task in a new chat, and ask the agent to quote its rules word for word.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Mnemoverse (the author's company) makes a memory API for agents; it is not one of the places described below, and nothing below tests it.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does Cursor repeat a mistake you already corrected?
&lt;/h2&gt;

&lt;p&gt;Because the correction was made in one conversation, and a new conversation does not carry it. Alden Harwood, on the &lt;a href="https://forum.cursor.com/t/how-to-get-rules-memories-to-actually-work/135079/3" rel="noopener noreferrer"&gt;Cursor forum on 26 September 2025&lt;/a&gt;: "If within a thread I correct it and tell it to 'use make test to test' then it often will continue and do so for the duration of the thread". It was the new threads that failed for him.&lt;/p&gt;

&lt;p&gt;A long thread can lose a correction too. Cursor's &lt;a href="https://cursor.com/docs/agent/prompting" rel="noopener noreferrer"&gt;prompting page&lt;/a&gt;: "When the window gets close to full, Cursor compresses older parts of the conversation into a summary to leave more room for new conversation." Dean Rie, Cursor staff, wrote on the &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/8" rel="noopener noreferrer"&gt;forum on 31 August 2026&lt;/a&gt; that summarization "can drop some instructions". Cursor's &lt;a href="https://cursor.com/blog/agent-best-practices" rel="noopener noreferrer"&gt;agent best practices&lt;/a&gt; list "The agent seems confused or keeps making the same mistakes" among the signs to start a new conversation.&lt;/p&gt;

&lt;p&gt;A new chat clears the noise and the correction with it, so the correction has to leave the chat. The &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules page&lt;/a&gt;: "Type &lt;code&gt;/create-rule&lt;/code&gt; in Agent and describe what you want." And: "You can even tag &lt;code&gt;@cursor&lt;/code&gt; on a GitHub issue or PR to have Agent update the rule for you."&lt;/p&gt;

&lt;h2&gt;
  
  
  Did the rule reach this chat, or did the model choose otherwise?
&lt;/h2&gt;

&lt;p&gt;When a rule exists and the mistake still comes back, the rule failed in one of two ways, and Cursor's staff tell the two apart in their forum replies.&lt;/p&gt;

&lt;p&gt;Mohit, Cursor staff, on &lt;a href="https://forum.cursor.com/t/agent-repeatedly-ignores-workspace-user-rules-and-repo-gates-across-multiple-chats-unauthorized-api-deploy-wrong-process-order/170277/12" rel="noopener noreferrer"&gt;2 September 2026&lt;/a&gt;, to a user whose agent kept breaking his rules across chats: "Rules in infra/.cursor/rules/ only load when a chat is touching infra/ (even with alwaysApply: true), and pointer files only pass the path, not the rule itself." On another rule in the same reply: "Your GitLab-only rule is reaching the model, but some built-in guidance competes with it, so adding another 'no gh' rule won't reliably win." He added: "This isn't intended behavior, and we've let the team know." The first rule never reached the chat. The second reached it and lost.&lt;/p&gt;

&lt;p&gt;Kevin Neilson, Cursor staff, on &lt;a href="https://forum.cursor.com/t/the-agent-is-ignoring-the-rules/165164/6" rel="noopener noreferrer"&gt;9 July 2026&lt;/a&gt;, after reading a user's transcript: "From the transcript you pasted, the rules were actually in context. The agent still chose a bigger design over your constraints." Dean Rie, on &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/6" rel="noopener noreferrer"&gt;30 August 2026&lt;/a&gt;, to a user whose agent kept breaking the same Python rules: "So this is not a rules loading issue. The issue is how the rules get applied."&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;The rule never reached this chat&lt;/th&gt;
&lt;th&gt;The rule was in context, the model chose otherwise&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Causes Cursor names&lt;/td&gt;
&lt;td&gt;The rule sits in a subfolder the chat does not touch; a pointer file passes only a path; an Apply Intelligently rule without a description; a file pattern that does not match; a feature rules do not reach, such as Tab or Bugbot&lt;/td&gt;
&lt;td&gt;A long chat and its summaries; built-in guidance that competes with the rule; a long always-applied file that buries the key constraint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fix&lt;/td&gt;
&lt;td&gt;Put the rule text where that chat loads it; keep must-obey constraints short, specific and Always Apply&lt;/td&gt;
&lt;td&gt;A check that runs: a hook, a linter, a test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First check&lt;/td&gt;
&lt;td&gt;Ask the agent to quote the rule&lt;/td&gt;
&lt;td&gt;Ask whether it also happens in a new chat&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;From outside the two look the same: the mistake comes back. The last row is the check that tells them apart.&lt;/p&gt;

&lt;p&gt;For the first case, the FAQ of the &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules page&lt;/a&gt;: "Check the rule type. For &lt;code&gt;Apply Intelligently&lt;/code&gt;, ensure a description is defined. For &lt;code&gt;Apply to Specific Files&lt;/code&gt;, ensure the file pattern matches referenced files." This case makes no noise. Ned C, in a &lt;a href="https://dev.to/nedcodes/comment/34o4i"&gt;dev.to comment of 23 February 2026&lt;/a&gt;: "the alwaysApply thing is brutal because nothing tells you it's not working. it just silently does nothing."&lt;/p&gt;

&lt;p&gt;For the second case, Kevin Neilson, in the &lt;a href="https://forum.cursor.com/t/the-agent-is-ignoring-the-rules/165164/6" rel="noopener noreferrer"&gt;same reply of 9 July&lt;/a&gt;, on how rules work today: "they are strong guidance injected into the model prompt, not fail-closed runtime guards." Dean Rie, on &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/8" rel="noopener noreferrer"&gt;31 August&lt;/a&gt;: "So adding more rules often backfires." The Reddit user InteractionSmall6778, in a &lt;a href="https://www.reddit.com/r/cursor/comments/1tfn3c4/solution_to_cursor_repeating_past_mistakes_and/omb29hr/" rel="noopener noreferrer"&gt;comment of 17 May 2026&lt;/a&gt; on r/cursor: "The rules are still there, they just lose the attention war against 15 turns of error output."&lt;/p&gt;

&lt;p&gt;An apology from the agent tells you neither case. Nikolaos Moraitis quoted his agent's reply on the &lt;a href="https://forum.cursor.com/t/the-agent-is-ignoring-the-rules/165164/15" rel="noopener noreferrer"&gt;forum on 3 August 2026&lt;/a&gt;: "That broke your rules. Won't do that again." Dean Rie wrote on &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/8" rel="noopener noreferrer"&gt;31 August 2026&lt;/a&gt; that acknowledging and repairing does not improve compliance further in the same session, and called that "a result of the probabilistic nature of the model and the degradation in long runs".&lt;/p&gt;

&lt;h2&gt;
  
  
  What fixes a rule that was in context and still broken?
&lt;/h2&gt;

&lt;p&gt;A check that runs outside the model's choice. javier marcon, on &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/1" rel="noopener noreferrer"&gt;30 August 2026&lt;/a&gt;: "So Agent clearly understands the rule once an external gate reports it." And: "The problem is that the same classes of violations are then introduced again in subsequent implementation work." Dean Rie's &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/6" rel="noopener noreferrer"&gt;answer of the same day&lt;/a&gt;: "A hook on afterFileEdit can run your Ruff and module-size audit after every file edit and block the patch deterministically." In his words, "This is enforcement, not guidance".&lt;/p&gt;

&lt;p&gt;Where the hook sits matters. Dean Rie, on &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/12" rel="noopener noreferrer"&gt;20 September&lt;/a&gt;: "afterFileEdit runs after the file is written." And: "What actually blocks an edit before the agent starts building dependent changes on top of it is preToolUse on the Write tool".&lt;/p&gt;

&lt;p&gt;Cursor's documentation points the same way. The &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules page&lt;/a&gt;, on copying a style guide into a rule: "Use a linter instead. Agent already knows common style conventions." The &lt;a href="https://cursor.com/blog/agent-best-practices" rel="noopener noreferrer"&gt;best practices post&lt;/a&gt;: "Use typed languages, configure linters, and write tests."&lt;/p&gt;

&lt;p&gt;A hook has limits. Kevin Neilson, on &lt;a href="https://forum.cursor.com/t/the-agent-is-ignoring-the-rules/165164/18" rel="noopener noreferrer"&gt;17 August 2026&lt;/a&gt;: "Hooks can hard-block specific files or commands." What stays a rule should be short: Kevin Neilson's &lt;a href="https://forum.cursor.com/t/the-agent-is-ignoring-the-rules/165164/6" rel="noopener noreferrer"&gt;advice of 9 July&lt;/a&gt;, "Keep must-obey constraints short, specific, and Always Apply (or in AGENTS.md)", and Dean Rie's of &lt;a href="https://forum.cursor.com/t/cursor-agent-repeatedly-generates-python-code-that-violates-the-same-explicit-deterministic-repository-hard-rules/169954/12" rel="noopener noreferrer"&gt;20 September&lt;/a&gt;, "a short BAD or GOOD snippet in .mdc is picked up by the agent much better than abstract prose."&lt;/p&gt;

&lt;h2&gt;
  
  
  Where does Cursor keep a lesson, and what reads it?
&lt;/h2&gt;

&lt;p&gt;The table lists nine places where a lesson can live in Cursor. Different hands write them and different parts of Cursor read them; the pages read for this article state for only some pairs whether one reads another.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Where the lesson lives&lt;/th&gt;
&lt;th&gt;Who writes it&lt;/th&gt;
&lt;th&gt;What reads it&lt;/th&gt;
&lt;th&gt;How to check it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The chat&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;That thread; older turns get summarized as the window fills&lt;/td&gt;
&lt;td&gt;Repeat the task in a new chat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Project rules in &lt;code&gt;.cursor/rules&lt;/code&gt;, or &lt;code&gt;AGENTS.md&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;You; Agent, through &lt;code&gt;/create-rule&lt;/code&gt; or an &lt;code&gt;@cursor&lt;/code&gt; tag on a GitHub issue or PR&lt;/td&gt;
&lt;td&gt;Agent (Chat), by rule type: "They do not apply to Tab completion or Bugbot PR reviews."&lt;/td&gt;
&lt;td&gt;Rule type, description, file pattern; ask the agent to quote the rule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User Rules in Cursor Settings&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Agent, in all your projects, synced with your account; files in &lt;code&gt;~/.cursor/rules&lt;/code&gt; "stay on the machine and do not sync."&lt;/td&gt;
&lt;td&gt;Ask the agent to quote its user rules section&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team rules (Team and Enterprise plans)&lt;/td&gt;
&lt;td&gt;Team admins: for Agent on the Cursor dashboard, for Bugbot in Bugbot Automations&lt;/td&gt;
&lt;td&gt;Each first in its own order: Agent (Chat) reads the dashboard's Team Rules, Bugbot its own team rules; the pages read do not say that one list feeds the other&lt;/td&gt;
&lt;td&gt;Team Rules in Customize, where a member can switch off a rule that is not enforced; Bugbot's table of included rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.cursor/BUGBOT.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Bugbot: the root file, plus files found upward from changed files&lt;/td&gt;
&lt;td&gt;Bugbot's table of included rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bugbot learned rules&lt;/td&gt;
&lt;td&gt;Bugbot, from feedback on merged or closed pull requests; you, with &lt;code&gt;@cursor remember [fact]&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Bugbot reviews; kept in the dashboard; the pages read do not describe them reaching Agent chat&lt;/td&gt;
&lt;td&gt;The dashboard; the attribution in the review comment's footer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A Project's shared files&lt;/td&gt;
&lt;td&gt;The Project's agents&lt;/td&gt;
&lt;td&gt;Agents of that Project, on cloud and local machines; not on the Free, Plus or legacy Hobby plans&lt;/td&gt;
&lt;td&gt;The page does not say where the files can be viewed, or how an entry is chosen or removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automation memories&lt;/td&gt;
&lt;td&gt;The agent, in runs of one automation; you, in the tool configuration UI&lt;/td&gt;
&lt;td&gt;Later runs of the same automation&lt;/td&gt;
&lt;td&gt;View, edit or delete them in the tool configuration UI; the page warns that inputs "may lead to misleading or malicious memories"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Older account rules&lt;/td&gt;
&lt;td&gt;Saved to the account earlier; staff say the case "seems most likely on accounts that used the old Memories feature"&lt;/td&gt;
&lt;td&gt;Agent, even where Customize leaves them out&lt;/td&gt;
&lt;td&gt;Ask the agent to quote its user rules section; open Customize in a new window with no folder&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Each row summarizes Cursor's documentation and staff replies on its forum, read on 4 and 5 November 2026; not a test.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Row sources: &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules&lt;/a&gt;, &lt;a href="https://cursor.com/help/customization/rules" rel="noopener noreferrer"&gt;rules help&lt;/a&gt;, &lt;a href="https://cursor.com/docs/agent/prompting" rel="noopener noreferrer"&gt;prompting&lt;/a&gt;, &lt;a href="https://cursor.com/docs/bugbot" rel="noopener noreferrer"&gt;Bugbot&lt;/a&gt;, &lt;a href="https://cursor.com/help/ai-features/bugbot" rel="noopener noreferrer"&gt;Bugbot help&lt;/a&gt;, &lt;a href="https://cursor.com/docs/agent/projects" rel="noopener noreferrer"&gt;Projects&lt;/a&gt;, &lt;a href="https://cursor.com/docs/cloud-agent/automations" rel="noopener noreferrer"&gt;automations&lt;/a&gt; and the forum posts linked in the text.&lt;/p&gt;

&lt;p&gt;Two cells matter most here. The &lt;a href="https://cursor.com/docs/bugbot" rel="noopener noreferrer"&gt;Bugbot page&lt;/a&gt;: "Cursor project rules (&lt;code&gt;*.mdc&lt;/code&gt; files in &lt;code&gt;.cursor/rules/&lt;/code&gt;) do not apply to Bugbot runs." Both orders also begin with team rules, but the pages read keep them in two settings. The &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules page&lt;/a&gt; says a Team Rule "is included in the model context for Agent (Chat) across all repositories and projects for that team", and the Bugbot page says "Team admins can create rules in Bugbot Automations that apply to all repositories in the team." Neither says that one list feeds the other. Until a page says so, a lesson that has to hold in the editor and in review is written for each: a project rule or a Team Rule for Agent, and &lt;code&gt;.cursor/BUGBOT.md&lt;/code&gt; or a Bugbot team rule for review.&lt;/p&gt;

&lt;p&gt;The community Memory Bank template, &lt;a href="https://github.com/vanzan01/cursor-memory-bank" rel="noopener noreferrer"&gt;vanzan01/cursor-memory-bank&lt;/a&gt;, keeps lessons in files of its own: its reflect command "facilitates structured reflection on completed implementation, documenting lessons learned and process improvements." The plan command's own list of files it reads does not include the reflection or archive files. This covers the template's command files, not all its rule files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Bugbot learn from past mistakes, and does Agent see what it learned?
&lt;/h2&gt;

&lt;p&gt;Bugbot does, for its own reviews. Cursor's &lt;a href="https://cursor.com/changelog/04-08-26" rel="noopener noreferrer"&gt;changelog of 8 April 2026&lt;/a&gt;: "Bugbot can now learn from feedback on pull requests and turn those signals into learned rules that improve future reviews." The signals, per the &lt;a href="https://cursor.com/blog/bugbot-learning" rel="noopener noreferrer"&gt;post on learned rules&lt;/a&gt;, are reactions and replies to Bugbot comments and "Comments from human reviewers, which flag issues that Bugbot missed." Candidate rules are promoted as signal accumulates and disabled when they stop being useful.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://cursor.com/docs/bugbot" rel="noopener noreferrer"&gt;Bugbot documentation&lt;/a&gt;: "Bugbot learns from a pull request when it's merged or closed." And: "You can also teach Bugbot new rules inline by commenting &lt;code&gt;@cursor remember [fact]&lt;/code&gt; on any PR. Bugbot saves the fact as a learned rule and applies it to future reviews." The &lt;a href="https://cursor.com/help/ai-features/bugbot" rel="noopener noreferrer"&gt;help page&lt;/a&gt;: "Learning is set per organization." Manual rules are the ones written by hand on Bugbot's repository rules page, not &lt;code&gt;.cursor/BUGBOT.md&lt;/code&gt;, and the &lt;a href="https://cursor.com/docs/bugbot" rel="noopener noreferrer"&gt;Bugbot documentation&lt;/a&gt; ties them to the Automatically Learn Rules switch: "Where that switch exists, manual rules apply only while learning is on, so turning learning off also stops manual rules from applying."&lt;/p&gt;

&lt;p&gt;That &lt;code&gt;@cursor remember&lt;/code&gt; saves a learned rule for Bugbot. The &lt;code&gt;@cursor&lt;/code&gt; tag on the rules page has Agent update a rule file. They are different jobs.&lt;/p&gt;

&lt;p&gt;One direction between the two is stated. Dean Rie, Cursor staff, on &lt;a href="https://forum.cursor.com/t/bugbot-ignores-pr-description-context-when-reviewing-a-pr/165857/7" rel="noopener noreferrer"&gt;16 July 2026&lt;/a&gt;: "Bugbot only reads context from .cursor/BUGBOT.md inside the repo itself, plus Team Rules and repository rules learned or manual from the dashboard." The other direction, learned rules reaching Agent chat, is not described on the pages read for this article. On those pages, a lesson Bugbot learned is a lesson for the review, and the review can run from Agent: "Use the &lt;code&gt;/review-bugbot&lt;/code&gt; or &lt;code&gt;/review&lt;/code&gt; skills to run Bugbot from your agent before you push the code." The section on that skill does not say which rules such a run includes, so a lesson Agent itself has to follow is still written where Agent reads.&lt;/p&gt;

&lt;p&gt;Charles Gourdin named the cost in a &lt;a href="https://forum.cursor.com/t/api-or-git-based-workflow-to-promote-bugbot-learned-rules-into-repository-rules/171018/1" rel="noopener noreferrer"&gt;feature request of 8 September 2026&lt;/a&gt;: "The issue is Bugbot's learned rules: they live only in the Cursor dashboard." Ofer Shapira tried turning repeated human review comments into project rules; two candidate rules passed his evidence bar, and he reported on the &lt;a href="https://forum.cursor.com/t/turning-repeated-code-review-comments-into-cursor-rules-a-small-experiment/176123/1" rel="noopener noreferrer"&gt;forum on 25 October 2026&lt;/a&gt;: "Result: only one rule passed testing on real code." That is one person's experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened to Cursor Memories, and can an old lesson keep applying?
&lt;/h2&gt;

&lt;p&gt;Colin, Cursor staff, on &lt;a href="https://forum.cursor.com/t/legacy-user-rules-still-apply-to-every-chat-but-they-no-longer-appear-in-customize-rules/174724/16" rel="noopener noreferrer"&gt;26 October 2026&lt;/a&gt;: "in some cases Customize can leave out older account rules while the agent still loads them. This seems most likely on accounts that used the old Memories feature, which was retired in Cursor 2.1." So a mistake can also come back from an old lesson that the settings screen does not show. Colin wrote that he had "flagged this to the team" and gave a way to look: a new window with no folder open, then Customize, Rules. "If they show up there, you can edit or delete them from that window, and they'll stop being applied to your chats." Colin's check, on &lt;a href="https://forum.cursor.com/t/legacy-user-rules-still-apply-to-every-chat-but-they-no-longer-appear-in-customize-rules/174724/5" rel="noopener noreferrer"&gt;14 October&lt;/a&gt;: "List every rule in your user rules section and quote each one word for word."&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I check which failure I have?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Repeat the task in a new chat.&lt;/strong&gt; Dean Rie's first question in a &lt;a href="https://forum.cursor.com/t/how-to-get-rules-memories-to-actually-work/135079/2" rel="noopener noreferrer"&gt;thread of 26 September 2025&lt;/a&gt; was "Is this also happening in a new chat?" If the new chat gets it right, the long thread was the problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask the agent to quote the rule.&lt;/strong&gt; Use Colin's prompt above for user rules; for a project rule, also check its type, description, file pattern and folder. A missing rule needs a new place, not new wording.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If the rule was there, look at the thread.&lt;/strong&gt; Kevin Neilson's questions on &lt;a href="https://forum.cursor.com/t/the-agent-is-ignoring-the-rules/165164/9" rel="noopener noreferrer"&gt;9 July 2026&lt;/a&gt;: "How full is the context window? Has it ever been compacted or summarized?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If a short fresh chat with the rule present still breaks it, stop rewording.&lt;/strong&gt; Add a &lt;code&gt;preToolUse&lt;/code&gt; hook on writes, an &lt;code&gt;afterFileEdit&lt;/code&gt; check, a linter or a test. A hook that crashes or times out lets the action through by default, per the &lt;a href="https://cursor.com/docs/hooks" rel="noopener noreferrer"&gt;hooks documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check reviews separately.&lt;/strong&gt; After a &lt;code&gt;bugbot run verbose=true&lt;/code&gt; comment on the pull request, the &lt;a href="https://cursor.com/docs/bugbot" rel="noopener noreferrer"&gt;Bugbot documentation&lt;/a&gt; says, it "posts a table of every rule included in that run and flags any that were truncated or omitted."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test a new rule on real code.&lt;/strong&gt; Ofer Shapira, in his &lt;a href="https://forum.cursor.com/t/turning-repeated-code-review-comments-into-cursor-rules-a-small-experiment/176123/1" rel="noopener noreferrer"&gt;post of 25 October 2026&lt;/a&gt;: "Test on real code before treating a rule as law."&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What this article does not claim
&lt;/h2&gt;

&lt;p&gt;It tests no Cursor feature and gives no figure for how often Agent or Bugbot follows a rule. The staff lines are forum support replies about the cases in those threads, not documentation. The pages read do not describe Bugbot's learned rules reaching Agent chat; this article does not claim that they never do. No hook was run. The Memory Bank observation covers its command files only, and the check list is a proposal, not Cursor's procedure.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Every quotation except the Reddit comment was read on 4 November 2026 with two instruments, a browser-like request (on Cursor's documentation also on each page's Markdown version) and a reader service with its cache off; on 5 November 2026 the Bugbot, rules, Projects and automations pages and the forum posts added on that day were read again with both instruments, and a direct request found every quotation on the page it links to. Forum posts were also read through the forum's JSON and dev.to comments through the dev.to API; the Memory Bank files came from raw.githubusercontent.com. The Reddit comment rests on the thread's RSS feed alone, because the reader service does not serve Reddit. A made-up address on each host answered 404 as a control, and the reader service reported the same 404 everywhere except Reddit, where it refused the thread and the control alike. Staff status comes from the forum's own data. The text describes those pages as of those dates. Which files of the community Memory Bank template actually reach a Cursor session is covered in &lt;a href="https://mnemoverse.com/docs/library/cursor-memory-bank-what-loads" rel="noopener noreferrer"&gt;Cursor Memory Bank: What Actually Loads&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-11-04&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cursor</category>
      <category>ai</category>
      <category>productivity</category>
      <category>codereview</category>
    </item>
    <item>
      <title>How do you reduce LLM spam in PR reviews?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Sat, 07 Nov 2026 09:53:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/how-do-you-reduce-llm-spam-in-pr-reviews-3gjo</link>
      <guid>https://dev.to/izgorodin/how-do-you-reduce-llm-spam-in-pr-reviews-3gjo</guid>
      <description>&lt;p&gt;LLM spam in PR reviews comes from two places: people who paste model output without reading it, and AI reviewers set up to comment on everything. For people, the fix is a written team rule. LLVM's policy says "Contributors must read and review all LLM-generated code or text before they ask other project members to review it.", and it lists "Comments and feedback on pull requests" among the contributions it covers. For bots, AI code review vendors document their own levers against noise: run only when someone asks, raise the bar, skip paths and kinds of comments, write team rules into the repository, and let the reviewer learn from comments the team rejects. Then count what share of each reviewer's comments the team accepts; several vendors already show that share.&lt;/p&gt;

&lt;p&gt;Every vendor and project fact below comes from that vendor's or project's own pages as I read them on 5 November 2026, and none of them saw this text before publication.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a teammate pastes model output into a review
&lt;/h2&gt;

&lt;p&gt;Write the rule down where reviewers see it, and answer a pasted list with a link to that rule instead of a reply to every point. The question behind this article describes the case exactly: a colleague posted, as a review comment on a pull request, an eleven-point list that a model wrote and the colleague had not read. Answering such a list point by point takes the reviewer longer than pasting it took, and LLVM's policy is written against that imbalance.&lt;/p&gt;

&lt;p&gt;LLVM's AI Tool Use Policy fits the whole rule into a few sentences. Tools are allowed, but a person reads the output first and owns it: "The contributor is always the author and is fully accountable for their contributions." Tool use is to be noted where authorship is normally shown: "Contributors should note tool usage in their pull request description, commit message, or wherever authorship is normally indicated for the work." Review bots fall under the same rule: "Similarly, automated review tools that publish comments without human review are not allowed." The next sentence leaves room for a reviewer that a person drives: "However, an opt-in review tool that keeps a human in the loop is acceptable under this policy." Under all of it sits one test: "Our golden rule is that a contribution should be worth more to the project than the time it takes to review it." For a contribution that breaks the policy, maintainers get a standard reply to paste, which asks the author to justify why the change is worth the project's review time.&lt;/p&gt;

&lt;p&gt;Ghostty's AI policy calls its own rules strict. It says "All AI usage in any form must be disclosed.", and for issues and discussions it asks for exactly the trimming that the list in the question skipped: "AI is very good at being overly verbose and including noise that distracts from the main point." and "Humans must do their research and trim this down." Its scope is stated plainly: "These rules apply only to outside contributions to Ghostty."&lt;/p&gt;

&lt;p&gt;When a pasted list has already landed, GitHub lets a team fold it away. Organization moderators and anyone with write access to a repository can hide a comment, and GitHub's moderation page names the cases: "If a comment is off-topic, outdated, or resolved, you may want to hide a comment to keep a discussion focused or make a pull request easier to navigate and review." A hidden comment stays available to readers of the repository: "Hidden comments are minimized but people with read access to the repository can expand them."&lt;/p&gt;

&lt;p&gt;A team can take the shape of these rules without adopting any of them whole: whoever posts model output has read it, answers for every point in it, and says that a tool wrote it. Such a rule works when it sits where authors and reviewers already look, in CONTRIBUTING or in the pull request template, so that the answer to the next unread list is a single link.&lt;/p&gt;

&lt;h2&gt;
  
  
  Levers AI reviewers document against noise
&lt;/h2&gt;

&lt;p&gt;Bots are the other half of LLM spam, and here the vendors document the controls themselves. A vendor appears in a row where its own pages, read for this text, describe that lever; a vendor missing from a row is not a claim that it lacks the lever.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lever&lt;/th&gt;
&lt;th&gt;What it changes&lt;/th&gt;
&lt;th&gt;Who documents it, on their own pages&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Run it only when someone asks&lt;/td&gt;
&lt;td&gt;no review on pushes nobody asked about&lt;/td&gt;
&lt;td&gt;GitHub Copilot: "By default, Copilot only reviews a pull request if you assign it to the pull request." and "However, you can configure automatic reviews."; Greptile: &lt;code&gt;autoReview&lt;/code&gt; as an empty list, "To disable automatic reviews entirely"; CodeRabbit: &lt;code&gt;reviews.auto_review.enabled&lt;/code&gt; set to false, with a review started by a label or by a "Keyword in the PR description that triggers a review when automatic reviews are disabled."; Codex in GitHub: a review on an &lt;code&gt;@codex review&lt;/code&gt; comment, with automatic review as a toggle and a Review trigger for when it runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raise the bar&lt;/td&gt;
&lt;td&gt;fewer comments, and the ones left rank higher&lt;/td&gt;
&lt;td&gt;CodeRabbit: profiles quiet, chill (the default) and assertive, where quiet "Posts only the most important comments inline and groups the other review comments in the review summary."; Greptile: &lt;code&gt;strictness&lt;/code&gt; on a 1-3 scale, where 3 "Shows only the most critical issues (high threshold)."; Sourcery: a review profile that "sets how many comments a review posts."; Qodo: the Precision preset, "Only display comments worth acting on."; Codex in GitHub: it "flags only P0 and P1 issues"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drop a kind or a severity&lt;/td&gt;
&lt;td&gt;takes out a whole class of comments&lt;/td&gt;
&lt;td&gt;Greptile: &lt;code&gt;commentTypes&lt;/code&gt;, with logic, syntax and style as the types; Claude Code Review: &lt;code&gt;REVIEW.md&lt;/code&gt;, "Use it to say what your team wants flagged, at what severity, and what to skip."; Devin Review: "By default, bugs and security findings are posted as PR comments.", "Investigate and informational flags are not posted by default.", and "Admins can toggle each finding type independently."; Graphite: comment exclusions, situations written in plain language where Graphite Agent should not comment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skip paths&lt;/td&gt;
&lt;td&gt;no comments on generated, vendored or lock files&lt;/td&gt;
&lt;td&gt;CodeRabbit: &lt;code&gt;path_filters&lt;/code&gt;, "Specify file patterns to include or exclude in a review using glob patterns"; Greptile: &lt;code&gt;ignorePatterns&lt;/code&gt;, for files that do not need review, "to speed up analysis and reduce noise"; Claude Code Review: in &lt;code&gt;REVIEW.md&lt;/code&gt;, "list paths and finding categories where Claude should skip findings."; Macroscope: &lt;code&gt;.macroscope/ignore.md&lt;/code&gt; "at the repository root, with one glob pattern per line."; GitHub Copilot skips some file types on its own: "If you include these file types in a pull request, Copilot code review will not review the file."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write team rules into the repository&lt;/td&gt;
&lt;td&gt;the reviewer checks your rules, not generic ones&lt;/td&gt;
&lt;td&gt;GitHub Copilot: &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; and path-specific instruction files with &lt;code&gt;applyTo&lt;/code&gt;, where you "Use glob syntax to specify what files or directories the instructions apply to.", and "Custom instructions are enabled for Copilot code review by default"; Codex: a &lt;code&gt;## Code Review Rules&lt;/code&gt; section in &lt;code&gt;AGENTS.md&lt;/code&gt;, with the advice "Start with two or three concise rules that encode checks reviewers often explain." and "Keep formatting, lint, and other deterministic checks out of review rules."; Cursor Bugbot: project rule files &lt;code&gt;.cursor/BUGBOT.md&lt;/code&gt;, and team rules: "Team admins can create rules in Bugbot Automations that apply to all repositories in the team."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Let it learn from what you reject&lt;/td&gt;
&lt;td&gt;repeats less of what the team ignores or turns down&lt;/td&gt;
&lt;td&gt;Greptile: "Greptile learns to eliminate nitpicky comments that distract developers from critical issues by analyzing which suggestions your team actually acts on.", and "Reactions are the fastest way to train Greptile."; CodeRabbit: learnings, "it learns your team's code-review preferences based on chat interactions"; Cursor Bugbot: learned rules, "Rules are generated automatically from your team's activity on GitHub for that repository or by manually backfilling from the history of the repository."; cubic: "cubic uses relevant learnings to find issues and avoid repeating known false positives."; CodeAnt AI: a reply that dismisses a suggestion is saved as "a customized review instruction that prevents similar suggestions in future reviews."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deduplicate and check before posting&lt;/td&gt;
&lt;td&gt;one finding once, the most severe first&lt;/td&gt;
&lt;td&gt;Claude Code Review: "A verification step checks findings against the code before they're reported.", then "the findings that remain are deduplicated and ranked by severity."; cubic, on later pushes: "Only new issues are posted as comments; previously flagged issues are not repeated"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each row says the vendor documents the setting, as read on 5 November 2026; it does not say how well it works on your code.&lt;/p&gt;

&lt;p&gt;Sigma (Mnemoverse, the author's company), a GitHub pull request reviewer, documents three of these levers on its own pages. Its docs say "On request starts reviews only when asked; Automatic can also start them after PR events.", and that P3 findings, "an optional improvement", are "not published inline by default", with at most five verified findings going inline and suspicions no verifier confirmed folded apart as "leads no verifier confirmed, not findings". Sigma runs on Claude Code and OpenAI models.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each lever costs
&lt;/h2&gt;

&lt;p&gt;Every lever trades some noise for some risk, and the vendors name the trade on the same pages. A higher bar and a wide exclusion can hide what matters. Greptile's checklist for missing important issues starts with "Is strictness too high? Try reducing by 1", and Graphite warns: "If an exclusion is written too broadly, then Graphite Agent may not leave valid comments."&lt;/p&gt;

&lt;p&gt;Path filters and repository rules hold only under conditions. Greptile's &lt;code&gt;ignorePatterns&lt;/code&gt; "will only ignore those files during PR review.", and Greptile still indexes those files. Claude Code Review applies path exclusions, lowered severities and nit caps from &lt;code&gt;REVIEW.md&lt;/code&gt; "When a review reads the copy on a protected default branch", and it reads that file from the base or default branch, "never from the pull request's own changes." Macroscope keeps ignored paths out even on a manual request: "Manual review requests do not override ignores."&lt;/p&gt;

&lt;p&gt;A profile or a preset reaches only part of the output. Sourcery says "The profile changes only the inline comments.", and Qodo says "Findings already published on open pull requests are not affected by a preset switch."&lt;/p&gt;

&lt;p&gt;Learning takes time and the right kind of feedback, and at Cursor it counts toward Bugbot usage. Among the steps for a team that still sees too many comments at the highest strictness, Greptile lists "Give the learning system 2-3 weeks to adapt to your reactions". cubic says it learns from what is addressed to it ("cubic only learns from feedback directly addressed to it in comments"), and that short replies such as thanks or done "do not become learnings." Cursor says Bugbot learns from a pull request once it is merged or closed, and "each learning run counts toward Bugbot usage like a review."&lt;/p&gt;

&lt;p&gt;GitHub Copilot handles feedback differently. Where repository settings and policies allow it, Copilot code review draws on Copilot Memory: "Copilot can store useful details it has learned about a repository and use them when reviewing pull requests." Ratings on its comments go to GitHub instead, whose page says "We use this information to improve the product and the quality of Copilot's suggestions.", and on a second review Copilot "may repeat the same comments again, even if they have been dismissed".&lt;/p&gt;

&lt;h2&gt;
  
  
  How to tell whether the noise went down
&lt;/h2&gt;

&lt;p&gt;Count, for each reviewer, how many of its comments the team acted on, before and after one change. Several vendors already put that count on a dashboard. Cursor's rule analytics for Bugbot show, for each rule, "Number of findings your team accepted." and "Percentage of findings that were accepted." Qodo counts a finding as accepted when it "resulted in an accepted code change", and reports "The percentage of findings that were accepted." Greptile shows an addressed rate, "The percentage of Greptile comments on closed or merged pull requests that were addressed", and its advice for a low rate begins "Your rules may be too noisy." Graphite's dashboard shows "Percentage of suggestions that were accepted over time" next to a downvote rate.&lt;/p&gt;

&lt;p&gt;Each vendor defines acceptance its own way, so compare a reviewer with itself over time, not one vendor's rate with another's. Without a dashboard the same count fits in a spreadsheet: for two weeks, mark each comment from each reviewer as acted on or not, change one thing, such as the bar, a path filter or the trigger, and count for two more weeks. If the share of comments the team acts on goes up while the number it acts on holds, the change took out noise and kept the signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;Sources and method: every page below was read on 5 November 2026, each quotation was matched word for word against its page that day, and this text describes the pages as of that date. Related on this account: &lt;a href="https://dev.to/izgorodin/why-does-codex-keep-finding-new-issues-every-time-it-reviews-its-own-code-23kc"&gt;Why does Codex keep finding new issues every time it reviews its own code?&lt;/a&gt;, on review loops and when to stop them, and &lt;a href="https://dev.to/izgorodin/which-ai-is-best-for-code-review-298k"&gt;a comparison of how AI code reviewers describe noise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Projects and GitHub: &lt;a href="https://llvm.org/docs/AIToolPolicy.html" rel="noopener noreferrer"&gt;LLVM AI Tool Use Policy&lt;/a&gt;, &lt;a href="https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md" rel="noopener noreferrer"&gt;Ghostty AI policy&lt;/a&gt;, &lt;a href="https://docs.github.com/en/communities/moderating-comments-and-conversations/managing-disruptive-comments" rel="noopener noreferrer"&gt;managing disruptive comments&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Copilot: &lt;a href="https://docs.github.com/en/copilot/concepts/agent-capabilities/agent-powered-workflows-and-operations/code-review" rel="noopener noreferrer"&gt;code review&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-code-review" rel="noopener noreferrer"&gt;using code review&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/add-custom-instructions/add-repository-instructions" rel="noopener noreferrer"&gt;repository instructions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeRabbit: &lt;a href="https://docs.coderabbit.ai/reference/configuration" rel="noopener noreferrer"&gt;configuration&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/knowledge-base/learnings" rel="noopener noreferrer"&gt;learnings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Greptile: &lt;a href="https://www.greptile.com/docs/code-review/controlling-nitpickiness" rel="noopener noreferrer"&gt;controlling nitpickiness&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/code-review/training-the-learning-system" rel="noopener noreferrer"&gt;training the learning system&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/how-greptile-works/nitpicks" rel="noopener noreferrer"&gt;reducing nitpicks&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/account/analytics" rel="noopener noreferrer"&gt;analytics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cursor: &lt;a href="https://cursor.com/docs/bugbot" rel="noopener noreferrer"&gt;Bugbot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anthropic: &lt;a href="https://code.claude.com/docs/en/code-review" rel="noopener noreferrer"&gt;Code Review&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review-customize" rel="noopener noreferrer"&gt;customizing Code Review&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAI: &lt;a href="https://learn.chatgpt.com/docs/third-party/github" rel="noopener noreferrer"&gt;Codex code review in GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Qodo: &lt;a href="https://docs.qodo.ai/configuration/review-presets" rel="noopener noreferrer"&gt;review presets&lt;/a&gt;, &lt;a href="https://docs.qodo.ai/governance/code-review-analytics" rel="noopener noreferrer"&gt;code review analytics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sourcery: &lt;a href="https://docs.sourcery.ai/reviews/configure/" rel="noopener noreferrer"&gt;review settings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Devin: &lt;a href="https://docs.devin.ai/work-with-devin/devin-review" rel="noopener noreferrer"&gt;Devin Review&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Graphite: &lt;a href="https://graphite.com/docs/ai-review-customization" rel="noopener noreferrer"&gt;customization&lt;/a&gt;, &lt;a href="https://graphite.com/docs/ai-review-comments" rel="noopener noreferrer"&gt;review comments&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;cubic: &lt;a href="https://docs.cubic.dev/ai-review/memory-and-learning" rel="noopener noreferrer"&gt;memory and learning&lt;/a&gt;, &lt;a href="https://docs.cubic.dev/ai-review/ai-review-settings" rel="noopener noreferrer"&gt;review settings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeAnt AI: &lt;a href="https://docs.codeant.ai/pull_request/features/learnings" rel="noopener noreferrer"&gt;learnings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Macroscope: &lt;a href="https://docs.macroscope.com/code-review/ignore-files" rel="noopener noreferrer"&gt;ignore files&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sigma: &lt;a href="https://sigma.mnemoverse.com/docs?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=reduce-llm-spam-pr-reviews" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, &lt;a href="https://sigma.mnemoverse.com/docs/reading-a-review?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=reduce-llm-spam-pr-reviews" rel="noopener noreferrer"&gt;reading a review&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>github</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How do I make sure Copilot review is completed before PR can be auto merged?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Fri, 06 Nov 2026 11:52:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/how-do-i-make-sure-copilot-review-is-completed-before-pr-can-be-auto-merged-3kjh</link>
      <guid>https://dev.to/izgorodin/how-do-i-make-sure-copilot-review-is-completed-before-pr-can-be-auto-merged-3kjh</guid>
      <description>&lt;p&gt;Auto-merge waits only for what the branch rule requires, as GitHub puts it: "Auto-merge merges a pull request automatically after all required reviews and status checks pass." Copilot approvals left public preview on 28 October 2026: a Copilot approval can count as one of the required approvals, off by default, turned on by admins, optionally only for listed file paths. The rule counts approvals, not whose they are, so when two people approve while Copilot is still reviewing, as in this question, the pull request merges the same way with approvals on. Waiting for the review itself takes a required status check: Claude Code Review, CodeRabbit and Cursor Bugbot each document one of their own that a branch rule can require. The path GitHub documents for Copilot is the approval.&lt;/p&gt;

&lt;p&gt;Every fact below comes from each vendor's own pages as I read them on 5 November 2026, and none of them saw this text before publication.&lt;/p&gt;

&lt;h2&gt;
  
  
  What auto-merge actually waits for
&lt;/h2&gt;

&lt;p&gt;A branch rule, in a ruleset or in classic branch protection, gives auto-merge two kinds of requirement. Required reviews are a count: administrators "can require that all pull requests receive a specific number of approving reviews before someone merges the pull request into a protected branch", and those approvals can come "from people with write permissions in the repository or from a designated code owner". Required status checks are names: "After enabling required status checks, all required status checks must pass before collaborators can merge changes into the protected branch."&lt;/p&gt;

&lt;p&gt;A required check passes when it ends as success, skipped or neutral, and only on the newest commit: "Required checks must pass on the latest commit SHA. Checks from earlier commits don't satisfy the requirement." The rule can also tie a check to the app that posts it: "When you add a required status check, you can select an app that has recently set this check as the expected source of status updates." GitHub's troubleshooting page adds: "A required status check must have completed successfully in the chosen repository during the past seven days."&lt;/p&gt;

&lt;p&gt;GitHub describes &lt;strong&gt;Require conversation resolution before merging&lt;/strong&gt; in one line: "Requires all comments on the pull request to be resolved before it can be merged to a protected branch." That covers threads a reviewer has already opened, not a review that is still running.&lt;/p&gt;

&lt;p&gt;Agent Merge, announced in GitHub's changelog of 28 October 2026, is about getting a pull request to meet the rule. GitHub's auto-merge page says Copilot can fix failed GitHub Actions workflows and merge conflicts before auto-merge completes, and "Agent Merge fixes the blockers you select, while auto-merge waits for all merge requirements to be met." The Agent Merge page adds that it is a separate switch: "Enabling Agent Merge does not enable auto-merge." Whatever the rule does not require, auto-merge does not wait for.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make auto-merge wait for a Copilot approval
&lt;/h2&gt;

&lt;p&gt;These are GitHub's steps for letting a Copilot approval count toward the rule, which the next section separates from waiting for Copilot. Approvals work when they are enabled "in repository, organization, and enterprise settings", so the steps start at the top.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise and organization.&lt;/strong&gt; In the enterprise's &lt;strong&gt;AI controls&lt;/strong&gt;, the policy next to "Allow Copilot to approve pull requests" defaults to &lt;strong&gt;Disabled everywhere&lt;/strong&gt;: "Organizations cannot enable Copilot approvals. This is the default." The other choices are &lt;strong&gt;Let organizations decide&lt;/strong&gt; and &lt;strong&gt;Enable for selected organizations&lt;/strong&gt;. In the organization's Copilot code review settings, next to "Count Copilot approvals toward merge requirements", the choices are &lt;strong&gt;Enabled everywhere&lt;/strong&gt;, &lt;strong&gt;Let repositories decide&lt;/strong&gt;, &lt;strong&gt;Enable for selected repositories&lt;/strong&gt; and &lt;strong&gt;Disabled everywhere&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository.&lt;/strong&gt; In &lt;strong&gt;Settings&lt;/strong&gt;, &lt;strong&gt;Copilot&lt;/strong&gt;, &lt;strong&gt;Code review&lt;/strong&gt;, under &lt;strong&gt;Auto-approval&lt;/strong&gt;, turn on &lt;strong&gt;Allow Copilot to approve pull requests&lt;/strong&gt; and &lt;strong&gt;Allow Copilot approvals to count toward merge requirements&lt;/strong&gt;, which GitHub describes as "Toggle on so Copilot approvals can satisfy pull request approval requirements." &lt;strong&gt;File paths&lt;/strong&gt; is optional: it takes "one file glob per line", counts approvals "only on pull requests where every changed file matches one of the globs", and "Up to 15 globs are supported."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branch rule.&lt;/strong&gt; Require a pull request with at least one approval: in a ruleset the rule is &lt;strong&gt;Require a pull request before merging&lt;/strong&gt;, in classic branch protection &lt;strong&gt;Require pull request reviews before merging&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A review on every push.&lt;/strong&gt; In the ruleset, under &lt;strong&gt;Branch rules&lt;/strong&gt;, select &lt;strong&gt;Automatically request Copilot code review&lt;/strong&gt; and &lt;strong&gt;Review new pushes&lt;/strong&gt;. A new commit takes the approval away: "If new commits are pushed after Copilot approves, the approval is dismissed, and you can re-request a review." Without &lt;strong&gt;Review new pushes&lt;/strong&gt;, "Copilot will only review the pull request once."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull request.&lt;/strong&gt; Auto-merge has to be allowed for the repository first ("Before you use auto-merge, it must be enabled for the repository."). On the pull request, click &lt;strong&gt;Enable auto-merge&lt;/strong&gt;, then &lt;strong&gt;Confirm auto-merge&lt;/strong&gt;; "The option to enable auto-merge is shown only on pull requests that cannot be merged immediately."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each Copilot review also carries an assessment of whether the pull request is "ready to approve", and that line holds nothing by itself: "On its own, this assessment does not count toward merge requirements."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why that still does not guarantee Copilot finished
&lt;/h2&gt;

&lt;p&gt;GitHub describes a Copilot approval as interchangeable with a person's. It satisfies the required-approval rule "the same way a teammate's approval would", and the changelog of 28 October 2026 says "Copilot's approval behaves like a human reviewer's approval." Whichever approvals arrive first close the rule, so if two people approve while Copilot is still reviewing, auto-merge has nothing left to wait for unless a required check is still pending. CodeRabbit's docs say the same about GitHub's approval count in general, "A required approval count does not say who must approve.", and about its own approval, "Two people can also approve the pull request without waiting for CodeRabbit."&lt;/p&gt;

&lt;p&gt;Without approvals turned on, a Copilot review takes no part in the count at all: by default Copilot leaves a Comment review, not an Approve or a Request changes review. &lt;strong&gt;Require conversation resolution before merging&lt;/strong&gt; still holds the merge on Copilot's open threads, since "Copilot's review comments behave like review comments from humans.", but only once Copilot has posted them.&lt;/p&gt;

&lt;p&gt;A status check posted by Copilot code review, and a setting that requires Copilot's review in particular before a merge, are not found on GitHub's pages about Copilot code review, configuring it, using it, and the available ruleset rules, as of 5 November 2026. On those pages the way into a merge requirement is the approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  How other reviewers make the merge wait
&lt;/h2&gt;

&lt;p&gt;The table puts Copilot code review next to reviewers whose docs say what a required rule does with their check.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Reviewer&lt;/th&gt;
&lt;th&gt;What it posts on the pull request&lt;/th&gt;
&lt;th&gt;What a required rule can wait for, in its docs&lt;/th&gt;
&lt;th&gt;What it does not guarantee, in its docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot code review&lt;/td&gt;
&lt;td&gt;a review: a Comment review by default, or an approving review when approvals are on&lt;/td&gt;
&lt;td&gt;an approving review, which counts "the same way a teammate's approval would"&lt;/td&gt;
&lt;td&gt;that Copilot is among the approvers; new commits dismiss its approval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code Review (Anthropic)&lt;/td&gt;
&lt;td&gt;inline findings, a summary and a check run named Claude Code Review&lt;/td&gt;
&lt;td&gt;the check run, which "never concludes as a failure, so a finished review doesn't fail a required check"&lt;/td&gt;
&lt;td&gt;that findings are dealt with: "You can merge without responding to a finding, unless your repository's own rules require it."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;a check run named &lt;code&gt;CodeRabbit&lt;/code&gt;, since 27 October 2026, and a review&lt;/td&gt;
&lt;td&gt;the &lt;code&gt;CodeRabbit&lt;/code&gt; check: "A required check blocks merging until the review ends."&lt;/td&gt;
&lt;td&gt;that every pass had a review: "It does not block skipped or rate-limited reviews."; "No setting guarantees that CodeRabbit reviews every pull request before it merges."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor Bugbot&lt;/td&gt;
&lt;td&gt;a status for each review run, a check named &lt;code&gt;Cursor Bugbot&lt;/code&gt; on GitHub&lt;/td&gt;
&lt;td&gt;the Bugbot check, required "to make sure Bugbot runs before merge"&lt;/td&gt;
&lt;td&gt;that findings hold the merge: requiring the status alone "does not block merges on findings", because findings default to neutral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sigma (Mnemoverse, the author's company)&lt;/td&gt;
&lt;td&gt;"a neutral check per reviewer on the head commit, which tracks the run, and a review with the findings"&lt;/td&gt;
&lt;td&gt;its docs: "The check is never a merge gate; its conclusion is always neutral."&lt;/td&gt;
&lt;td&gt;a verdict: where the repository's verdict setting is exposed, Rules "can add one separate, deterministic Approve or Request changes review."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At Claude Code Review, when a command that starts a review is accepted, the check run appears with the title "Code review queued..." and switches to "Code review in progress..." when the review starts; at the end, "The check run concludes as neutral, or as skipped after some pushes that change no files and keep the earlier result." By GitHub's rule a required check passes only as success, skipped or neutral, and by Anthropic's page this one never ends as a failure; read together, a required Claude Code Review check holds the merge while the review is queued or running and lets it through when the review ends, with or without findings. The same page mentions check runs "for a review that failed, timed out, was canceled, or was superseded by a newer one", and since the check never concludes as a failure, a required Claude Code Review check also lets the merge through after a review that failed or timed out. To stop a merge on findings, Anthropic's docs point to your own CI, which reads the severity counts from the last line of the check's Details text with gh and jq. With &lt;strong&gt;After every push&lt;/strong&gt; under &lt;strong&gt;Review runs&lt;/strong&gt;, "a review runs on pushes to the pull request branch".&lt;/p&gt;

&lt;p&gt;CodeRabbit's changelog of 27 October 2026: "The review status on GitHub is now a CodeRabbit check run." Its status check page says "Branch rules can require it before a pull request merges." and is plain about the gaps: a skipped or rate-limited review "counts as passing for a required check, but no review happened", and in a merge queue CodeRabbit reports a successful check on the queue's commit, while "CodeRabbit does not review that commit." By default a failed review ends neutral and passes; the page's strongest setup sets &lt;code&gt;reviews.fail_commit_status&lt;/code&gt; to true, "so a failed review blocks merging". Its advice for the rest: "To make sure people review what CodeRabbit skipped, also require human approvals." Automatic Approvals, "off by default", make CodeRabbit approve once its feedback is resolved and it has reviewed the latest commit, and "When a review leaves actionable comments, CodeRabbit requests changes."&lt;/p&gt;

&lt;p&gt;Cursor's docs say "Bugbot publishes a status for each review run." and "If you use branch protection, require the Bugbot check or build status to make sure Bugbot runs before merge." The status is neutral when Bugbot found issues, and also when "the run was cancelled by a newer commit, or Bugbot hit an internal error"; GitHub counts neutral as passing, so a required Bugbot check lets the merge through after findings and after an internal error. A failing status takes one more setting: "If fail-on-unresolved-issues behavior is available for your organization, enable it to make unresolved findings produce a failing status."&lt;/p&gt;

&lt;p&gt;Sigma runs on Claude Code and OpenAI models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which setup fits which goal
&lt;/h2&gt;

&lt;p&gt;If the review has to finish before the merge, require that reviewer's own check in the branch rule and let it review every push, since GitHub counts only checks on the newest commit. If an AI approval should be able to close the rule, that is the path of Copilot approvals, or of CodeRabbit's Automatic Approvals. If a person has to approve, the count alone does not ensure it once any bot's approval can fill a slot. For a review from a specific team, CodeRabbit's docs point to code owners with &lt;strong&gt;Require review from Code Owners&lt;/strong&gt; turned on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;Sources and method: every page below was read on 5 November 2026, each quotation was matched word for word against its page that day, and this text describes the pages as of that date. Switching Copilot's automatic review off, instead of waiting for it, is covered in &lt;a href="https://dev.to/izgorodin/how-to-disable-copilot-code-review-in-github-56g3"&gt;How to disable Copilot code review in GitHub?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/automatically-merging-a-pull-request" rel="noopener noreferrer"&gt;auto-merge&lt;/a&gt;, &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches" rel="noopener noreferrer"&gt;protected branches&lt;/a&gt;, &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets" rel="noopener noreferrer"&gt;ruleset rules&lt;/a&gt;, &lt;a href="https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks" rel="noopener noreferrer"&gt;required status checks&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/concepts/agent-capabilities/agent-powered-workflows-and-operations/code-review" rel="noopener noreferrer"&gt;Copilot code review&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/set-up-copilot/configure-code-review" rel="noopener noreferrer"&gt;configuring it&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-code-review" rel="noopener noreferrer"&gt;using it&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/use-copilot-agents/get-pull-requests-ready-to-merge" rel="noopener noreferrer"&gt;Agent Merge&lt;/a&gt;, &lt;a href="https://github.blog/changelog/2026-10-28-copilot-code-review-merge-with-confidence-with-max-and-approvals/" rel="noopener noreferrer"&gt;Copilot approvals, 28 October 2026&lt;/a&gt;, &lt;a href="https://github.blog/changelog/2026-10-28-agent-merge-watches-and-fixes-pull-requests-in-the-cloud/" rel="noopener noreferrer"&gt;Agent Merge, 28 October 2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anthropic: &lt;a href="https://code.claude.com/docs/en/code-review" rel="noopener noreferrer"&gt;Code Review&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review-pull-requests" rel="noopener noreferrer"&gt;Code Review on pull requests&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review-setup" rel="noopener noreferrer"&gt;setting it up&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodeRabbit: &lt;a href="https://docs.coderabbit.ai/changelog" rel="noopener noreferrer"&gt;changelog&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/pr-reviews/status-check" rel="noopener noreferrer"&gt;status check&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/pr-reviews/approval-policies" rel="noopener noreferrer"&gt;approval policies&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/pr-reviews/automatic-approvals" rel="noopener noreferrer"&gt;Automatic Approvals&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cursor: &lt;a href="https://cursor.com/docs/bugbot" rel="noopener noreferrer"&gt;Bugbot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sigma: &lt;a href="https://sigma.mnemoverse.com/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=copilot-review-before-auto-merge" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://sigma.mnemoverse.com/docs/reading-a-review?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=copilot-review-before-auto-merge" rel="noopener noreferrer"&gt;reading a review&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubcopilot</category>
      <category>codereview</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to store agent states across restarts?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Wed, 04 Nov 2026 12:54:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/how-to-store-agent-states-across-restarts-52oi</link>
      <guid>https://dev.to/izgorodin/how-to-store-agent-states-across-restarts-52oi</guid>
      <description>&lt;p&gt;Adam Lewis framed the practical problem in a dev.to comment on 30 September 2026: "Where does the halfway state live when you close the terminal, is it in the message list or reconstructed from the repo each time it starts?" He then identified the difficult part: "saving the transcript is easy and the plan the agent was carrying is hard. If the plan is implied by the files it has already touched, restarting is re-deriving it." (&lt;a href="https://dev.to/nark3d/comment/3g5d5"&gt;comment&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Store four kinds of state separately. Run state goes in a database-backed framework checkpointer or session service, the current plan goes explicitly inside that state, tool calls in flight get an outcome status and an idempotency key derived from stable intent, and learned memory lives outside the individual run.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A restart must preserve four things: run state, the agent's current plan, tool calls in flight, and what the agent learned. In the LangGraph, Google ADK, and OpenAI Agents SDK documentation read on 2 November 2026, the in-memory storage option loses state at restart, while each framework documents a persistent alternative.&lt;/li&gt;
&lt;li&gt;An operation that started but did not report completion has an unknown outcome. It should not be retried blindly or allowed to block later work. Changes in Codex and Hy-Memory separated that condition from ordinary retryable failure in October 2026.&lt;/li&gt;
&lt;li&gt;A retry is safe only when the called service enforces an idempotency key derived from stable intent. ADK says resumed tools run "at least once" and may run more than once.&lt;/li&gt;
&lt;li&gt;Run state belongs in the framework's persistent execution facility. Learned memory belongs outside one run. LangGraph documents these as separate systems: checkpointers persist graph state, while stores hold application-defined data outside it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Mnemoverse (the author's company) makes a memory layer of the kind described in the section on what an agent learned.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does an agent have to keep across a restart?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Run state is the durable record of where one execution is, including the data needed to continue it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A checkpoint is a persisted snapshot of run state from which execution can continue or replay.&lt;/strong&gt; LangGraph describes the mechanism directly: "Checkpointers persist a thread's graph state as checkpoints." (&lt;a href="https://docs.langchain.com/oss/python/langgraph/persistence" rel="noopener noreferrer"&gt;source&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A side effect is an externally visible change caused by a tool call, such as sending a message or writing to another service.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An unknown outcome is a call state in which the agent knows an operation started but cannot tell whether its side effect committed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An idempotency key is a stable operation identifier that the called service checks to prevent the same intended effect from being applied twice.&lt;/strong&gt; Temporal notes that such protection is enforced by the called service, "not by the Activity itself." (&lt;a href="https://docs.temporal.io/activity-definition" rel="noopener noreferrer"&gt;source&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learned memory is information retained for later threads or sessions rather than for continuing one current execution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These records answer different recovery questions: where execution should continue, what plan the agent was following, which external actions completed, failed or remain uncertain, and what the agent should still know in a later session.&lt;/p&gt;

&lt;p&gt;A Hugging Face forum question from 2 January 2026 asked whether developers "struggle with preserving deterministic agent state across restarts?" (&lt;a href="https://discuss.huggingface.co/t/how-do-you-preserve-agent-state-across-restarts/172174" rel="noopener noreferrer"&gt;thread&lt;/a&gt;). The difficulty is not one missing database. It is the need to represent each state explicitly.&lt;/p&gt;

&lt;p&gt;If the agent is a coding tool you use rather than one you build, see &lt;a href="https://mnemoverse.com/docs/library/what-survives-when-ai-agents-restart" rel="noopener noreferrer"&gt;What survives when AI agents restart?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistent agent state APIs: where do LangGraph, ADK and the OpenAI Agents SDK keep run state?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework and documentation&lt;/th&gt;
&lt;th&gt;What in-memory storage loses at restart&lt;/th&gt;
&lt;th&gt;Documented persistent facility&lt;/th&gt;
&lt;th&gt;What else matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Google ADK&lt;/strong&gt;, read 2 November 2026&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;InMemorySessionService&lt;/code&gt;: "All conversation data is lost if the application restarts." &lt;code&gt;InMemoryMemoryService&lt;/code&gt;: "None, data is lost on restart".&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;DatabaseSessionService&lt;/code&gt;: "Data survives application restarts."&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;temp:&lt;/code&gt; state is discarded after an invocation. &lt;code&gt;user:&lt;/code&gt; and &lt;code&gt;app:&lt;/code&gt; state stored in memory is lost at restart. Resume is available in ADK Python 1.16 and higher, reinstates completed events, and continues from partially completed state. Resume is not supported by default for Custom Agents. (&lt;a href="https://adk.dev/sessions/session/" rel="noopener noreferrer"&gt;session&lt;/a&gt;, &lt;a href="https://adk.dev/sessions/memory/" rel="noopener noreferrer"&gt;memory&lt;/a&gt;, &lt;a href="https://adk.dev/sessions/state/" rel="noopener noreferrer"&gt;state&lt;/a&gt;, &lt;a href="https://adk.dev/runtime/resume/" rel="noopener noreferrer"&gt;resume&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;LangGraph&lt;/strong&gt;, read 2 November 2026&lt;/td&gt;
&lt;td&gt;"MemorySaver and InMemorySaver store checkpoints in RAM. When the process restarts, all checkpoints are lost."&lt;/td&gt;
&lt;td&gt;A database-backed checkpointer for run state and a database-backed store for cross-thread data.&lt;/td&gt;
&lt;td&gt;A checkpointer saves graph state at each super-step. Cooperative shutdown can finish the current super-step and save a resumable checkpoint. A node already running finishes before draining takes effect. (&lt;a href="https://docs.langchain.com/oss/python/langgraph/persistence" rel="noopener noreferrer"&gt;persistence&lt;/a&gt;, &lt;a href="https://docs.langchain.com/oss/python/langgraph/add-memory" rel="noopener noreferrer"&gt;memory&lt;/a&gt;, &lt;a href="https://docs.langchain.com/oss/python/langgraph/fault-tolerance" rel="noopener noreferrer"&gt;fault tolerance&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;OpenAI Agents SDK&lt;/strong&gt;, read 2 November 2026&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;SQLiteSession&lt;/code&gt; without a file path uses an "In-memory database (lost when process ends)".&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;SQLiteSession&lt;/code&gt; with a file uses a "Persistent file-based database". A suspended run can be represented by durable &lt;code&gt;RunState&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;Serialized &lt;code&gt;RunState&lt;/code&gt; includes approval decisions, pending tool calls, and tool arguments. The documentation says loading does "not authenticate the snapshot or the person submitting it." (&lt;a href="https://openai.github.io/openai-agents-python/sessions/" rel="noopener noreferrer"&gt;sessions&lt;/a&gt;, &lt;a href="https://openai.github.io/openai-agents-python/human_in_the_loop/" rel="noopener noreferrer"&gt;human in the loop&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;From each framework's own documentation, read on 2 November 2026. Examples, not a full list of backends. The row order is alphabetical, not evaluative.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anis Meziani described the operational default in his own ADK-based system: "And if you don't configure where sessions live, ADK falls back to an in-memory session service." In a later comment he wrote that ADK has three in-memory defaults, covering sessions, long-term memory, and artifacts; that is his reading, not an independent claim here about every ADK facility (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/amnesia-and-deja-vu-how-our-ai-agents-failed-after-every-restart-and-how-we-fixed-it-5c80"&gt;article&lt;/a&gt;, &lt;a href="https://dev.to/anis_meziani_52aab42304a8/comment/3ho4b"&gt;comment&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is saving the conversation not enough to resume an agent?
&lt;/h2&gt;

&lt;p&gt;A persistent conversation database solves only part of recovery. Meziani put the boundary plainly: "Postgres alone doesn't save the half-finished task. It saves the conversation. The run that was in flight still dies with the pod." (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/comment/3ho4b"&gt;comment&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;A conventional workflow can resume from a named step because its control path is explicit. An agent may choose its next action from model output and current context. Meziani wrote, "With an LLM agent, there is no step 3." Max Quimby made the related point that "you can't cleanly resume a non-deterministic trajectory" (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/amnesia-and-deja-vu-how-our-ai-agents-failed-after-every-restart-and-how-we-fixed-it-5c80"&gt;article&lt;/a&gt;, &lt;a href="https://dev.to/max_quimby/comment/3hkoa"&gt;comment&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The practical response is to persist the plan explicitly. Record the current objective, completed step identifiers, pending branches, and required inputs in run state, and update that record at each durable boundary. ADK's guidance for resumable custom logic says to "generate and save the agent state for each completed step of the agent's overall task." (&lt;a href="https://adk.dev/runtime/resume/" rel="noopener noreferrer"&gt;source&lt;/a&gt;) Do not put a resumable plan in ADK &lt;code&gt;temp:&lt;/code&gt; state. ADK says that state is "Discarded after the invocation completes and does not carry over to the next one." (&lt;a href="https://adk.dev/sessions/state/" rel="noopener noreferrer"&gt;source&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Without the original input and an explicit plan, recovery has to infer intent from the transcript and observed effects. Meziani summarized his own incident: "What was missing wasn't observability. It was the input." (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/amnesia-and-deja-vu-how-our-ai-agents-failed-after-every-restart-and-how-we-fixed-it-5c80"&gt;source&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens to a tool call that was running when the agent restarted?
&lt;/h2&gt;

&lt;p&gt;The dangerous interval is after the external service commits but before the agent records success.&lt;/p&gt;

&lt;p&gt;Temporal gives a direct example: "The Activity function completes successfully, but the Worker crashes just before it notifies the Temporal Service." The event history then lacks completion, "so the Activity will be retried." Completed activities do not execute again during workflow replay, and failed workflow execution continues from the last recorded event (&lt;a href="https://docs.temporal.io/activity-definition" rel="noopener noreferrer"&gt;activity definition&lt;/a&gt;, &lt;a href="https://docs.temporal.io/workflow-execution" rel="noopener noreferrer"&gt;workflow execution&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;LangGraph documents a related boundary at graph-node level. If one node fails during a super-step, pending writes from other nodes that completed successfully are stored, and resuming that super-step does not rerun those successful nodes. Replay from an earlier checkpoint re-executes later nodes, "including any LLM calls, API requests, or interrupts". LangGraph also records failure provenance (&lt;a href="https://docs.langchain.com/oss/python/langgraph/checkpointers" rel="noopener noreferrer"&gt;checkpointers&lt;/a&gt;, &lt;a href="https://docs.langchain.com/oss/python/langgraph/fault-tolerance" rel="noopener noreferrer"&gt;fault tolerance&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;ADK states that Resume runs tools "at least once, and may run more than once when resuming a workflow." It tells developers whose tools can cause harmful duplicates to make the tool check for and prevent them (&lt;a href="https://adk.dev/runtime/resume/" rel="noopener noreferrer"&gt;source&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Meziani's system records invocation rather than waiting for a response: "We count the call, not the response." Its &lt;code&gt;tools_executed&lt;/code&gt; field distinguishes no call, confirmed calls, and uncertain calls. He treats an uncertain call as "probably something" because the cost of the two errors differs: "Refusing a safe relaunch costs a click. Approving an unsafe one costs a duplicate email to a customer." (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/amnesia-and-deja-vu-how-our-ai-agents-failed-after-every-restart-and-how-we-fixed-it-5c80"&gt;Fix 7&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Changes in two projects in October 2026 show how that status becomes operational:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On 16 October, &lt;a href="https://github.com/openai/codex/pull/54664" rel="noopener noreferrer"&gt;Codex PR #54664&lt;/a&gt; distinguished transient errors "known to be safe to retry" from writes "that may already have committed". It also states: "Recovery remains the operation owner's responsibility; neither category automatically triggers retries."&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://github.com/Tencent-Hunyuan/Hy-Memory/issues/24" rel="noopener noreferrer"&gt;Hy-Memory issue&lt;/a&gt; opened on 17 October described extraction tasks left as &lt;code&gt;unknown&lt;/code&gt; after a network interruption. The reporter expected the endpoint's &lt;code&gt;backlog_pending&lt;/code&gt; value to match the database and reported reinstallation as the only recovery they had found. A maintainer linked &lt;a href="https://github.com/Tencent-Hunyuan/Hy-Memory/pull/27" rel="noopener noreferrer"&gt;PR #27&lt;/a&gt; and closed the issue that day.&lt;/li&gt;
&lt;li&gt;PR #27 preserved unknown rows for reconciliation so one uncertain write would not freeze later writes from the same source. It retried an unresolved first attempt once after reconciliation, then parked a second unknown result for explicit recovery. The PR says: "This does not blindly treat unknown as definitely unsent."&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Tencent-Hunyuan/Hy-Memory/pull/63" rel="noopener noreferrer"&gt;Hy-Memory PR #63&lt;/a&gt;, merged on 18 October, separated waiting for model activation from timed retry. Its prior path returned the backlog to pending every minute without attempting a provider call. The change readmitted those rows after successful activation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A durable write record therefore needs at least four states: completed, safe to retry, outcome unknown, and waiting for an event. Each needs a separate recovery branch. A queue counter that cannot represent unknown work can look empty while progress has stopped.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I make a retried step safe to run twice?
&lt;/h2&gt;

&lt;p&gt;Temporal recommends idempotent activities. Its suggested key combines Workflow Run ID and Activity ID because that pair remains stable across retry attempts while differing between workflow executions (&lt;a href="https://docs.temporal.io/activity-definition" rel="noopener noreferrer"&gt;source&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The key must identify intent, not whichever arguments the model generated this time. &lt;a href="https://dev.to/max_quimby/comment/3hkoa"&gt;Quimby described&lt;/a&gt; effectful tools that compute a key from arguments. Meziani identified the failure mode: "a key hashed from the args breaks when the LLM rewrites them on replay. The key has to come from stable intent, never from generated content." He cited provider message identity, a content digest for dataset imports, and human approval for outbound campaigns as examples from his system (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/comment/3hl0c"&gt;discussion&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A forum respondent described another useful pattern: "I store the outputs of anything nondeterministic, like tool calls and external requests, so a replay reads the stored result rather than calling the outside world again." The same system gives each step an identifier so retries do not duplicate side effects (&lt;a href="https://discuss.huggingface.co/t/how-do-you-preserve-agent-state-across-restarts/172174" rel="noopener noreferrer"&gt;thread&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Retries can also hide inside transport code. Meziani reported that the ApowerB runtime built on ADK resent the same request after a 429 up to twice without checking whether a streamed function call had already passed. This describes ApowerB code, not ADK behavior. His resulting rule was: "once a call has passed, forward the 429 and let a human decide." The author of this article suggested that the forwarded error could identify calls already completed in that turn (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/comment/3hl0g"&gt;Meziani&lt;/a&gt;, &lt;a href="https://dev.to/izgorodin/comment/3hn8k"&gt;Izgorodin&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Meziani also names the boundary of his approach: "A replay is a new run that cites the original". His system did not yet provide true mid-flight resume that reused completed tool results (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/amnesia-and-deja-vu-how-our-ai-agents-failed-after-every-restart-and-how-we-fixed-it-5c80"&gt;source&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Where should what the agent learned live?
&lt;/h2&gt;

&lt;p&gt;Learned information should survive beyond one execution. It should not depend on whether a particular run remains resumable.&lt;/p&gt;

&lt;p&gt;LangGraph separates these responsibilities: "Stores persist application-defined data outside the graph state." It recommends stores for "long-term, cross-thread memory, including user preferences, facts, and shared knowledge", with a database-backed store for production (&lt;a href="https://docs.langchain.com/oss/python/langgraph/persistence" rel="noopener noreferrer"&gt;persistence&lt;/a&gt;, &lt;a href="https://docs.langchain.com/oss/python/langgraph/add-memory" rel="noopener noreferrer"&gt;memory&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;ADK likewise distinguishes sessions, state, and memory. Its in-memory memory service loses data at restart, and state with &lt;code&gt;user:&lt;/code&gt; or &lt;code&gt;app:&lt;/code&gt; scope, which can span conversations, is lost at restart when its in-memory service holds it (&lt;a href="https://adk.dev/sessions/memory/" rel="noopener noreferrer"&gt;memory&lt;/a&gt;, &lt;a href="https://adk.dev/sessions/state/" rel="noopener noreferrer"&gt;state&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;An external memory layer is another option. Mnemoverse is one example for learned memory. Its REST &lt;a href="https://mnemoverse.com/docs/api/reference#post-memory-write" rel="noopener noreferrer"&gt;&lt;code&gt;POST /memory/write&lt;/code&gt;&lt;/a&gt; accepts an &lt;code&gt;external_ref&lt;/code&gt;, described as a client-provided unique reference for idempotent writes. A write that reuses one is answered with &lt;code&gt;409 CONFLICT&lt;/code&gt;, and the reference can be looked up to recover an atom identifier after restart. The documented &lt;code&gt;/memory/write-batch&lt;/code&gt; route accepts an &lt;code&gt;Idempotency-Key&lt;/code&gt;; retrying with the same key after a dropped response returns the cached response instead of writing the batch twice. An &lt;code&gt;external_ref&lt;/code&gt; derived from stable intent, such as a decision and its date rather than model-generated wording, applies the same rule used for effectful tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes when the code is upgraded between the crash and the restart?
&lt;/h2&gt;

&lt;p&gt;A stored execution may outlive the code that created it. ADK gives a direct warning: "Do not modify a stopped agent workflow before resuming it." (&lt;a href="https://adk.dev/runtime/resume/" rel="noopener noreferrer"&gt;source&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Schema compatibility needs the same attention. Debashish Ghosal, replying to the author of this article about his own recovery guard, wrote: "So the guard is build-vs-manifest, and the restore path never reads alembic_version from the target DB." He agreed that the rolling deployment window is the gap, because an old pod could restore into a database one revision ahead (&lt;a href="https://dev.to/debashish_ghosal/comment/3i7ok"&gt;comment&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A recovery check should compare checkpoint metadata with the database and schema into which it will restore, not only with the application build. During a rollout, old and new processes may write the same durable state. Compatibility rules must cover that overlap.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I test that agent state survives a restart?
&lt;/h2&gt;

&lt;p&gt;Treat restart recovery as a fault-injection test, not as a database connectivity check.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Kill the process during an effectful tool call.&lt;/strong&gt; Restart it and verify that the external effect exists once. Confirm that the call is recorded as completed or unknown rather than silently repeated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kill the process between plan steps.&lt;/strong&gt; Verify that execution continues from the recorded step and plan. It should not infer a fresh trajectory solely from the transcript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write a user preference, then start a new thread after restart.&lt;/strong&gt; Verify that cross-session memory still contains the preference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run a negative control with the documented in-memory option.&lt;/strong&gt; It should lose state. If it does not, the test may be exercising an unintended persistent component.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Meziani proposes the same basic fault injection in his own walkthrough: "kill the container mid-run, restart it, and watch the session come back." (&lt;a href="https://dev.to/anis_meziani_52aab42304a8/amnesia-and-deja-vu-how-our-ai-agents-failed-after-every-restart-and-how-we-fixed-it-5c80"&gt;source&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article does not claim
&lt;/h2&gt;

&lt;p&gt;No performance figure is given for any framework or product. The frameworks in the table are examples, and only their own documentation is quoted, as read on 2 November 2026. This article tests none of them. Practitioners' accounts describe their own systems and code. The four recovery tests are proposals, not a description of any team's test suite.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Every quotation was read on 2 November 2026 with two instruments, a browser-like request and a reader service with its cache off (dev.to comments and the article also through the dev.to API, the GitHub pull requests and the issue also through the GitHub API); a made-up address on each host answered 404 as a control. The text describes those pages as of that date. A longer version, with the common questions and the full list of sources, is in the Mnemoverse documentation library: &lt;a href="https://mnemoverse.com/docs/library/store-agent-state-across-restarts" rel="noopener noreferrer"&gt;How to store agent states across restarts?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-11-02&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Tue, 03 Nov 2026 12:15:26 +0000</pubDate>
      <link>https://dev.to/izgorodin/can-a-user-retrieve-information-outside-their-permissions-including-through-the-lexical-search-115m</link>
      <guid>https://dev.to/izgorodin/can-a-user-retrieve-information-outside-their-permissions-including-through-the-lexical-search-115m</guid>
      <description>&lt;p&gt;Jeevan Srivastava asked this question word for word in a &lt;a href="https://medium.com/@thejeevan/building-production-rag-retrieval-quality-privacy-and-engineering-trade-offs-33bab4384dda" rel="noopener noreferrer"&gt;Medium article of 18 October 2026&lt;/a&gt;, as one of three dimensions he would assess for a production system, beside retrieval quality and operational performance. He labels his access-control design: "These are proposed production design decisions, not features I'm claiming to have implemented as part of my retrieval fix."&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yes, through any read path the permission check does not cover. The question names three: the lexical branch of a hybrid search, filtered differently from the vector branch; a cache that answers before the check runs; and indirect references, such as a fetch by ID or exact name, a pointer to a hidden record, or a scope value supplied by the request or the model.&lt;/li&gt;
&lt;li&gt;One rule addresses all three: the server derives the read scope from the verified caller identity and applies one filter on every path that can return stored content. For the model's part, the Databricks agent memory documentation says of the actor_id that scopes every read: "Never let the model choose it."&lt;/li&gt;
&lt;li&gt;Three probes, run as a user without access, test whether a system holds: a rare word from a restricted document through every search branch; a cache warmed by a user with access; and a direct fetch, a followed pointer and a foreign scope. Each needs a positive control run as a user with access, or an empty result proves nothing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Mnemoverse (the author's company) makes one of the memory APIs quoted below.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Can a user retrieve information outside their permissions?
&lt;/h2&gt;

&lt;p&gt;Yes, whenever a path that returns stored content skips the check that search runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A read path is any function, endpoint or query type that can return stored content to a caller: a search, an exact get, a list, an export, an admin surface or a debug endpoint.&lt;/strong&gt; Heinrich Neb, who works on a memory layer for coding agents, gave the audit rule in a &lt;a href="https://dev.to/heinrichneb/comment/3djp0"&gt;dev.to comment of 27 August 2026&lt;/a&gt;: "find every function that can return stored content."&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Read path&lt;/th&gt;
&lt;th&gt;How it returns what the user may not see&lt;/th&gt;
&lt;th&gt;What closes it&lt;/th&gt;
&lt;th&gt;Documented by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lexical branch of a hybrid search&lt;/td&gt;
&lt;td&gt;The full-text query lacks the vector query's filter&lt;/td&gt;
&lt;td&gt;One filter below both branches, or passed to each&lt;/td&gt;
&lt;td&gt;Srivastava; PostgreSQL; Elasticsearch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache in front of retrieval&lt;/td&gt;
&lt;td&gt;A stored answer is served before the check&lt;/td&gt;
&lt;td&gt;The caller's scope in the key, or the cache behind the check&lt;/td&gt;
&lt;td&gt;RFC 9111, for shared HTTP caches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fetch by ID or exact name&lt;/td&gt;
&lt;td&gt;A lookup outside search returns the record&lt;/td&gt;
&lt;td&gt;An object-level check on every route that takes an ID or a name&lt;/td&gt;
&lt;td&gt;OWASP API1:2023; Neb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pointer from a visible record&lt;/td&gt;
&lt;td&gt;A visible record names a hidden one&lt;/td&gt;
&lt;td&gt;The target's visibility checked when the pointer is read&lt;/td&gt;
&lt;td&gt;Neb; PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope from the request or the model&lt;/td&gt;
&lt;td&gt;A user ID or tag from the path, body or a tool argument is trusted&lt;/td&gt;
&lt;td&gt;Scope from the verified identity; supplied values checked against the configured set&lt;/td&gt;
&lt;td&gt;Databricks; Supermemory; Mem0; Anis Meziani&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query language as a search type&lt;/td&gt;
&lt;td&gt;Raw queries reach the store&lt;/td&gt;
&lt;td&gt;Off unless every user of the deployment is trusted&lt;/td&gt;
&lt;td&gt;Cognee&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The last four rows are kinds of indirect reference. Srivastava separates the two decisions: "Relevance determines whether information is useful. Authorization determines whether information is allowed to be accessed."&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the lexical search path leak in a hybrid search?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The lexical branch is the half of a hybrid search that matches the query's words against a full-text index, such as BM25 or PostgreSQL full-text search, beside the vector half that matches embeddings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Srivastava's rule: "The key decision is that both vector search and lexical search must respect the same access restrictions." The failure: "If vector search filters by tenant or document permissions but PostgreSQL full-text search doesn't, the hybrid retrieval pipeline can introduce a data leak through the lexical branch." On merging the two lists: "Combining rankings must never override authorization boundaries." And at retrieval time: "Apply authorization and tenant filters to every retrieval path."&lt;/p&gt;

&lt;p&gt;One filter can reach both branches from two places.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Below both branches, in the database.&lt;/strong&gt; With row security enabled on a PostgreSQL table, "all normal access to the table for selecting rows or modifying rows must be allowed by a row security policy", and a table with no policy falls back to "a default-deny policy" (&lt;a href="https://www.postgresql.org/docs/current/ddl-rowsecurity.html" rel="noopener noreferrer"&gt;PostgreSQL, Row Security Policies&lt;/a&gt;). The same page sets two limits: "the table's owner is typically not subject to row security policies" unless the table is altered with FORCE ROW LEVEL SECURITY, and "Superusers and roles with the BYPASSRLS attribute always bypass the row security system when accessing a table." An application that connects as the owner of an unforced table, as a superuser or as a BYPASSRLS role is not filtered at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One filter passed to every branch.&lt;/strong&gt; The &lt;code&gt;filter&lt;/code&gt; parameter of the &lt;a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rrf-retriever" rel="noopener noreferrer"&gt;Elasticsearch RRF retriever&lt;/a&gt; "Applies the specified boolean query filter to all of the specified sub-retrievers, according to each retriever's specifications." Written once, it cannot drift between two copies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://genai.owasp.org/llmrisk/llm082025-vector-and-embedding-weaknesses/" rel="noopener noreferrer"&gt;OWASP's LLM08:2025&lt;/a&gt; opens its prevention list with: "Implement fine-grained access controls and permission-aware vector and embedding stores." The OWASP text speaks of vector and embedding stores; a hybrid pipeline has a second index, and the same rule has to reach it. Srivastava adds a condition that holds over time: "metadata can become stale if permissions change and the retrieval index isn't updated accordingly."&lt;/p&gt;

&lt;h2&gt;
  
  
  Does a permission filter keep a restricted user's results complete?
&lt;/h2&gt;

&lt;p&gt;Nothing leaks here; the risk runs the other way. The &lt;a href="https://github.com/pgvector/pgvector/blob/master/README.md" rel="noopener noreferrer"&gt;pgvector README&lt;/a&gt;: "With approximate indexes, filtering is applied after the index is scanned. If a condition matches 10% of rows, with HNSW and the default hnsw.ef_search of 40, only 4 rows will match on average." Its first suggestion, an index on the filter column, can give exact search in many cases, so the shortfall applies whenever the planner takes the HNSW index instead.&lt;/p&gt;

&lt;p&gt;What follows is this article's inference for a vector branch on pgvector with an HNSW index, not a measurement. A permission rule is a condition that keeps some share of the rows, so the narrower a user's rights, the fewer rows one scan of the vector index can return, while the full-text branch can still return every permitted match. For hybrid search the README offers fusion: "You can use Reciprocal Rank Fusion or a cross-encoder to combine results." Fusion ranks the lists it receives, so a restricted user's top results draw more on keyword matches than an administrator's do. An evaluation run as an administrator measures only the administrator's ranking: report retrieval quality per permission level.&lt;/p&gt;

&lt;p&gt;The README's levers: "Starting with 0.8.0, you can enable iterative index scans, which will automatically scan more of the index until enough results are found". On tenants: "For applications with multiple tenants, sharing an approximate index between tenants means vectors from one tenant can affect recall (and speed) for other tenants." And: "For tenant isolation, use list partitioning or separate tables."&lt;/p&gt;

&lt;h2&gt;
  
  
  Can a cache answer with documents the user may not see?
&lt;/h2&gt;

&lt;p&gt;Yes, when it answers before the check runs. For shared HTTP caches, &lt;a href="https://www.rfc-editor.org/rfc/rfc9111.html" rel="noopener noreferrer"&gt;RFC 9111&lt;/a&gt;, section 3.5, sets the rule: "A shared cache MUST NOT use a cached response to a request with an Authorization header field" to satisfy a later request, unless the response allows shared storage through a Cache-Control directive such as public, s-maxage or must-revalidate. A semantic or answer cache inside an application follows whatever rule the application gives it.&lt;/p&gt;

&lt;p&gt;Naveen Metta, in an &lt;a href="https://naveen-metta.medium.com/10-rag-concepts-every-ai-engineer-should-learn-before-shipping-to-production-46c54cbea5f6" rel="noopener noreferrer"&gt;article of 12 October 2026&lt;/a&gt; on RAG before production, states the requirement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If a user cannot open the document, the model should not be able to quote it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From his team's work: "We found one prompt that could surface HR documents to any employee." He also advises: "Then add a semantic cache in Redis for repeated questions." This article's inference about any cache in front of retrieval, not a description of his system: such a cache answers without running the filter, so the caller's scope has to be part of what it matches on, or it has to sit behind the check.&lt;/p&gt;

&lt;p&gt;Srivastava would test "whether permissions and deletion requests propagate to the relevant indexed and cached data." The warm, revoke, replay test is covered in &lt;a href="https://mnemoverse.com/docs/library/revoked-access-chat-history" rel="noopener noreferrer"&gt;the library page on revoked access after an answer was shown&lt;/a&gt;, and caches after a delete in &lt;a href="https://mnemoverse.com/docs/library/agent-memory-deletion" rel="noopener noreferrer"&gt;Agent Memory Deletion: What Survives a Delete&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What counts as an indirect reference, and how does it leak?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;An indirect reference is any way to reach a record other than a search the filter covers: its ID, its exact name, a pointer from another record, a scope value or a query language.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An existence leak is an answer that reveals that a hidden record exists, or something about it, without returning its content.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fetch that skips search.&lt;/strong&gt; Neb, on his own system: "We had scoping enforced correctly on retrieval, tested, verified", and beside it "a second read path, lookup by exact name rather than similarity, that returned full content to anyone who asked." In short: "Same store, two doors, one guarded." The sign in code: "a read path that doesn't accept the caller identity cannot enforce anything". For APIs, &lt;a href="https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/" rel="noopener noreferrer"&gt;OWASP API1:2023 Broken Object Level Authorization&lt;/a&gt;: "Every API endpoint that receives an ID of an object, and performs any action on the object, should implement object-level authorization checks."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pointer.&lt;/strong&gt; On 25 August 2026, &lt;a href="https://dev.to/heinrichneb/comment/3dh22"&gt;Neb reported&lt;/a&gt; a retired record whose banner kept naming its successor after the successor was made private: "Existence leak through the supersession pointer." His rule: "a pointer's validity and a pointer's visibility are both read-time questions, never write-time facts." PostgreSQL warns of a related channel: its referential integrity checks always bypass row security, and "Care must be taken when developing schemas and row level policies to avoid "covert channel" leaks of information through such referential integrity checks."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The query language.&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee/pull/5844" rel="noopener noreferrer"&gt;Cognee pull request #5844&lt;/a&gt;, merged into its dev branch on 15 October 2026: "CYPHER and NATURAL_LANGUAGE search types run raw Cypher against the graph database." And: "Any user with read access to a dataset could execute arbitrary queries". The change: "ALLOW_CYPHER_QUERY now defaults to false." For turning it back on: "Only do that when every user of the deployment is trusted."&lt;/p&gt;

&lt;p&gt;What closes the class: a check at every entry point, and a refusal that neither names nor describes the hidden record, so that a missing record and someone else's record get the same answer. An answer that tells the two apart reveals existence, which is acceptable only where existence is not a secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who should set the scope of a memory read: the server, the request or the model?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A caller-supplied scope is a value that selects whose data a read covers, such as a user ID, a tenant tag or an actor ID, and that arrives with the request or from the model instead of from the verified identity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.databricks.com/aws/en/agents/agent-memory/managed-memory" rel="noopener noreferrer"&gt;Databricks agent memory documentation&lt;/a&gt; (Beta, last updated 26 October 2026) states the rule: "Set actor_id in your application code from trusted caller context: the verified end-user identity for per-user memory, or a trusted team or project key for shared memory. Never let the model choose it." And: "If your strategy depends on an end-user identity, reject requests that don't carry one rather than falling back to a shared actor_id."&lt;/p&gt;

&lt;p&gt;Three classes of the error, each with a dated fix:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A scope chosen by the model.&lt;/strong&gt; &lt;a href="https://github.com/supermemoryai/supermemory/pull/1824" rel="noopener noreferrer"&gt;Supermemory pull request #1824&lt;/a&gt;, merged on 16 October 2026 into the 2.x release branch of its tools package: "In 2.x, getProfile, documentList, memoryForget and documentDelete accept an optional containerTag from the model and use it unchecked as the request scope." The consequence: "So a model, or a prompt-injected input, can name another tenant's tag and read their profile, list their documents, forget their memories, or delete their documents." The fix: "A model-supplied tag must be one of the tags the developer configured", or the call fails "before any request is sent". The pull request also notes: "Tools 3.x (#1773) already removed model-selected scope."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An empty scope read as everything.&lt;/strong&gt; &lt;a href="https://github.com/mem0ai/mem0/pull/7581" rel="noopener noreferrer"&gt;Mem0 pull request #7581&lt;/a&gt;, merged on 12 October 2026, on its hosted clients: "The dangerous one is an empty entity ID. The API treats an empty ID as matching every memory in the project." The case there is the delete calls, &lt;code&gt;delete_all&lt;/code&gt; and &lt;code&gt;delete_users&lt;/code&gt;, fixed on the client: "This PR blocks that client-side. The server needs its own fix, which is out of scope here." This article did not check whether the server has changed since.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A scope taken from the path or the body.&lt;/strong&gt; Anis Meziani, &lt;a href="https://dev.to/anis_meziani_52aab42304a8/comment/3hnne"&gt;replying on 14 October 2026&lt;/a&gt; to a comment under his own dev.to article: "Our ADK-native session routes originally checked that a token was valid, not which user it acted for, so the user_id in the path or body was trusted." His fix checks the token's subject against the user_id "on every route that reads sessions or memory, including the live WebSocket".&lt;/p&gt;

&lt;p&gt;The rule: the scope comes from the verified identity; a request without one is refused, not given a shared scope; an empty value is an error, not everything; a value from the model is checked against the configured set before any request goes out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes when several users share one memory store?
&lt;/h2&gt;

&lt;p&gt;In a shared store the question moves from the answer to the context. A &lt;a href="https://arxiv.org/abs/2610.25707" rel="noopener noreferrer"&gt;preprint of 19 October 2026&lt;/a&gt; (arXiv 2610.25707, version 1, not peer-reviewed) opens: "Shared long-term memory lets an LLM agent serving one user inadvertently retrieve another user's credentials, but it is unclear when such exposure leads to actual harm." Its audit used the AppWorld environment and one store for all users' logins: "In AppWorld, a store that mixes 763 past logins from all users retrieves another user's credential for 84.7 percent of required apps, yet agents rarely act on it." Of the misuse its stress test provokes: "Naming the owner before or inside each credential line prevents most of this". Its conclusion: "Agent memory should consistently record whose credential it stores, and evaluations should measure behavior, not only exposure."&lt;/p&gt;

&lt;p&gt;This article's reading: the boundary is crossed when another user's record reaches the model's context, whether or not the model uses it. Srivastava, from the design side: "The stronger approach is to prevent unauthorized information from entering the context in the first place."&lt;/p&gt;

&lt;p&gt;Databricks states where the boundary sits: "actor_id separates memories, but it is not an access control. Memory stores are workspace-scoped, so any principal that can reach a store can read and write every entry across all actors." And: "The store, not the actor, is the security boundary. For strict isolation between tenants or users, create a separate memory store per boundary." OWASP's LLM08:2025, for vector databases: "In multi-tenant environments where multiple classes of users or applications share the same vector database, there's a risk of context leakage between users or queries."&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you test that no read path leaks?
&lt;/h2&gt;

&lt;p&gt;Each probe has a positive control, because a probe that finds nothing proves nothing until it finds something where it should. They are this article's proposals, not any team's suite.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The lexical branch.&lt;/strong&gt; As the test user, run vector-only, lexical-only and hybrid queries for a rare word, such as a code name, found only in a document the user may not open. Expected: no chunk of it. Control: a user with access gets it. Srivastava proposes this negative test: "Queries from unauthorized users should not expose protected documents, even when those documents are semantically similar to the query."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cache.&lt;/strong&gt; User A, with access, asks a question whose answer needs the restricted document; user B, without access, asks it and a paraphrase. Expected: B's answer is not built from that document. Control: A's answer is built from that document, and B's answer with the cache off matches B's answer with the cache on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indirect references.&lt;/strong&gt; As a user without access, fetch the record by ID and by exact name, follow a pointer to it from a visible record, and send another user's scope and an empty scope. Expected: the same answer as for a record that does not exist. Controls: as a user with access, the same fetch, pointer and scope return the record, so the path is live; a made-up ID on the same path gives the answer to compare against.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Three rules for the run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Take the list of read paths from the code or the tool registry&lt;/strong&gt;, not from a filtered listing. sam ros, &lt;a href="https://dev.to/sampop3/comment/3i0bb"&gt;on 15 October 2026&lt;/a&gt;, about the CI test of the scope check in his MCP server: "with a list_tools override that filters by the token's scopes, the old test passed while a tickets:read token could still delete."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rerun the probes after a permission change and after a delete&lt;/strong&gt;: permission data copied into an index or a cache can go stale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspect what reached the model's context&lt;/strong&gt;, not only the final answer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A passing first probe says nothing about the second and the third.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do memory APIs document where the boundary is?
&lt;/h2&gt;

&lt;p&gt;Two documented positions, in their own words, as read on 2 November 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Databricks.&lt;/strong&gt; The store is the boundary, and application code, not the model, sets the actor ID; both are quoted above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mnemoverse.&lt;/strong&gt; The &lt;a href="https://mnemoverse.com/docs/api/security" rel="noopener noreferrer"&gt;security page&lt;/a&gt; states the tenant boundary: "Every API key is bound to a unique organization_id. All database queries are scoped to your organization." Shared rooms (beta) stay apart: "room content never appears in your normal (non-room) searches". The &lt;a href="https://mnemoverse.com/docs/api/rooms" rel="noopener noreferrer"&gt;rooms reference&lt;/a&gt; covers indirect references: "Knowing a room id grants no access to its contents: access is enforced by the API's membership check on every request, and non-members get 403." And: "Membership is checked before archive state, so a non-member of an archived room still gets the membership 403", so the answer does not reveal whether a room is archived. This is a documented boundary, not a test result; this article tests no product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article does not claim
&lt;/h2&gt;

&lt;p&gt;No measurement of any product and no figure for how often any system leaks. The numbers above are the pgvector README's illustration and one preprint's audit, each with its conditions. Vendor fixes are quoted from their own pull requests with their merge dates; this article did not check whether a fix has reached a release. The inference about rank fusion is for pgvector with an HNSW index and was not measured. The probes are proposals, not a description of any team's suite.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Every quotation was read on 2 November 2026 with two instruments, a browser-like request and a second reading of the same text: a reader service with its cache off, and in addition the dev.to API for the dev.to comments, the RSS feed for Jeevan Srivastava's article and the arXiv API for the preprint; for the GitHub pull requests and the pgvector README, which the reader service refuses, the GitHub API and the raw file took its place. A made-up address on each host answered 404 as a control, except Medium, which answers 200 to any address, so there only the article text counts. The text describes those pages as of that date. A longer version, with the common questions and the full list of sources, is in the Mnemoverse documentation library: &lt;a href="https://mnemoverse.com/docs/library/retrieval-outside-permissions" rel="noopener noreferrer"&gt;Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-11-02&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>rag</category>
      <category>ai</category>
      <category>postgres</category>
    </item>
    <item>
      <title>How to give Claude Code persistent context across separate terminal sessions?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Tue, 03 Nov 2026 10:53:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/how-to-give-claude-code-persistent-context-across-separate-terminal-sessions-3e69</link>
      <guid>https://dev.to/izgorodin/how-to-give-claude-code-persistent-context-across-separate-terminal-sessions-3e69</guid>
      <description>&lt;p&gt;Claude Code already carries context between sessions through two mechanisms: CLAUDE.md files that you write and auto memory notes that Claude writes. Anthropic says both load at the start of every conversation and act as context rather than enforced configuration (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;). &lt;code&gt;claude --continue&lt;/code&gt; serves a different purpose: it loads the most recent conversation in the current directory (&lt;a href="https://code.claude.com/docs/en/cli-reference" rel="noopener noreferrer"&gt;CLI reference&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Each mechanism has a boundary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Put stable project instructions in &lt;code&gt;CLAUDE.md&lt;/code&gt;. Use &lt;code&gt;~/.claude/CLAUDE.md&lt;/code&gt; or &lt;code&gt;~/.claude/rules/&lt;/code&gt; for personal instructions that should apply across projects on your machine.&lt;/li&gt;
&lt;li&gt;Auto memory is Claude-written, enabled by default in local sessions, and stored in a project-specific memory directory. Anthropic states: "Auto memory is machine-local."&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;claude --continue&lt;/code&gt; to load the latest conversation in the current directory. Use &lt;code&gt;--resume&lt;/code&gt; to select a conversation from local history.&lt;/li&gt;
&lt;li&gt;Add an MCP memory server at user scope only when its broader boundary is useful. Then authenticate it, add memory-use rules, and verify the labeled server tool call.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;th&gt;What it keeps&lt;/th&gt;
&lt;th&gt;Who writes it&lt;/th&gt;
&lt;th&gt;Where it lives&lt;/th&gt;
&lt;th&gt;Where its documented boundary appears&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Instructions and project context&lt;/td&gt;
&lt;td&gt;You, or Claude with your direction&lt;/td&gt;
&lt;td&gt;Project files or user-level files&lt;/td&gt;
&lt;td&gt;Project instructions can travel through version control; personal rules apply "on your machine"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto memory&lt;/td&gt;
&lt;td&gt;Notes based on corrections and preferences&lt;/td&gt;
&lt;td&gt;Claude&lt;/td&gt;
&lt;td&gt;A memory directory derived from the Git repository&lt;/td&gt;
&lt;td&gt;Anthropic states: "Auto memory is machine-local"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Saved conversation&lt;/td&gt;
&lt;td&gt;Messages, tool calls and results, subject to documented compaction behavior&lt;/td&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Session history associated with a project directory&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--continue&lt;/code&gt; selects the latest conversation in the current directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory MCP server&lt;/td&gt;
&lt;td&gt;Information written and read through server tools&lt;/td&gt;
&lt;td&gt;The agent under installed memory rules&lt;/td&gt;
&lt;td&gt;The connected memory service&lt;/td&gt;
&lt;td&gt;User scope covers projects on the machine; cross-tool use depends on the service, account and rules&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When you need one setup that applies in every project, or memory that other tools on the same account can reach, the next step is a memory server added at user scope. Several have a path into Claude Code, and the steps below use one of them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mnemoverse (the author's company) makes one of the memory servers mentioned here, and the step-by-step part uses it.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does Claude Code keep between sessions on its own?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CLAUDE.md is Anthropic's plain-text mechanism for instructions that Claude reads at the start of a session.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anthropic's documentation says: "Each Claude Code session begins with a fresh context window. Two mechanisms carry knowledge across sessions: CLAUDE.md files: instructions you write to give Claude persistent context." It then names auto memory as the second mechanism. A project-level &lt;code&gt;CLAUDE.md&lt;/code&gt; suits repository conventions, commands and constraints, and project instructions can be shared with a team through version control (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;). To create a starting file, run &lt;code&gt;/init&lt;/code&gt;, then use &lt;code&gt;/memory&lt;/code&gt; to refine it (&lt;a href="https://code.claude.com/docs/en/commands" rel="noopener noreferrer"&gt;commands&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto memory is "notes Claude writes itself based on your corrections and preferences".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is on by default in local sessions. Claude decides what may be useful in a future conversation, and &lt;code&gt;MEMORY.md&lt;/code&gt; acts as an index for its memory directory. The index and topic files remain until you or Claude edits or deletes them (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A saved conversation is a Claude Code session associated with a project directory and retained in session history.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;--continue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anthropic defines this flag as "Load the most recent conversation in the current directory" (&lt;a href="https://code.claude.com/docs/en/cli-reference" rel="noopener noreferrer"&gt;CLI reference&lt;/a&gt;). The sessions documentation describes conversation history as messages, tool calls and results, with a compaction caveat (&lt;a href="https://code.claude.com/docs/en/sessions" rel="noopener noreferrer"&gt;sessions&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; carries chosen instructions, auto memory carries Claude-written notes, and a saved conversation resumes prior work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where does each kind of Claude Code context stop?
&lt;/h2&gt;

&lt;p&gt;The conversation is tied to its directory. &lt;code&gt;--continue&lt;/code&gt; selects the latest conversation there, while &lt;code&gt;--resume&lt;/code&gt; reopens a conversation from the machine's local history (&lt;a href="https://code.claude.com/docs/en/cli-reference" rel="noopener noreferrer"&gt;CLI reference&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/claude-code-on-the-web" rel="noopener noreferrer"&gt;Claude Code on the web&lt;/a&gt;). The session picker can widen beyond the current directory: Anthropic documents &lt;code&gt;Ctrl+W&lt;/code&gt; for all worktrees of a repository and &lt;code&gt;Ctrl+A&lt;/code&gt; for every project "on this machine" (&lt;a href="https://code.claude.com/docs/en/sessions" rel="noopener noreferrer"&gt;sessions&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Auto memory has its own storage boundary. Each project gets a directory at &lt;code&gt;~/.claude/projects/&amp;lt;project&amp;gt;/memory/&lt;/code&gt;, with the project path derived from the Git repository. Anthropic states the full boundary: "Auto memory is machine-local. All worktrees and subdirectories within the same git repository share one auto memory directory. Files are not shared across machines or cloud environments" (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;). The &lt;code&gt;autoMemoryDirectory&lt;/code&gt; setting stores auto memory in a different location, and Anthropic describes it only as that.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I make Claude Code instructions apply in every project?
&lt;/h2&gt;

&lt;p&gt;For personal instructions, place them in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.claude/CLAUDE.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anthropic classifies this file as personal preferences for all projects. For modular personal rules, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.claude/rules/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anthropic says those rules apply to every project on your machine (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Subagents have another option. The &lt;code&gt;memory&lt;/code&gt; field gives a subagent a persistent directory that survives across conversations, and &lt;code&gt;memory: user&lt;/code&gt; is the documented scope for learnings across projects. This remains part of auto memory: turning off auto memory also disables the subagent memory field (&lt;a href="https://code.claude.com/docs/en/sub-agents" rel="noopener noreferrer"&gt;subagents&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A rule in &lt;code&gt;CLAUDE.md&lt;/code&gt; is context, not a forced control. If a rule is not being followed, inspect how it is written and loaded; the difference between instructions and enforcement is covered in &lt;a href="https://mnemoverse.com/docs/library/claude-md-agents-md-cursor-rules" rel="noopener noreferrer"&gt;how CLAUDE.md, AGENTS.md and Cursor rules work&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I carry what one session learned into the next?
&lt;/h2&gt;

&lt;p&gt;If a conversation produces a durable project rule, ask Claude to "add this to CLAUDE.md," or edit the file through &lt;code&gt;/memory&lt;/code&gt;. Anthropic's direct guidance is: "Add conversation-only instructions to CLAUDE.md to make them persist" (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Anthropic also publishes the &lt;code&gt;claude-md-management&lt;/code&gt; plugin in &lt;code&gt;claude-plugins-official&lt;/code&gt;. Its &lt;code&gt;/revise-claude-md&lt;/code&gt; command captures session learnings at the end of a session, and the plugin presents proposed changes as diffs and applies them only with your approval (&lt;a href="https://claude.com/marketplace/plugins/claude-md-management" rel="noopener noreferrer"&gt;plugin page&lt;/a&gt;). Install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/plugin install claude-md-management@claude-plugins-official
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a session, the command first opens the &lt;code&gt;/plugin&lt;/code&gt; panel on the plugin's details so you can choose a scope; user scope makes it available in every project on the machine (&lt;a href="https://code.claude.com/docs/en/plugins/install" rel="noopener noreferrer"&gt;plugin installation&lt;/a&gt;). If &lt;code&gt;claude-plugins-official&lt;/code&gt; is not on the Marketplaces tab of &lt;code&gt;/plugin&lt;/code&gt;, Anthropic says to add it with &lt;code&gt;/plugin marketplace add anthropics/claude-plugins-official&lt;/code&gt; (&lt;a href="https://code.claude.com/docs/en/plugins/anthropic-marketplaces" rel="noopener noreferrer"&gt;Anthropic marketplaces&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The plugin is not the only inspection route: in Claude Code 2.1.283 or later, Anthropic documents &lt;code&gt;/doctor prompt-audit&lt;/code&gt; for checking instruction files for outdated or conflicting content (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  How does context reach another computer, a teammate or a cloud session?
&lt;/h2&gt;

&lt;p&gt;Committed files provide the documented route for repository context. A project &lt;code&gt;CLAUDE.md&lt;/code&gt; can travel through version control, and so can a project-scoped &lt;code&gt;.mcp.json&lt;/code&gt;: Anthropic says teammates who clone the repository receive an approval prompt for the configured server (&lt;a href="https://code.claude.com/docs/en/mcp-quickstart" rel="noopener noreferrer"&gt;MCP quickstart&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Cloud sessions start from a fresh clone. Anthropic says committed repository content is available there and advises committing configuration that a cloud session needs (&lt;a href="https://code.claude.com/docs/en/cloud-environments" rel="noopener noreferrer"&gt;cloud environments&lt;/a&gt;). Local and user-scoped MCP configuration has a separate boundary. Anthropic states: "Those write to ~/.claude.json on your machine, not the repo. Add the server with claude mcp add --scope project, which writes the repo’s .mcp.json, and commit that file" (&lt;a href="https://code.claude.com/docs/en/cloud-environments" rel="noopener noreferrer"&gt;cloud environments&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Claude Code surfaces also retain distinct session lists. Anthropic says the desktop app, &lt;code&gt;claude.ai/code&lt;/code&gt; and the VS Code extension "each keep their own session list," while the desktop app can resume a CLI session (&lt;a href="https://code.claude.com/docs/en/sessions" rel="noopener noreferrer"&gt;sessions&lt;/a&gt;). On one computer, the terminal, local desktop sessions and the VS Code extension read the same settings files, so a user-scoped plugin installed in one is available in the other two (&lt;a href="https://code.claude.com/docs/en/plugins/install" rel="noopener noreferrer"&gt;plugin installation&lt;/a&gt;). A saved conversation is not shared instructions or shared memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  When is a memory server worth adding?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A memory MCP server is a service that exposes memory operations to Claude Code through the Model Context Protocol.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first reason is configuration scope. Anthropic says an MCP server added without the intended scope can remain tied to the current project. Adding it at user scope makes it available across all projects on your machine while keeping it private to your user account (&lt;a href="https://code.claude.com/docs/en/mcp-quickstart" rel="noopener noreferrer"&gt;MCP quickstart&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;MCP configuration&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The second reason is cross-tool memory. Mnemoverse, for example, documents memory under the same account across supported tools. Without memory rules in each tool, the memory is there but goes unused (&lt;a href="https://mnemoverse.com/docs/api/mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Some paths into Claude Code include:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Path named in its documentation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;&lt;a href="https://claude.com/marketplace/plugins/claude-md-management" rel="noopener noreferrer"&gt;&lt;code&gt;claude-md-management&lt;/code&gt; plugin&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mem0&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://docs.mem0.ai/integrations/claude-code" rel="noopener noreferrer"&gt;Plugin&lt;/a&gt; and &lt;a href="https://docs.mem0.ai/platform/mem0-mcp" rel="noopener noreferrer"&gt;Mem0 MCP server&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supermemory&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://supermemory.ai/docs/integrations/claude-code" rel="noopener noreferrer"&gt;Claude Code plugin&lt;/a&gt; and &lt;a href="https://supermemory.ai/docs/supermemory-mcp/setup" rel="noopener noreferrer"&gt;remote HTTP MCP server&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cognee&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://docs.cognee.ai/integrations/claude-code-integration" rel="noopener noreferrer"&gt;Cognee memory plugin&lt;/a&gt;, &lt;a href="https://docs.cognee.ai/cognee-mcp/integrations/claude-code" rel="noopener noreferrer"&gt;MCP integration&lt;/a&gt; and &lt;a href="https://docs.cognee.ai/cognee-cloud/connections/cloud-mcp" rel="noopener noreferrer"&gt;hosted MCP server&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;claude-mem&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.claude-mem.ai/installation" rel="noopener noreferrer"&gt;Claude-Mem plugin&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;remember&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Digital-Process-Tools/claude-remember" rel="noopener noreferrer"&gt;&lt;code&gt;remember@dpt-plugins&lt;/code&gt; plugin&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mnemoverse&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://mnemoverse.com/docs/api/remote-mcp-server" rel="noopener noreferrer"&gt;Remote MCP server&lt;/a&gt; and &lt;a href="https://mnemoverse.com/docs/api/install-by-host" rel="noopener noreferrer"&gt;Claude Code plugin path&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are examples, not an exhaustive list. For a selection framework, see &lt;a href="https://mnemoverse.com/docs/library/mcp-memory-servers-claude-code-and-cursor" rel="noopener noreferrer"&gt;MCP memory servers for Claude Code and Cursor&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I connect a memory server to Claude Code, step by step?
&lt;/h2&gt;

&lt;p&gt;The following path uses the hosted Mnemoverse MCP server.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Add the server at user scope
&lt;/h3&gt;

&lt;p&gt;Run this in your shell, outside a Claude session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--scope&lt;/span&gt; user &lt;span class="nt"&gt;--transport&lt;/span&gt; http mnemoverse https://mcp.mnemoverse.com/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anthropic documents this command shape, says user scope registers a server across projects on the machine, and says the command works the same in shells including PowerShell and Command Prompt (&lt;a href="https://code.claude.com/docs/en/mcp-quickstart" rel="noopener noreferrer"&gt;MCP quickstart&lt;/a&gt;). Anthropic accepts &lt;code&gt;-s&lt;/code&gt; as the short form of &lt;code&gt;--scope&lt;/code&gt; (&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;MCP configuration&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A session that is already open does not pick up the new server. The Mnemoverse Claude Code page: "A session that was already running when the command ran does not load the new server, even when Claude ran the command for you: exit and start claude again first" (&lt;a href="https://mnemoverse.com/docs/api/claude" rel="noopener noreferrer"&gt;Claude Code setup&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Confirm that authentication is required
&lt;/h3&gt;

&lt;p&gt;Adding the server does not start sign-in. Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before authentication, the expected state is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;! Needs authentication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No memory tools are available until sign-in completes (&lt;a href="https://mnemoverse.com/docs/api/agent-setup" rel="noopener noreferrer"&gt;agent setup&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/mcp-quickstart" rel="noopener noreferrer"&gt;MCP quickstart&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Sign in
&lt;/h3&gt;

&lt;p&gt;Start Claude Code, run &lt;code&gt;/mcp&lt;/code&gt;, choose &lt;code&gt;mnemoverse&lt;/code&gt;, then select &lt;strong&gt;Authenticate&lt;/strong&gt;. The flow opens &lt;code&gt;console.mnemoverse.com&lt;/code&gt;, where you sign in with a Mnemoverse account (&lt;a href="https://mnemoverse.com/docs/api/remote-mcp-server" rel="noopener noreferrer"&gt;remote MCP server&lt;/a&gt;). A free Mnemoverse account is required. Claude Code 2.1.186 or later also supports shell login (&lt;a href="https://mnemoverse.com/docs/api/agent-setup" rel="noopener noreferrer"&gt;agent setup&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp login mnemoverse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After authentication, &lt;code&gt;/mcp&lt;/code&gt; reports the server as connected, and &lt;code&gt;claude mcp list&lt;/code&gt; shows &lt;code&gt;✔ Connected&lt;/code&gt; (&lt;a href="https://mnemoverse.com/docs/api/agent-setup" rel="noopener noreferrer"&gt;agent setup&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/mcp-quickstart" rel="noopener noreferrer"&gt;MCP quickstart&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Add memory rules
&lt;/h3&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/mcp__mnemoverse__setup_memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code also exposes MCP prompts in the &lt;code&gt;/&lt;/code&gt; menu as &lt;code&gt;/servername:promptname (MCP)&lt;/code&gt;. For this setup, that is &lt;code&gt;/mnemoverse:setup_memory (MCP)&lt;/code&gt; (&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;MCP configuration&lt;/a&gt;, &lt;a href="https://mnemoverse.com/docs/api/agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt;). The setup prompt presents the rules, identifies the appropriate instruction file and offers to add them. Choose the project &lt;code&gt;CLAUDE.md&lt;/code&gt;, or &lt;code&gt;~/.claude/CLAUDE.md&lt;/code&gt; for every project.&lt;/p&gt;

&lt;p&gt;This step is required because connecting adds tools, not a usage habit. A request made only in chat lasts for that chat. Rules in an instruction file load at the start of later sessions (&lt;a href="https://mnemoverse.com/docs/api/agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt;, &lt;a href="https://mnemoverse.com/docs/api/mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Test the connection
&lt;/h3&gt;

&lt;p&gt;Ask Claude to call &lt;code&gt;memory_stats&lt;/code&gt;. A zero result is normal for a new account and still confirms that the connection works (&lt;a href="https://mnemoverse.com/docs/api/agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;An alternative path is the Mnemoverse connector at &lt;code&gt;https://mcp.mnemoverse.com/mcp&lt;/code&gt;, which works in &lt;code&gt;claude.ai&lt;/code&gt;, Claude Desktop, mobile and Claude Code (&lt;a href="https://mnemoverse.com/docs/api/claude" rel="noopener noreferrer"&gt;Claude Code setup&lt;/a&gt;). Anthropic says connectors added at &lt;code&gt;claude.ai/customize/connectors&lt;/code&gt; load in the CLI when you sign in with the same account, provided the active authentication method is a &lt;code&gt;claude.ai&lt;/code&gt; subscription login (&lt;a href="https://code.claude.com/docs/en/mcp-quickstart" rel="noopener noreferrer"&gt;MCP quickstart&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;MCP configuration&lt;/a&gt;). Use one path for the same endpoint: a server you added yourself takes precedence over a &lt;code&gt;claude.ai&lt;/code&gt; connector with the same URL (&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;MCP configuration&lt;/a&gt;). If the connector supplies the server, type &lt;code&gt;/&lt;/code&gt; and choose the &lt;code&gt;setup_memory&lt;/code&gt; entry marked &lt;code&gt;(MCP)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I check which memory answered?
&lt;/h2&gt;

&lt;p&gt;Each mechanism leaves its own signal, so check the signal rather than the answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is the fact in a loaded instruction file?   /context → Memory files      → CLAUDE.md
Did Claude Code print "Saved / Recalled N memories"?                    → auto memory
Is there a tool call labeled with the server name?                      → the MCP server
None of these?                              current context or the model's own knowledge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the &lt;strong&gt;Memory files&lt;/strong&gt; list. Anthropic documents this as the way to confirm that an instruction file loaded (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto memory
&lt;/h3&gt;

&lt;p&gt;A general request to remember something goes to auto memory. Claude Code shows messages such as "Saved 2 memories" or "Recalled 2 memories" when it writes or reads the project memory directory (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory documentation&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP memory server
&lt;/h3&gt;

&lt;p&gt;Anthropic's test is the tool-call label: "The tool call in Claude’s output is labeled with the server name, which is how you confirm the answer came from the MCP server rather than Claude’s built-in knowledge" (&lt;a href="https://code.claude.com/docs/en/mcp-quickstart" rel="noopener noreferrer"&gt;MCP quickstart&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;For a clean test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Temporarily disable auto memory with the toggle in &lt;code&gt;/memory&lt;/code&gt;, or set &lt;code&gt;CLAUDE_CODE_DISABLE_AUTO_MEMORY=1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Start a session and say: &lt;code&gt;Remember in Mnemoverse that I prefer concise commit messages.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Confirm that Claude makes a tool call labeled with the Mnemoverse server name.&lt;/li&gt;
&lt;li&gt;Start a new session and ask: &lt;code&gt;What is my preference for commit messages?&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Confirm another tool call labeled with the server name.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The example stores a personal preference, not a project fact. Do not infer the source from the answer alone; check the label. Turning off auto memory also turns off subagent memory (&lt;a href="https://code.claude.com/docs/en/sub-agents" rel="noopener noreferrer"&gt;subagents&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does Claude not use the memory server?
&lt;/h2&gt;

&lt;p&gt;A common symptom is a new session answering from current context without calling the server. Check these points in order.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm the rules loaded.&lt;/strong&gt; Run &lt;code&gt;/context&lt;/code&gt; and inspect &lt;strong&gt;Memory files&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the setup prompt.&lt;/strong&gt; Use &lt;code&gt;/mcp__mnemoverse__setup_memory&lt;/code&gt;, then place the rules in the intended &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check server scope.&lt;/strong&gt; If &lt;code&gt;/mcp&lt;/code&gt; is empty in a new repository, the server may have been added in local scope elsewhere. Re-add it with &lt;code&gt;--scope user&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check for name shadowing.&lt;/strong&gt; A local server with the same name takes precedence over a user-scoped server (&lt;a href="https://mnemoverse.com/docs/api/troubleshooting" rel="noopener noreferrer"&gt;troubleshooting&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check authentication.&lt;/strong&gt; Signing out or changing accounts removes access to the tools. Signing back in with the same Mnemoverse account restores access (&lt;a href="https://mnemoverse.com/docs/api/remote-mcp-server" rel="noopener noreferrer"&gt;remote MCP server&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the account.&lt;/strong&gt; Credentials associated with another account can expose an empty store without an error (&lt;a href="https://mnemoverse.com/docs/api/claude" rel="noopener noreferrer"&gt;Claude Code setup&lt;/a&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What about two terminals open at the same time?
&lt;/h2&gt;

&lt;p&gt;This article answers the sequential-session case. For active sessions, project-root and user-level &lt;code&gt;CLAUDE.md&lt;/code&gt; files are read once at session start. Edited content loads after the next &lt;code&gt;/clear&lt;/code&gt;, &lt;code&gt;/compact&lt;/code&gt; or restart (&lt;a href="https://code.claude.com/docs/en/prompt-caching" rel="noopener noreferrer"&gt;prompt caching&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Claude Code also has cross-session messaging, which Anthropic defines as one session delivering a message to another. Its documented boundary matters: "A message is a piece of text one Claude writes to another, never the sender’s conversation history or files" (&lt;a href="https://code.claude.com/docs/en/cross-session-messaging" rel="noopener noreferrer"&gt;cross-session messaging&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article does not claim
&lt;/h2&gt;

&lt;p&gt;No performance, latency or benchmark figure for anyone. The paths named are examples, not a list of all of them. Every quotation was read on the date given below. This article answers for sequential sessions; for two sessions open at once it repeats only what Anthropic documents.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Every quotation was read on 2 November 2026 with two instruments, a browser-like request (for Claude Code's documentation also the Markdown version of each page) and a reader service with its cache off; a made-up address on each host answered 404 as a control. The text describes those pages as of that date. A longer version, with common questions and the full list of sources, is in the Mnemoverse documentation library: &lt;a href="https://mnemoverse.com/docs/library/claude-code-persistent-memory" rel="noopener noreferrer"&gt;How to give Claude Code persistent context across separate terminal sessions?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-11-02&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>productivity</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Did you find a clean way to let the agent commit without giving it write access to the shared config?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Sat, 31 Oct 2026 07:10:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/did-you-find-a-clean-way-to-let-the-agent-commit-without-giving-it-write-access-to-the-shared-47bk</link>
      <guid>https://dev.to/izgorodin/did-you-find-a-clean-way-to-let-the-agent-commit-without-giving-it-write-access-to-the-shared-47bk</guid>
      <description>&lt;p&gt;Carlos (Bloqarl) asked the question in the title in a dev.to comment under &lt;a href="https://dev.to/bloqarl/your-repo-is-not-trusted-context-what-i-changed-after-giving-coding-agents-real-repositories-2ken"&gt;his article about giving coding agents real repositories&lt;/a&gt;, and named the trap in the same breath: "I was treating the worktree as the boundary and it's only the checkout."&lt;/p&gt;

&lt;p&gt;The short answer is: not by guarding paths inside a shared &lt;code&gt;.git&lt;/code&gt;. Isolate the repository, not the paths.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A linked worktree shares hooks, config and branch refs with the main repository: with hooks and config read-only, an agent that can commit there can still move &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use a clone per task that the main repository only fetches from, or let the agent only edit and make the commit outside the box.&lt;/li&gt;
&lt;li&gt;Make that outside commit run no hooks, because main's own hooks call code from the agent's checkout (husky's &lt;code&gt;npm test&lt;/code&gt;, &lt;code&gt;node_modules/.bin&lt;/code&gt; first on &lt;code&gt;PATH&lt;/code&gt;, lint-staged JavaScript configs).&lt;/li&gt;
&lt;li&gt;No hooks takes more than &lt;code&gt;--no-verify&lt;/code&gt; or an empty hooks directory: hooks declared in git config ran on Git for Windows 2.56.0, and a &lt;code&gt;core.fsmonitor&lt;/code&gt; command ran on 2.52.0 and 2.56.0. Run the checks inside the box and read the diff for what runs later.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;th&gt;What the agent can change that runs or moves outside the box&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Worktree per task, main &lt;code&gt;.git&lt;/code&gt; mounted&lt;/td&gt;
&lt;td&gt;hooks, config (&lt;code&gt;core.hooksPath&lt;/code&gt;; &lt;code&gt;hook.*&lt;/code&gt; from Git 2.54.0), branch refs including &lt;code&gt;main&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same, &lt;code&gt;.git/hooks&lt;/code&gt; and &lt;code&gt;.git/config&lt;/code&gt; read-only&lt;/td&gt;
&lt;td&gt;branch refs; hook bodies tracked in the tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clone per task, main repository fetches&lt;/td&gt;
&lt;td&gt;on fetch, nothing planted ran; git run inside the clone ran the clone's &lt;code&gt;core.fsmonitor&lt;/code&gt; command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent edits only, commit outside&lt;/td&gt;
&lt;td&gt;hook bodies and scripts in the checkout, unless the outside commit runs no hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every run described here was made on one Windows 11 machine on 15 October 2026, with Git for Windows 2.52.0 and 2.56.0, plain git and the tools named. Test scripts planted the hooks and configs; no agent ran.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is a worktree per task not a boundary for git?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A linked worktree&lt;/strong&gt; is an extra working tree added with &lt;code&gt;git worktree add&lt;/code&gt;: its own checkout and per-worktree files such as &lt;code&gt;HEAD&lt;/code&gt; and the index, everything else shared with the repository.&lt;/p&gt;

&lt;p&gt;git's &lt;a href="https://git-scm.com/docs/git-worktree" rel="noopener noreferrer"&gt;worktree page&lt;/a&gt; draws the line. A new worktree is "linked to the current repository, sharing everything except per-worktree files such as HEAD, index, etc." Also: "By default, the repository config file is shared across all worktrees." And: "In general, all pseudo refs are per-worktree and all refs starting with refs/ are shared." Branches live under &lt;code&gt;refs/heads/&lt;/code&gt;, so they are shared too. The linked worktree's own &lt;code&gt;.git&lt;/code&gt; is a pointer file, so an agent that commits from a container needs the main &lt;code&gt;.git&lt;/code&gt; mounted, hooks and config included.&lt;/p&gt;

&lt;p&gt;Runs from inside a linked worktree, on Git for Windows 2.52.0 and 2.56.0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;pre-commit&lt;/code&gt; hook written to the path &lt;code&gt;git rev-parse --git-path hooks&lt;/code&gt; returns ran on a commit in the main worktree.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git config core.hooksPath &amp;lt;dir&amp;gt;&lt;/code&gt; landed in the shared &lt;code&gt;.git/config&lt;/code&gt;, and the hook from that directory ran in the main worktree.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git update-ref refs/heads/main &amp;lt;commit&amp;gt;&lt;/code&gt; moved the main repository's &lt;code&gt;main&lt;/code&gt; to the task's commit.&lt;/li&gt;
&lt;li&gt;On 2.56.0 only, a configured &lt;code&gt;pre-commit&lt;/code&gt; hook written into the shared config ran in the main worktree, also with &lt;code&gt;core.hooksPath&lt;/code&gt; pointed at an empty directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That leaves the read-only case: hooks and config read-only, refs open for commits. No run enforced read-only protection (&lt;code&gt;chmod a-w&lt;/code&gt; on &lt;code&gt;.git/config&lt;/code&gt; did not hold on Windows), so that case rests on git's documentation: a commit updates a branch ref, and branch refs are shared.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do coding-agent sandboxes do with .git?
&lt;/h2&gt;

&lt;p&gt;Two coding-agent sandboxes document how they treat &lt;code&gt;.git&lt;/code&gt;. Neither was run here; they are quoted in their own words.&lt;/p&gt;

&lt;p&gt;Claude Code's &lt;a href="https://code.claude.com/docs/en/sandboxing" rel="noopener noreferrer"&gt;sandboxing page&lt;/a&gt;: "Git worktrees: when the working directory is a linked git worktree, the sandbox also allows writes to the main repository’s shared .git directory so commands such as git commit can update refs and the index. Writes to hooks/ and config inside that directory remain denied." The reason for the protected paths: "A command that could edit those files could grant itself permissions, or add a hook or MCP server that Claude Code runs outside the sandbox." Its conditions include "The sandbox is off by default." and "The sandbox covers shell commands only. Claude’s file tools, MCP servers, and hooks run outside it."&lt;/p&gt;

&lt;p&gt;OpenAI's Codex &lt;a href="https://learn.chatgpt.com/docs/agent-approvals-security" rel="noopener noreferrer"&gt;approvals and security page&lt;/a&gt;: "&amp;lt;writable_root&amp;gt;/.git is protected as read-only whether it appears as a directory or file." And: "If &amp;lt;writable_root&amp;gt;/.git is a pointer file (gitdir: ...), the resolved Git directory path is also protected as read-only." For a linked worktree, git calls that resolved directory the private one under the main repository's &lt;code&gt;.git/worktrees/&lt;/code&gt;; the page does not say whether the shared hooks, config and refs are covered.&lt;/p&gt;

&lt;p&gt;The first is the read-only hooks and config setup with refs open for commits. Both pages describe what runs inside the sandbox, and the conditions they state matter as much as the paths they protect.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does a clone per task keep hooks and config inside the box?
&lt;/h2&gt;

&lt;p&gt;git's &lt;a href="https://git-scm.com/docs/git#_security" rel="noopener noreferrer"&gt;security section&lt;/a&gt;: "Because configuration and hooks are not copied using git clone, it is generally safe to clone remote repositories with untrusted content, inspect them with git log, and so on." In the runs, a test script standing in for the agent planted six hooks, a configured &lt;code&gt;reference-transaction&lt;/code&gt; hook and a &lt;code&gt;core.fsmonitor&lt;/code&gt; command in the task clone. The main repository's &lt;code&gt;git fetch ../task task:refs/heads/task-review&lt;/code&gt; ran none of them and added no hooks and no &lt;code&gt;core.fsmonitor&lt;/code&gt; to it.&lt;/p&gt;

&lt;p&gt;A fetch still carries some risk, and git says so: "Git does restrict the set of options and hooks that will be run by upload-pack, which handles the server side of a clone or fetch, but beware that the surface area for attack against upload-pack is large, so this does carry some risk."&lt;/p&gt;

&lt;p&gt;Never run git inside the agent's clone. The same section: "However, it is not safe to run Git commands in a .git directory (or the working tree that surrounds it) when that .git directory itself comes from an untrusted source. The commands in its config and hooks are executed in the usual way." In the runs, &lt;code&gt;git -C &amp;lt;task clone&amp;gt; status&lt;/code&gt; from outside executed the &lt;code&gt;core.fsmonitor&lt;/code&gt; command planted in the clone's config. Starting the command outside the box did not change whose configuration it read. To inspect with git, "you should first clone it with git clone --no-local to obtain a clean copy."&lt;/p&gt;

&lt;p&gt;Submodules are a second git directory: &lt;code&gt;.git/modules&lt;/code&gt; "Contains the git-repositories of the submodules." (&lt;a href="https://git-scm.com/docs/gitrepository-layout" rel="noopener noreferrer"&gt;repository layout&lt;/a&gt;). After &lt;code&gt;git submodule add&lt;/code&gt;, &lt;code&gt;.git/modules/lib&lt;/code&gt; had its own &lt;code&gt;hooks&lt;/code&gt; and &lt;code&gt;config&lt;/code&gt;, and a hook placed there ran on a commit inside the submodule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do main's hooks still run the agent's code?
&lt;/h2&gt;

&lt;p&gt;Committing outside with the main repository's own hooks trusts the hook files, not what they call. Each run below used husky 9.1.7, lint-staged 17.6.0, npm 11.13.0 and Node 24.16.0.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;husky.&lt;/strong&gt; &lt;code&gt;husky init&lt;/code&gt; "creates a pre-commit script in .husky/ and updates the prepare script in package.json", and its &lt;a href="https://typicode.github.io/husky/get-started.html" rel="noopener noreferrer"&gt;example&lt;/a&gt; notes "test script will run every time you commit". After &lt;code&gt;npx husky init&lt;/code&gt;, a plain commit ran &lt;code&gt;pretest&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt; and &lt;code&gt;posttest&lt;/code&gt; from the checkout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm.&lt;/strong&gt; &lt;code&gt;npm test&lt;/code&gt; "runs a predefined command specified in the "test" property of a package's "scripts" object" (&lt;a href="https://docs.npmjs.com/cli/v12/commands/npm-test" rel="noopener noreferrer"&gt;npm-test&lt;/a&gt;). A &lt;code&gt;pre-commit&lt;/code&gt; hook kept outside the checkout, with the body &lt;code&gt;npm test&lt;/code&gt;, ran all three scripts from the checkout's &lt;code&gt;package.json&lt;/code&gt;. The hook file can sit anywhere; the code it calls is the checkout's.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PATH&lt;/code&gt;.&lt;/strong&gt; husky's runner sets &lt;code&gt;export PATH="node_modules/.bin:$PATH"&lt;/code&gt;, and git starts a hook in "the root of the working tree in a non-bare repository." An &lt;code&gt;npm&lt;/code&gt; planted in the checkout's &lt;code&gt;node_modules/.bin&lt;/code&gt; ran instead of the real one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;HUSKY=0&lt;/code&gt;.&lt;/strong&gt; The &lt;a href="https://typicode.github.io/husky/how-to.html" rel="noopener noreferrer"&gt;how-to&lt;/a&gt; labels the variable "Temporarily disables all Git hooks", but the check sits in &lt;code&gt;.husky/_/h&lt;/code&gt;, inside the checkout, out of &lt;code&gt;git status&lt;/code&gt;. A replaced &lt;code&gt;.husky/_/pre-commit&lt;/code&gt; ran on a commit made with &lt;code&gt;HUSKY=0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lint-staged.&lt;/strong&gt; The &lt;a href="https://github.com/lint-staged/lint-staged" rel="noopener noreferrer"&gt;README&lt;/a&gt;: "Writing the configuration file in JavaScript is the most powerful way to configure lint-staged". With &lt;code&gt;npx lint-staged&lt;/code&gt; as the outside hook, the top level of &lt;code&gt;sub/lint-staged.config.js&lt;/code&gt; executed even with only a root file staged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A hook from main is as trustworthy as the scripts, configs and executables it calls, and here the agent wrote them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can the outside commit run no hooks?
&lt;/h2&gt;

&lt;p&gt;No hooks is not one flag. In these runs, commands at commit time came from the hooks directory, from hooks declared in git configuration, and from &lt;code&gt;core.fsmonitor&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--no-verify&lt;/code&gt; is narrower than it looks.&lt;/strong&gt; git-commit describes it as: "Bypass the pre-commit and commit-msg hooks." githooks says &lt;code&gt;prepare-commit-msg&lt;/code&gt; "is not suppressed by the --no-verify option", and &lt;code&gt;post-commit&lt;/code&gt; "is meant primarily for notification, and cannot affect the outcome of git commit." Both still ran with &lt;code&gt;--no-verify&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An empty hooks directory.&lt;/strong&gt; githooks: "By default the hooks directory is $GIT_DIR/hooks, but that can be changed via the core.hooksPath configuration variable". An empty directory or &lt;code&gt;/dev/null&lt;/code&gt; there kept all four hooks of the usual directory from running.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks in config, from Git 2.54.0.&lt;/strong&gt; git-config: "You can also disable all hooks entirely by setting core.hooksPath to /dev/null." On Git for Windows 2.56.0, &lt;code&gt;pre-commit&lt;/code&gt; and &lt;code&gt;post-commit&lt;/code&gt; hooks in the global config ran anyway, with &lt;code&gt;core.hooksPath&lt;/code&gt; at &lt;code&gt;/dev/null&lt;/code&gt; and at an empty directory. On 2.52.0, nothing ran.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;core.fsmonitor&lt;/code&gt;.&lt;/strong&gt; It holds "the pathname of the "fsmonitor" hook command". With one in the repository config, a commit with an empty hooks directory ran the command twice; &lt;code&gt;-c core.fsmonitor=false&lt;/code&gt; stopped it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The per-event switch, from Git 2.55.0.&lt;/strong&gt; &lt;code&gt;hook.&amp;lt;event&amp;gt;.enabled=false&lt;/code&gt; stopped a configured &lt;code&gt;pre-commit&lt;/code&gt; hook on 2.56.0, and the &lt;code&gt;pre-commit&lt;/code&gt; script in the hooks directory still ran. It goes beside an empty hooks directory, not in place of one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The recipe, as run in Git Bash on both versions on 15 October 2026, against a global config that held a &lt;code&gt;pre-commit&lt;/code&gt; hook entry and a &lt;code&gt;core.fsmonitor&lt;/code&gt; command:&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="c"&gt;# outside the box, after reading the diff&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /tmp/no-hooks &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; : &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/empty.gitconfig
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GIT_CONFIG_GLOBAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/empty.gitconfig &lt;span class="nv"&gt;GIT_CONFIG_NOSYSTEM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
git config &lt;span class="nt"&gt;--show-origin&lt;/span&gt; &lt;span class="nt"&gt;--get-regexp&lt;/span&gt; &lt;span class="s1"&gt;'^(hook\.|core\.fsmonitor)'&lt;/span&gt;   &lt;span class="c"&gt;# expect no output and exit code 1&lt;/span&gt;
git &lt;span class="nt"&gt;-c&lt;/span&gt; core.hooksPath&lt;span class="o"&gt;=&lt;/span&gt;/tmp/no-hooks &lt;span class="nt"&gt;-c&lt;/span&gt; core.fsmonitor&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; user.name&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Review Harness"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; user.email&lt;span class="o"&gt;=&lt;/span&gt;harness@example.invalid &lt;span class="se"&gt;\&lt;/span&gt;
    commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Agent change, reviewed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The check printed nothing and returned 1, and the commit ran neither. With the global config emptied, the author comes from &lt;code&gt;-c&lt;/code&gt;. If the check prints anything or returns other than 1, stop and read the entries. The check covers hook entries and &lt;code&gt;core.fsmonitor&lt;/code&gt; only; it is not a list of every setting that can run a command, which is why the &lt;code&gt;.git&lt;/code&gt; the commit is made from stays out of the agent's reach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where do the checks run instead?
&lt;/h2&gt;

&lt;p&gt;Inside the box, where the agent's tests already run. Among the inputs Carlos's article lists: "A test can execute code." and "A git hook can run before the commit you asked for." A test that runs the agent's code inside the box is what the box is for. A hook that runs the agent's code on the reviewer's machine, outside the box, is the failure described here.&lt;/p&gt;

&lt;p&gt;So checking the change and recording it are separate steps. Lint, tests and formatting run where the agent works; whoever makes the outside commit reads their result and the diff, and the commit itself runs no hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else in the agent's diff runs or loads later?
&lt;/h2&gt;

&lt;p&gt;A commit that runs no hooks settles what runs at the moment of the commit. It does not approve what the diff will run later, on another machine or in CI. Worth reading first: anything under the hooks path, such as &lt;code&gt;.husky/&lt;/code&gt;; &lt;code&gt;package.json&lt;/code&gt; scripts with their &lt;code&gt;pre&lt;/code&gt; and &lt;code&gt;post&lt;/code&gt; companions; lint-staged configs in any directory; CI workflow files. The same article: "Config files are persistence. If the agent can write to your shell config, IDE settings, git hooks or CI workflows, one bad step survives the session."&lt;/p&gt;

&lt;p&gt;Agent instructions and memory survive the session too. Anthropic's &lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory page&lt;/a&gt; for Claude Code: "Both are loaded at the start of every conversation. Claude treats them as context, not enforced configuration." A change to &lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;AGENTS.md&lt;/code&gt; or &lt;code&gt;.claude/&lt;/code&gt; in an agent's diff deserves the same reading as a change to CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article does not claim
&lt;/h2&gt;

&lt;p&gt;Measurements come from one Windows 11 machine on 15 October 2026. No results from Linux or macOS are reported, and Git 2.54.0 and 2.55.0 were not measured separately on Windows. The sandboxes of Claude Code and Codex were not run: they are described in their own words, not compared. The hook events measured at commit were &lt;code&gt;pre-commit&lt;/code&gt;, &lt;code&gt;prepare-commit-msg&lt;/code&gt;, &lt;code&gt;commit-msg&lt;/code&gt;, &lt;code&gt;post-commit&lt;/code&gt; and &lt;code&gt;reference-transaction&lt;/code&gt;; other settings that can run a command, such as &lt;code&gt;.gitattributes&lt;/code&gt; filter drivers or commit signing programs, were not measured.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Every quotation was read on 25 October 2026 with two instruments, a browser-like request and a reader service with its cache off (GitHub files also as raw files; five passages of git's pages that the reader drops were checked in git's own documentation sources instead); a made-up address on each host answered 404 as a control. The text describes those pages as of that date; the measurements were made on 15 October 2026 and are reported with that date. This article involves no Mnemoverse product, and every run used plain git and the tools named. A longer version, with every run and source, is in the Mnemoverse documentation library: &lt;a href="https://mnemoverse.com/docs/library/coding-agent-git-commit-hooks" rel="noopener noreferrer"&gt;Did you find a clean way to let the agent commit without giving it write access to the shared config?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-10-25&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>ai</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>If persistence is not permission, where would you have drawn the line: cards only, or the entire turn?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Thu, 29 Oct 2026 13:08:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/if-persistence-is-not-permission-where-would-you-have-drawn-the-line-cards-only-or-the-entire-gdp</link>
      <guid>https://dev.to/izgorodin/if-persistence-is-not-permission-where-would-you-have-drawn-the-line-cards-only-or-the-entire-gdp</guid>
      <description>&lt;p&gt;A RAG copilot answers a question, and the turn is stored with its source cards: which documents backed the answer, with names, versions and scores. A reload replays the conversation. Weeks later an admin revokes a permission. Should history still show the cards, the words, or nothing?&lt;/p&gt;

&lt;p&gt;Rodrigo Diego asked exactly that at the end of &lt;a href="https://dev.to/rdiegoss/chat-history-is-a-second-read-path-into-your-rag-data-gate-the-replay-like-the-search-10j0"&gt;his dev.to article of 25 August 2026&lt;/a&gt;, and the question in the title is his. The replay fight is real. It is also incomplete: search can be clean, history can be clean, and the document still returns.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A revocation has three points to reach, not two: search, the history replay, and the assembly of the next turn's context. Cards only and the entire turn are both replay lines. A narrow revocation does not reach what a stored thread already holds unless the assembly step checks it again.&lt;/li&gt;
&lt;li&gt;For what a person sees, two records are defensible: keep the delivered words and withhold the derived evidence, counting a verbatim quote as evidence, or replay the turn exactly as it was shown. Either way, say that the permission behind the turn is no longer granted.&lt;/li&gt;
&lt;li&gt;For what the model sees, compute the revoked state at every assembly against the permission as it is then, and never write it into the stored thread, so restoring the permission restores the result.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article reads one public thread as a case study, the article and its comments through 9 October 2026 (two of them by the author of this article), and quotes vendor documentation only for what it states.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is chat history a second read path into RAG data?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A second read path is any route other than search that returns data retrieved under a permission that may since have changed.&lt;/strong&gt; In the article's copilot, the history endpoint restores the conversation after a refresh and replays the stored source cards, so "your history endpoint becomes a second read path into the same data your search guards so carefully."&lt;/p&gt;

&lt;p&gt;The article opens with this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Persistence is not permission. What a turn was allowed to show at write time proves nothing about what it may show at read time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At write time the live path runs search, entitlement checks and a per-document view gate. At read time the history endpoint selects stored rows. Between the two, weeks pass, and tenant admins flip two toggles: the copilot itself and the document-search capability that produces the cards. Hence the article's rule: "Entitlements drift between write and read. Re-check authorization at read time, in the service, not just at the gateway." The check was scoped on purpose: "The gate is entitlement-level, not document-level."&lt;/p&gt;

&lt;h2&gt;
  
  
  Cards only, the entire turn, or the record as shown?
&lt;/h2&gt;

&lt;p&gt;The article's closing paragraph names three lines and picks one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When the document entitlement is revoked, I kept the words and withheld the evidence. A stricter shop would redact the whole turn; a looser one would replay everything and call the persisted rows an immutable record.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Its case for keeping the words: "the words were already delivered to this user once, and the toggle governs the document-search capability". Its own caveat: "The prose answer was generated from those documents and may paraphrase them."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/rdiegoss/comment/3good"&gt;By 8 October 2026&lt;/a&gt; the author had moved:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Turns now replay exactly as they were shown, cards included, and the document toggle governs what the next turn can do rather than what the record shows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/rdiegoss/comment/3gool"&gt;Another reply that day&lt;/a&gt; gives the mechanism: "Since the post, a turn's result blocks are written once at turn end, exactly as streamed, and the transcript replays them as seen. The document toggle scopes doing; the record stays the record." For the whole copilot: "Copilot off still means no history reads at all (now a typed 403), with every row intact and no deletion event."&lt;/p&gt;

&lt;p&gt;Two conditions hold for every replay line. Keeping a record and letting someone read it are separate decisions: the 8 October design keeps every row and still admits no history read when the copilot is off. And a notice that the permission is gone explains the policy; it does not enforce it. None of the replay lines decides what the model receives next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where does a revoked document get back into the next turn?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Context assembly is the step that builds the prompt for the next model call from the stored thread, the new message and any tool results.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/izgorodin/comment/3do0h"&gt;In the thread on 30 August 2026&lt;/a&gt;, the author of this article pointed at the gap: the checks on search and on the history read leave out what gets assembled into the prompt for the next turn. A document hidden after it sat inside an earlier exchange comes back, without touching either check, when that exchange returns as context. An illustration, not any team's system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;turn 1   search runs under the user's permission and returns document D
         the answer quotes D; the tool result and the answer go into the thread
revoke   an admin removes view permission on D (a narrow revocation)
replay   the history endpoint re-checks the permission and applies its replay line
turn 2   context assembly loads the thread, tool result and answer included
         unless assembly checks D again, the model receives D again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://dev.to/rdiegoss/comment/3gooo"&gt;On 8 October 2026&lt;/a&gt; Rodrigo Diego answered:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rebuilt from the stored thread, not re-derived from retrieval, so it's a genuine third gate and not a stricter second one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He described what the thread holds: "The next turn's context is assembled from a checkpointed thread that holds tool results retrieved under the old entitlement." And how far each revocation reaches: "Revoking the copilot entirely closes it, because no turn is admitted at all. A narrower revocation, like the document capability or view permission on a single document, doesn't reach what's already in the thread."&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Point&lt;/th&gt;
&lt;th&gt;What it reads&lt;/th&gt;
&lt;th&gt;Revoking one capability or one document&lt;/th&gt;
&lt;th&gt;Revoking the whole copilot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;The documents, live&lt;/td&gt;
&lt;td&gt;The live path checks entitlements and per-document view permission (article, 25 August)&lt;/td&gt;
&lt;td&gt;No turn is admitted (8 October)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;History replay&lt;/td&gt;
&lt;td&gt;Stored turns and their cards&lt;/td&gt;
&lt;td&gt;Document capability: cards withheld (25 August). One document: not re-checked on replay, the gate is entitlement-level (25 August). Either: the turn as shown (8 October)&lt;/td&gt;
&lt;td&gt;No history reads at all, every row intact (8 October)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next-turn assembly&lt;/td&gt;
&lt;td&gt;The checkpointed thread, tool results included&lt;/td&gt;
&lt;td&gt;Does not reach what is already in the thread (8 October)&lt;/td&gt;
&lt;td&gt;No turn is admitted (8 October)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;He named where a check would go: "The assembly step already rewrites history on every model call (guardrail scoping, tool-call repair, version stamps on document-bearing results), so that's where re-authorization would live." That is a location, not a shipping report. The precedent is in the same design: a turn cut short gets an explicit message in place of the missing tool result, "so the model sees the gap rather than a shorter conversation. A revoked result deserves the same treatment."&lt;/p&gt;

&lt;h2&gt;
  
  
  What counts as evidence: the words or the cards?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Delivered speech is answer text that was already shown to this reader. A derived artifact is anything that exists because a retrieval ran under a permission: source cards, document names, versions, scores, and text that reproduces a document verbatim.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/heinrichneb/comment/3dh1l"&gt;Heinrich Neb refined the article's line on 25 August 2026&lt;/a&gt;: the boundary is not text against cards but delivered speech against derived artifacts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;text that VERBATIM quotes a document is a card wearing prose.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For text that mixes both, his rule: "Where provenance is segmentable, redaction should follow it per segment; where it isn't (paraphrase), keeping the words is defensible because they were already delivered". &lt;a href="https://dev.to/rdiegoss/comment/3gooi"&gt;On 8 October 2026&lt;/a&gt; the author called delivered speech against derived artifact "the line I should have drawn", and wrote in the same reply that "a revoked capability now governs the next turn, not the record".&lt;/p&gt;

&lt;p&gt;That settles what a person sees, not what the model receives, because the answer text changes role. &lt;a href="https://dev.to/izgorodin/comment/3h2l4"&gt;As the author of this article put it on 9 October 2026&lt;/a&gt;: shown back to the user, the answer is record, and the argument that it was already delivered still holds. Fed back to the model, it is material for the next turn, which is what the revocation should reach. If that answer quoted a revoked result, the model can restate a claim it once grounded with nothing left to check it against.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why compute the revoked marker at assembly instead of writing it to the thread?
&lt;/h2&gt;

&lt;p&gt;Because the two facts age differently. In the same exchange on 9 October 2026, the author of this article put it this way: "This did not complete" is a fact about that turn and stays true forever, while "this was revoked" is a fact about the current entitlement and stops being true the moment the permission comes back. Written back into the checkpoint, the placeholder has already destroyed the result by the time a revocation is undone. Computed per call, there is nothing to undo: the next assembly reads the restored permission and includes the result again.&lt;/p&gt;

&lt;p&gt;Treat the stored thread as the record and the assembled context as a permission-filtered view of it. A sketch, not an API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for result in thread.tool_results:
    if not entitled_now(result):
        yield unavailable_placeholder(result)   # computed per call, never written back
    else:
        yield result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sketch covers tool results only; an answer that quoted a result needs provenance on the answer text as well.&lt;/p&gt;

&lt;p&gt;Documentation built for context management, not for permissions, shows the same shape. LangGraph: "Checkpointers persist a thread’s graph state as checkpoints." LangChain's transient context is "What the LLM sees for a single call. You can modify messages, tools, or prompts without changing what’s saved in state." Summarization works the other way, "permanently replacing old messages with a summary that’s saved for all future turns." A revoked marker belongs on the transient side. Anthropic's context editing splits the same way on the server: "Context editing is applied server-side before the prompt reaches Claude. Your client application maintains the full, unmodified conversation history." Only the shape is borrowed here: a change made when the prompt is assembled, without writing to what is stored.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should a replayed turn say when the permission behind it is gone?
&lt;/h2&gt;

&lt;p&gt;Silence is a third product decision, and the thread argued against it. &lt;a href="https://dev.to/heinrichneb/comment/3dh1l"&gt;Heinrich Neb, on 25 August 2026&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'd stamp the replayed turn with "generated under an entitlement no longer granted" rather than silently replaying it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/rdiegoss/comment/3gooi"&gt;Rodrigo Diego, on 8 October 2026&lt;/a&gt;, after the move to replay as shown: "If the record replays as seen, the honest version tells the reader the capability behind it is no longer granted, and the replay response carries no field for that today." &lt;a href="https://dev.to/kartik-nvjk/comment/3di80"&gt;Kartik N V J K, on 26 August 2026&lt;/a&gt;, had already stored what such a notice needs: "I started snapshotting the doc IDs and the entitlement version onto each turn so a replay can diff against current access, not just re-render."&lt;/p&gt;

&lt;p&gt;The stamp is a display concern; the snapshot is a diff input. The recommendation here: a replayed turn keeps what the record holds and carries a status computed at read time against the reader's current permission, in the replay response itself, so that every client can show it. That is a recommendation, not a reported implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does gating the response keep revoked data out of the service?
&lt;/h2&gt;

&lt;p&gt;Only if the policy concerns the response alone. The article's second gate withheld the cards in the response builder, and &lt;a href="https://dev.to/rdiegoss/comment/3gool"&gt;the author confirmed on 8 October 2026&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The revoked payload was selected, normalized and held in memory, and only serialization was gated, so a traceback, a payload-capturing span or a debug dump would all have seen it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keeping cards out of a response and out of the request's data path are different properties. The author agreed with the alternative: "Driving the column list from the entitlement (already loaded by then), with a not-selected negative control, is the right shape". The first gate had the stronger property, and a test for it: "The test pins this: when the toggle is off, the session and turn queries are never even awaited." A test that proves the protected read never ran says more than a test of the response shape.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can a cache in front of the history endpoint replay what was revoked?
&lt;/h2&gt;

&lt;p&gt;A check in the service protects the requests that reach the service. &lt;a href="https://dev.to/vinhnguyenthanhdn/comment/3dh4e"&gt;Vinh Nguyen, on 26 August 2026&lt;/a&gt;: "If the endpoint is cacheable, the cache key has to include tenant plus entitlement version, or revocation must purge it". His test: "A negative test that warms the cache before revocation and replays after would cover the read path the mocked database test cannot see."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/rdiegoss/comment/3gooj"&gt;The author agreed on 8 October 2026&lt;/a&gt;: without an explicit cache header, "nothing caches this" is "an assumption about whatever sits in front of the service, not a property of the service." His remedy: "Cache-Control: no-store on the history routes is the cheap fix that makes the guarantee local, and your warm-then-revoke-then-replay test is the one that proves it end to end."&lt;/p&gt;

&lt;h2&gt;
  
  
  How do assistants and memory APIs document this?
&lt;/h2&gt;

&lt;p&gt;Two examples, each in its own words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microsoft Copilot.&lt;/strong&gt; &lt;a href="https://learn.microsoft.com/en-us/microsoft-365/copilot/microsoft-365-copilot-privacy" rel="noopener noreferrer"&gt;Data, Privacy, and Security for Microsoft Copilot&lt;/a&gt;: "Microsoft Copilot only surfaces organizational data to which individual users have at least view permissions." On stored history: "The stored data includes the user's prompt and Copilot's response, including citations to any information used to ground Copilot's response." Stored history there carries citations too, which is the surface this article is about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mnemoverse&lt;/strong&gt; (the author's company). In shared-memory rooms (beta), "an expired or revoked grant stops working on the very next request." The &lt;a href="https://mnemoverse.com/docs/api/rooms" rel="noopener noreferrer"&gt;rooms reference&lt;/a&gt; states the boundary: "Revocation is immediate and forward-only. A revoked member loses access from that moment on. There is no retroactive un-sharing: whatever the member already read, it keeps, and atoms it wrote remain in the room." Access can come back: "Re-inviting a revoked member restores access." This is the record-stays-the-record position at the level of a memory API. The next turn is assembled in the client that reads from the API, so the third point still needs its own check there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which tests prove the permission line holds?
&lt;/h2&gt;

&lt;p&gt;Five tests, one per decision.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Not awaited.&lt;/strong&gt; With the copilot entitlement off, request history and assert that the session and turn queries never ran, not only that the response is empty. This is the article's own test of its first gate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not selected.&lt;/strong&gt; Where a policy forbids reading a field once access is revoked, assert that the field was never selected, not nulled in the response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warm, revoke, replay.&lt;/strong&gt; Warm any cache in front of the history route, revoke, replay through the same route, and assert the current replay policy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revoke, continue.&lt;/strong&gt; Revoke one document's permission after an exchange that used it, and continue. Assert that the assembled input carries an explicit marker in place of the tool result and of any quotation of it in the answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restore, continue.&lt;/strong&gt; Restore the permission and continue. Inspect the stored thread itself, not the model output, and assert that it still holds the original result with no placeholder written into it; then assert that the next assembly includes the result again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A passing replay test does not establish the continuation result; a passing continuation test does not establish that restoration works.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article does not claim
&lt;/h2&gt;

&lt;p&gt;No performance or latency figure for anyone; the author of the original design did not measure one. Positions are dated, because the article of 25 August 2026 and the replies of 8 October 2026 differ. Product documentation is quoted for what it states; where a page says nothing about revocation, this article says nothing either, and it tests no product. Apart from the first test, which the original article describes as its own, the tests are proposals, not a description of any team's suite.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Every quotation was read on 25 October 2026 with two instruments: a browser-like request and a reader service with its cache off, and for dev.to comments the comment page and the dev.to API. A made-up address on each host answered 404 as a control. The text describes those sources as of that date. A longer version, with the full list of sources, is in the Mnemoverse documentation library: &lt;a href="https://mnemoverse.com/docs/library/revoked-access-chat-history" rel="noopener noreferrer"&gt;If persistence is not permission, where would you have drawn the line: cards only, or the entire turn?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-10-25&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>Is AI code review good?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:16:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/is-ai-code-review-good-2ofe</link>
      <guid>https://dev.to/izgorodin/is-ai-code-review-good-2ofe</guid>
      <description>&lt;p&gt;Uber writes that its AI code review platform, uReview, treats automation "not as a substitute for human insight, but as a scalable partner that enhances engineering productivity", and reports over 65% of uReview's posted comments addressed, counting a comment as addressed when five re-runs on the final commit no longer produce a similar one. DoorDash reports that 60.2% of settled high and critical findings ended with the engineer changing code before merge (n=2,256). Atlassian reports 38.70% of its reviewer's comments followed by a code change in the next commit, and a 44.45% resolution rate for human comments. Each company counts a different event, so these are three counting rules rather than one score, and none shows whether a comment caught what mattered.&lt;/p&gt;

&lt;p&gt;Every number below comes from the company's or the authors' own page as I read it on 25 October 2026; none of them saw this text before publication.&lt;/p&gt;

&lt;h2&gt;
  
  
  What companies measured on their own pull requests
&lt;/h2&gt;

&lt;p&gt;Seven sources report what an AI reviewer did on real pull requests, each with its own counting rule and its own scale.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Who, when&lt;/th&gt;
&lt;th&gt;What they counted&lt;/th&gt;
&lt;th&gt;What they report, with the counting rule&lt;/th&gt;
&lt;th&gt;Scale and period&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;An AI review tool at one company, in a study presented at ICSE 2025 (arXiv, revised 28 December 2024)&lt;/td&gt;
&lt;td&gt;automated comments that developers acted on; time to close a pull request&lt;/td&gt;
&lt;td&gt;"73.8% of automated comments were resolved.", counted from "comment labels indicating whether developers acted on the automated comments". Average pull request closure time went from five hours 52 minutes to eight hours 20 minutes, "with varying trends across projects".&lt;/td&gt;
&lt;td&gt;"three projects with 4,335 pull requests, 1,568 of which underwent automated reviews"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft, Engineering@Microsoft, 14 July 2025&lt;/td&gt;
&lt;td&gt;median time to complete a pull request&lt;/td&gt;
&lt;td&gt;Median PR completion time improved by 10 to 20 percent in 5,000 repositories onboarded to Microsoft's AI reviewer, by what the post calls early experiments and data science studies.&lt;/td&gt;
&lt;td&gt;the reviewer "started as an internal experiment and now has scaled to support over 90% of PRs across the company impacting more than 600K pull requests per month"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uber, uReview, 12 August 2025&lt;/td&gt;
&lt;td&gt;posted comments addressed in the same changeset; comments rated useful&lt;/td&gt;
&lt;td&gt;Over 65% of posted comments were addressed, where a comment counts as addressed when none of five re-runs of uReview on the final commit reproduces a semantically similar comment. "Engineers who interact with the tool mark 75% of its comments as useful". Separately, "Internal audits show that only 51% of human-written comments are considered as bugs by the author and addressed in the same changeset."&lt;/td&gt;
&lt;td&gt;"Each week, uReview processes over 10,000 commits, excluding configuration files."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic, Code Review launch article, 9 March 2026&lt;/td&gt;
&lt;td&gt;findings that Anthropic's engineers marked incorrect; pull requests with substantive review comments; both on Anthropic's own pull requests&lt;/td&gt;
&lt;td&gt;"Engineers largely agree with what it surfaces: less than 1% of findings are marked incorrect." and "Before, 16% of PRs got substantive review comments. Now 54% do."&lt;/td&gt;
&lt;td&gt;"We run Code Review on nearly every PR at Anthropic."; "We've been running Code Review internally for months"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atlassian, its AI code reviewer, post of 7 April 2026 and a paper accepted at ICSE 2026&lt;/td&gt;
&lt;td&gt;comments followed by a code change in the next commit; median PR cycle time&lt;/td&gt;
&lt;td&gt;38.70% of the reviewer's generated comments "led directly to code changes in the subsequent commit", and the resolution rate for human comments was 44.45%. Median PR cycle time fell by 30.8%.&lt;/td&gt;
&lt;td&gt;"a year-long, large-scale online evaluation across over 1,900 repositories"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare, 20 April 2026&lt;/td&gt;
&lt;td&gt;times engineers overrode the reviewer with a break glass comment; findings per review&lt;/td&gt;
&lt;td&gt;When a person comments break glass, "the system forces an approval regardless of what the AI found"; engineers needed it 288 times, 0.6% of merge requests. "That is about 1.2 findings per review on average", a number Cloudflare calls "deliberately low".&lt;/td&gt;
&lt;td&gt;48,095 merge requests in 5,169 repositories, 10 March to 9 April 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DoorDash, 11 May 2026&lt;/td&gt;
&lt;td&gt;settled high and critical findings followed by a code change before merge&lt;/td&gt;
&lt;td&gt;"60.2% of settled high and critical findings result in the engineer changing code before merge (n=2,256), up from a 46% acceptance rate with our previous third-party review agent." The rule: "We measure this on if the human acted on it or not."&lt;/td&gt;
&lt;td&gt;"more than 10,000 pull requests across 56 onboarded repositories" in a typical week&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each row comes from the company's or the authors' own page, read on 25 October 2026; the rows count different things, so no number in one row compares with a number in another.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each number counts
&lt;/h2&gt;

&lt;p&gt;Most of these numbers count what engineers did after the reviewer spoke, and the event counted changes from page to page. Uber automates its count: "It automatically evaluates if a given posted comment has been addressed by re-running uReview five times on the final commit." Its 75% comes from the engineers who interact with the tool, who can rate each comment as useful or not useful. DoorDash's 60.2% counts only settled findings of high and critical severity, and its 46% belongs to the third-party review agent it used before.&lt;/p&gt;

&lt;p&gt;Atlassian counts a comment when the next commit changes the code; its ICSE 2026 paper describes the same 38.70% as "comments that triggered code changes in the subsequent commits". Anthropic counts the findings its own engineers marked incorrect, on its own pull requests. Cloudflare's 0.6% counts the times engineers overrode the reviewer's verdict. Microsoft's figure is a change in time, not a count of comments, and the ICSE 2025 study counts labels on each automated comment.&lt;/p&gt;

&lt;p&gt;GitHub defines the "addressed rate" of Copilot code review (CCR) with a model as the judge: it "is the percentage of CCR comments that an LLM determines prompted a developer to make a corresponding code change, based on the diff, thread, reactions, resolution state, and post-review code." A study of 2,604 bot comments at Beko, accepted to EASE 2026, compared two automated ways of grading such comments, G-Eval and an LLM-as-a-Judge pipeline, with the fixed or wontFix label an engineer gave each one, and found "Agreement ratios range from approximately 0.44 to 0.62". Its authors add that "Developer actions such as resolving or ignoring comments reflect not only comment quality, but also contextual constraints, prioritization decisions, and workflow dynamics that are difficult to capture through static artifacts."&lt;/p&gt;

&lt;p&gt;A comment that was acted on is not always a comment that caught something important; &lt;a href="https://medium.com/@izgorodin/has-your-ai-reviewer-ever-caught-something-your-team-missed-that-actually-mattered-9b85f060cb92" rel="noopener noreferrer"&gt;Has your AI reviewer ever caught something your team missed that actually mattered?&lt;/a&gt; is about telling the two apart on your own pull requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  What research sets built from human reviews find
&lt;/h2&gt;

&lt;p&gt;Research sets start from issues that human reviewers flagged and ask how many of them an AI finds, which is a different question from whether engineers act on AI comments. SWE-PRBench, posted to arXiv on 27 March 2026 as "a benchmark of 350 pull requests with human-annotated ground truth", reports that "8 frontier models detect only 15-31% of human-flagged issues on the diff-only configuration", scored by an LLM judge "validated at kappa=0.75"; these are models given a diff, not review products. c-CRAB, posted to arXiv on 24 March 2026 and "systematically constructed from human reviews", evaluated one open-source and three commercial review agents and reports that "the existing review agents taken together can solve only around 40% of the c-CRAB tasks". Benchmarks that vendors run on their own tools use their own judges and datasets, and &lt;a href="https://dev.to/izgorodin/should-we-trust-ai-code-review-benchmarks-3p6n"&gt;Should we trust AI code review benchmarks?&lt;/a&gt; goes through how they are built.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the teams behind these numbers post fewer comments
&lt;/h2&gt;

&lt;p&gt;Uber, DoorDash, Cloudflare and Atlassian each put a filter between the model and the pull request, and three of them say plainly that they chose fewer comments over more. Uber writes "Early in development, we learned that comment quality matters far more than quantity." and "To preserve trust, we focused on delivering fewer but more useful comments."; its category classifier "suppresses those from categories with historically low developer value", and "Readability nits, minor logging tweaks, low-impact performance optimizations, and stylistic issues consistently received poor ratings."&lt;/p&gt;

&lt;p&gt;At DoorDash, "Before any comment is posted, it has to survive a disprove-it pass, an explicit step where the system tries to falsify its own finding." The post ties its number to that choice: "The 60% acceptance number is the output of that tradeoff. We'd rather miss some issues than become noise. A reviewer that's muted catches nothing." Cloudflare explains its average of 1.2 findings per review with "We biased hard for signal over noise". Atlassian runs a model judge that "acts as a gatekeeper, reviewing every generated comment for factual correctness against the code change", then a classifier trained "to classify comments based on whether they led to a code resolution".&lt;/p&gt;

&lt;p&gt;Sriramprabhu Rajendran, an engineering leader who wrote on dev.to on 12 October 2026 about adding an LLM reviewer to a Java and Spring Boot pull request process, gives one rule for that reviewer: "The false positive rate should be kept under 15%. Otherwise, developers will dismiss all comments."&lt;/p&gt;

&lt;p&gt;Two products describe a check of the same kind on their own pages. Anthropic's docs for Claude Code Review say "A verification step checks findings against the code before they're reported.", and CodeRabbit's architecture page lists a Verification agent among the agents that work in parallel on a review. Sigma (Mnemoverse, the author's company), a reviewer for GitHub pull requests in closed beta, is described on its homepage as "A useful second look". Its docs describe a fresh verifier that "confirms, rejects or reclassifies each one" of the candidate issues, say "only confirmed candidates are verified findings" while suspicions no verifier confirmed stay labeled separately, and add "A verification label is agent-produced evidence, not proof that the code is correct." Sigma runs on Claude Code and OpenAI models. Teams can request access on its homepage, which says "A request does not grant access automatically."&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not replace
&lt;/h2&gt;

&lt;p&gt;Five of the companies that built these reviewers write that it works next to people, not in their place. DoorDash writes "The agent is not trying to replace human review.", Atlassian "Code reviewer isn't meant to replace human judgment", and Cloudflare "This isn't a replacement for human code review, at least not yet with today's models." Uber designed uReview "to augment the code review process with a second AI reviewer", and Microsoft gives its goal as "freeing human reviewers to focus on higher-level concerns".&lt;/p&gt;

&lt;p&gt;Time moves in both directions in these reports. Atlassian measured a 30.8% reduction in median PR cycle time over its year of evaluation. Microsoft reports a 10 to 20 percent improvement in median PR completion time from its early experiments and data science studies. In the study presented at ICSE 2025, the authors write that the tool "proved useful in software development, enhancing bug detection", while average pull request closure time grew from five hours 52 minutes to eight hours 20 minutes, and they name "drawbacks like faulty reviews, unnecessary corrections, and irrelevant comments".&lt;/p&gt;

&lt;p&gt;Anthropic's docs for Claude Code Review state the limit plainly: "A review with no findings doesn't mean your code is error-free or secure."&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and method
&lt;/h2&gt;

&lt;p&gt;The numbers are quoted with the counting rule each page gives, none of them was recomputed, the table rows run in order of publication, and each quotation was checked word for word against its page on the reading day.&lt;/p&gt;

&lt;p&gt;Sources, all read on 25 October 2026; this text describes them as of that date. Uber: &lt;a href="https://www.uber.com/us/en/blog/ureview/" rel="noopener noreferrer"&gt;uReview&lt;/a&gt;. DoorDash: &lt;a href="https://careersatdoordash.com/blog/doordash-built-an-ai-code-reviewer-engineers-actually-listen-to/" rel="noopener noreferrer"&gt;an AI code reviewer engineers listen to&lt;/a&gt;. Atlassian: &lt;a href="https://www.atlassian.com/blog/ai-at-work/developer-productivity-improved-with-rovo-dev" rel="noopener noreferrer"&gt;code reviewer post&lt;/a&gt;, &lt;a href="https://arxiv.org/abs/2601.01129" rel="noopener noreferrer"&gt;ICSE 2026 paper&lt;/a&gt;. Microsoft: &lt;a href="https://devblogs.microsoft.com/engineering-at-microsoft/enhancing-code-quality-at-scale-with-ai-powered-code-reviews/" rel="noopener noreferrer"&gt;AI-powered code reviews&lt;/a&gt;. Cloudflare: &lt;a href="https://blog.cloudflare.com/ai-code-review/" rel="noopener noreferrer"&gt;AI code review at scale&lt;/a&gt;. Anthropic: &lt;a href="https://claude.com/resources/articles/code-review" rel="noopener noreferrer"&gt;Code Review launch&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review" rel="noopener noreferrer"&gt;Code Review docs&lt;/a&gt;. GitHub: &lt;a href="https://github.blog/ai-and-ml/github-copilot/reviewbench-an-open-benchmark-for-ai-code-review/" rel="noopener noreferrer"&gt;ReviewBench&lt;/a&gt;. CodeRabbit: &lt;a href="https://docs.coderabbit.ai/overview/architecture" rel="noopener noreferrer"&gt;architecture&lt;/a&gt;. Studies: &lt;a href="https://arxiv.org/abs/2412.18531" rel="noopener noreferrer"&gt;Automated Code Review In Practice, ICSE 2025&lt;/a&gt;, &lt;a href="https://arxiv.org/abs/2604.24525" rel="noopener noreferrer"&gt;automated evaluation of review bots at Beko, EASE 2026&lt;/a&gt;, &lt;a href="https://arxiv.org/abs/2603.26130" rel="noopener noreferrer"&gt;SWE-PRBench&lt;/a&gt;, &lt;a href="https://arxiv.org/abs/2603.23448" rel="noopener noreferrer"&gt;c-CRAB&lt;/a&gt;. Sriramprabhu Rajendran: &lt;a href="https://dev.to/rsri/llm-code-reviews-are-not-what-you-think-an-opinionated-take-on-ai-assisted-quality-3ia"&gt;LLM Code Reviews Are Not What You Think&lt;/a&gt;. Sigma: &lt;a href="https://sigma.mnemoverse.com/?src=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=is-ai-code-review-good" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://sigma.mnemoverse.com/docs/reading-a-review?src=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=is-ai-code-review-good" rel="noopener noreferrer"&gt;reading a review&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>softwareengineering</category>
      <category>devops</category>
    </item>
    <item>
      <title>Which AI is best for code review?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Tue, 27 Oct 2026 13:14:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/which-ai-is-best-for-code-review-298k</link>
      <guid>https://dev.to/izgorodin/which-ai-is-best-for-code-review-298k</guid>
      <description>&lt;p&gt;The question has two readings, a review tool or its model, and on most hosted tools they are one choice, because the vendor picks the model: GitHub says of Copilot code review "Model switching is not supported", Anthropic's Code Review "chooses the Claude models that reviews run on", and CodeRabbit and Sourcery name OpenAI and Anthropic; PR-Agent runs the model you choose. No vendor page settles which tool: each reports accuracy in its own metric on its own data, and in the table of &lt;a href="https://dev.to/izgorodin/should-we-trust-ai-code-review-benchmarks-3p6n"&gt;Should we trust AI code review benchmarks?&lt;/a&gt; every vendor-run comparison against other tools puts its author first. Named most often on 27 best-of lists I read on 25 October 2026 are CodeRabbit, GitHub Copilot, Greptile and Qodo; vendors wrote some of those lists. How often a tool is right on your code is a number you count yourself over two weeks: findings fixed against findings dismissed.&lt;/p&gt;

&lt;p&gt;Every fact about a tool below comes from that tool's own pages as I read them on 25 October 2026; the counts come from 27 best-of lists read the same day; none of the vendors saw this text before publication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which model does each reviewer run on?
&lt;/h2&gt;

&lt;p&gt;On most hosted review tools the vendor picks the model. Copilot code review: "Model switching is not supported". Anthropic: "Code Review chooses the Claude models that reviews run on", with no model choice in its admin settings. Cursor: "Bugbot uses a combination of frontier and in-house models to review code." CodeRabbit: "Your code is shared with OpenAI and/or Anthropic for reviewing purposes only". Graphite: "Many of our AI features are powered through partnerships with Anthropic and OpenAI, who currently act as our AI subprocessors." Sourcery sends "the relevant sections of the diff and the surrounding code context to two LLM providers, OpenAI and Anthropic." Greptile: "Greptile uses third-party LLM providers for AI inference." Codex code review is OpenAI's own product. PR-Agent is the one where you choose, among models it lists "and any other model reachable through LiteLLM". Outside PR-Agent and some self-hosted or bring-your-own-key setups, choosing a review tool chooses its model as well, so the model question comes back to the same count on your own pull requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  How each reviewer says it checks a finding before you see it
&lt;/h2&gt;

&lt;p&gt;Each cell is from the vendor's own pages, read on 25 October 2026; "not stated" means not found on the pages listed at the end that day. Rows follow the number of lists that name the tool.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What its pages say happens before a comment is posted&lt;/th&gt;
&lt;th&gt;What its pages say about its own limits&lt;/th&gt;
&lt;th&gt;Named on, of 27 lists&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;"Specialized AI agents working in parallel: Review, Verification, Chat, Pre-Merge Checks"&lt;/td&gt;
&lt;td&gt;on its security check of a pull request: "A successful or neutral result does not guarantee that the code has no security issues."&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot code review&lt;/td&gt;
&lt;td&gt;GitHub's blog: "Silence is better than noise."&lt;/td&gt;
&lt;td&gt;"Copilot is not guaranteed to spot all problems or issues in a pull request. Sometimes it will make mistakes."; "Copilot may repeat the same comments again, even if they have been dismissed"&lt;/td&gt;
&lt;td&gt;26, counting any mention of Copilot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greptile&lt;/td&gt;
&lt;td&gt;"TREX runs your PR branch in a sandbox to catch the bugs that only show up at runtime."; its docs changelog says "TREX is generally available" in an entry dated 16 October 2026, while the homepage menu still says "TREX: Runtime Validation Beta"&lt;/td&gt;
&lt;td&gt;an organization turns TREX on in its settings, and a run is billed apart from the code review; on its auto-approval feature: "Do not enable it broadly across all PRs."&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;several review agents, "filtering out low-impact or irrelevant comments before they reach the pull request"&lt;/td&gt;
&lt;td&gt;not stated; a finding you tell Qodo does not apply is recorded as "False positive, Rejected, Deferred, or Intentional"&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor Bugbot&lt;/td&gt;
&lt;td&gt;"Bugbot detects the hardest logic bugs with a low false positive rate."; it reads earlier comments on the pull request, which "helps avoid duplicate suggestions"&lt;/td&gt;
&lt;td&gt;on what a review takes in: "Each rule is truncated at 30,000 characters when included in a review."; "Bugbot doesn't read the contents of files whose path looks like a credential file"&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code (Anthropic)&lt;/td&gt;
&lt;td&gt;managed Code Review: "A verification step checks findings against the code before they're reported."; &lt;code&gt;/code-review&lt;/code&gt; in the terminal, at its &lt;code&gt;low&lt;/code&gt; effort level: "the review reports the findings it's most confident in, so you see fewer false positives"&lt;/td&gt;
&lt;td&gt;"Code Review uses AI to review code and may miss bugs, security vulnerabilities, or other issues."; "A review never approves or blocks the pull request, so the decision to merge stays with your team."&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graphite Agent&lt;/td&gt;
&lt;td&gt;for comment exclusions you set: "This reduces noise and focuses AI reviews on what matters most to your team."&lt;/td&gt;
&lt;td&gt;on custom rule files: "Too many files can reduce review quality"&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI Codex code review&lt;/td&gt;
&lt;td&gt;"In GitHub, Codex flags only P0 and P1 issues so review comments stay focused on high-priority risks."&lt;/td&gt;
&lt;td&gt;"Code review rules guide Codex; they don't replace tests, branch protections, or required approvals."&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sourcery&lt;/td&gt;
&lt;td&gt;the Quiet review profile "posts only the highest-priority comments."; the default "posts all but the lowest-priority ones."&lt;/td&gt;
&lt;td&gt;on its own findings report: "The report counts findings and can't tell you which ones are false positives."&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sigma (Mnemoverse, the author's company)&lt;/td&gt;
&lt;td&gt;"Sigma checks potential issues and brings the evidence back to your code."; "A fresh verifier confirms, rejects or reclassifies each one", and "only confirmed candidates are verified findings"&lt;/td&gt;
&lt;td&gt;candidates no verifier confirmed are listed apart under "Unverified suspicions"; its docs call them "leads, not findings"&lt;/td&gt;
&lt;td&gt;added outside that count&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every cell in the second column is a description, not a measurement; how often each check is right on your code is what the count at the end of this page measures.&lt;/p&gt;

&lt;p&gt;The last row is a reviewer for GitHub pull requests in closed beta, described by its homepage and docs only. Sigma runs on Claude Code and OpenAI models. Its homepage takes requests through a "Request beta access" form and says "A request does not grant access automatically."&lt;/p&gt;

&lt;h2&gt;
  
  
  Does it read the diff, the files or the whole repository?
&lt;/h2&gt;

&lt;p&gt;A reviewer that reads only the lines in the diff can miss how a change breaks code elsewhere, so what each tool reads is part of the answer. The vendors put it in different words. GitHub lists "Full project context gathering" for Copilot code review and says "This capability analyzes your entire repository to better understand the context of code changes."; the review "runs in an ephemeral development environment, similar to Copilot cloud agent." CodeRabbit's architecture page lists "Sandboxed cloud execution with your full repository cloned for isolated analysis". Qodo writes "Specialized review agents reason over full codebase context to flag real bugs, rule violations, and requirements gaps with less noise." Graphite says its AI reviews analyze "your entire codebase to provide relevant feedback". Greptile's homepage describes "AI agents that review and test pull requests with full context of the codebase.", its docs say a review builds context "from your entire codebase, not just the diff", and its TREX also runs the pull request branch in a sandbox; Greptile's docs changelog says "TREX is generally available" in an entry dated 16 October 2026, and its TREX docs say that an organization turns TREX on in its settings and that a run is billed apart from the code review.&lt;/p&gt;

&lt;p&gt;Others describe a narrower or more specific read. Anthropic's Code Review docs say "Several agents read each change alongside the surrounding code" and that a review works "without building or running your code". Sourcery "reads the diff of the changed code" and, for some changes, "supplements the diff with related code from your repository". Codex "reviews the pull request diff, follows your repository guidance". Cursor says Bugbot "reads both top-level and inline pull request comments from connected providers and includes them as context during reviews", and it reads project rules from &lt;code&gt;.cursor/BUGBOT.md&lt;/code&gt; files. None of these sentences says how often the tool is right; whether a wider read means fewer misses on your code is what the count at the end of this page measures.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the best AI code review tool?
&lt;/h2&gt;

&lt;p&gt;No list can answer this for your code, but the lists can be counted. On 25 October 2026 I read again the 28 tool lists that web searches for lists of AI code review tools returned on 9 October; 27 answered, and one returned a server error on three attempts, so every count on this page is out of 27. A tool counts when the page names it. That measures mentions, not use or quality, and some lists are written by vendors whose own tool is on them, so the table gives the count with and without such lists.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Named on, of 27 lists&lt;/th&gt;
&lt;th&gt;Without lists written by the tool's own vendor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot&lt;/td&gt;
&lt;td&gt;26, counting any mention of Copilot; Copilot code review by name on 20&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greptile&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor Bugbot&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Next by count, among names with a pull request reviewer, are PR-Agent (15), Claude Code (14), Graphite (12), Codex (11) and Sourcery (10), each counting any mention of the name. SonarQube, a static analysis platform whose maker sells a separate AI review product, is named on 19 of the 27, more often than Bugbot, and has its own section below. Sigma appears in the tables of this page outside that count.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best AI PR code reviewer?
&lt;/h2&gt;

&lt;p&gt;For a pull request reviewer, the pages differ most on where your code can live, what the bill counts, and whether the reviewer can run inside your own infrastructure.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Code hosts&lt;/th&gt;
&lt;th&gt;What you pay for&lt;/th&gt;
&lt;th&gt;Self-hosting&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;GitHub, including GitHub Enterprise Server; GitLab, including self-managed; Azure DevOps; Bitbucket Cloud and Bitbucket Data Center&lt;/td&gt;
&lt;td&gt;each developer who creates pull requests: Essentials $24 per developer per month billed annually, $30 monthly; 5 PR reviews per hour per developer on Essentials, then $0.25 per reviewed file only with usage-based reviews turned on; the Free plan gives "PR summarization only; code reviews are available through the VS Code extension and CLI."; "Open-source projects receive Team features with no paid subscription required."&lt;/td&gt;
&lt;td&gt;Enterprise "with 500 or more user seats"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot code review&lt;/td&gt;
&lt;td&gt;GitHub.com; "Azure DevOps (public preview)"; "Copilot is not currently available for GitHub Enterprise Server."&lt;/td&gt;
&lt;td&gt;AI credits from the plan's monthly allowance, which GitHub estimates per review at $0.05 to $1 USD on Lite effort and $0.25 to $5 USD on Balanced; also GitHub Actions minutes for context gathering and tool use, except on self-hosted runners; "Available for all paid Copilot plans", not on Copilot Free, while maintainers of popular open source projects may be eligible for free Copilot Pro; on Copilot Business and Enterprise an organization can also let members without a Copilot license use it&lt;/td&gt;
&lt;td&gt;its agentic capabilities run on GitHub Actions, and GitHub says you can "use self-hosted runners" for them; a self-hosted review service was not found on the code review page as of 25 October 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greptile&lt;/td&gt;
&lt;td&gt;GitHub, GitLab, Bitbucket, Cursor Origin; on Enterprise also GitHub Enterprise Server, GitHub Enterprise Cloud with data residency, GitLab Self-Managed, Bitbucket Data Center and Gitea, and Perforce through P4 Code Review for on-premises deployments&lt;/td&gt;
&lt;td&gt;Pro $1 per credit with no seat fees, credits prepaid and shared across the organization; a Base review is 1 credit, Plus 3, Apex 10; Starter free for one active developer with 50 credits a month; free for qualified non-commercial projects with an OSI-approved license; a startup discount of 500 free credits a month for 6 months for pre-Series A startups with under $2M revenue in the past 12 months&lt;/td&gt;
&lt;td&gt;Enterprise: "Self-host in your own infrastructure"; "The entirety of Greptile's service can be self-hosted in an air-gapped environment."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;"GitHub (cloud and Enterprise Server), GitLab (cloud and self-managed), Bitbucket (Cloud and Data Center), Azure DevOps."; Gerrit, which the homepage puts on Enterprise and the deployment docs list for every deployment model&lt;/td&gt;
&lt;td&gt;a credit pool for the team: Pro Team $30 a month for 2,500 credits, ~18 reviews by Qodo's estimate, "$.012/credit, pooled across the team"; "We don't offer a permanent free tier.", while qualified open source projects can get free access through the Qodo for Open Source program&lt;/td&gt;
&lt;td&gt;Enterprise: "Single-tenant SaaS or on-prem"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor Bugbot&lt;/td&gt;
&lt;td&gt;Origin; GitHub, including GitHub Enterprise Server; GitLab, including GitLab Self-Hosted; Bitbucket, including Bitbucket Data Center; Azure DevOps Services&lt;/td&gt;
&lt;td&gt;each run beyond the plan's included usage: "Bugbot first consumes your included usage, then bills additional reviews from your prepaid credit, or from on-demand spend on a legacy Cursor plan."; "The average Bugbot run costs between $1.00 and $1.50, depending on PR size and complexity."; on Cursor's current plans Bugbot starts with Premium at $30 a month, and Teams seats at $30, $100 or $200 per seat a month are Premium or higher; Plus does not include it&lt;/td&gt;
&lt;td&gt;a self-hosted Bugbot service was not found on Cursor's Bugbot docs as of 25 October 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR-Agent&lt;/td&gt;
&lt;td&gt;GitHub, GitLab, BitBucket, Azure DevOps and Gitea, by its README&lt;/td&gt;
&lt;td&gt;open source, "a community-maintained legacy project of Qodo"; you pay the model provider you choose, "and any other model reachable through LiteLLM"&lt;/td&gt;
&lt;td&gt;CLI, GitHub Actions, Docker, self-hosted or webhooks, by its README&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code (Anthropic)&lt;/td&gt;
&lt;td&gt;managed Code Review: "repositories hosted on GitHub, including GitHub Enterprise Server and GitHub Enterprise Cloud with data residency"; &lt;code&gt;/code-review&lt;/code&gt;: a GitHub pull request or a GitLab merge request; GitLab CI/CD: "currently in beta"&lt;/td&gt;
&lt;td&gt;managed Code Review on Team and Enterprise plans, "billed on token usage through usage credits", "Code Review has no flat per-review price.", billed to the organization; &lt;code&gt;/code-review&lt;/code&gt;: "The command works on any plan."&lt;/td&gt;
&lt;td&gt;managed Code Review runs "on Anthropic infrastructure, in a managed environment"; Claude in your own CI runs on "Your own CI runners" with a Claude API key or cloud provider credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graphite Agent&lt;/td&gt;
&lt;td&gt;GitHub; GitHub Enterprise Server for Enterprise customers&lt;/td&gt;
&lt;td&gt;per user per month billed annually: Starter $20, Team $40; AI reviews limited on Hobby and Starter, unlimited on Team and Enterprise; Hobby is free for personal projects&lt;/td&gt;
&lt;td&gt;"There is no self-hosted deployment of Graphite's service available for a user to run in their own cloud."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI Codex code review&lt;/td&gt;
&lt;td&gt;"GitHub code review is generally available. GitLab merge request support in Code Review is in preview."&lt;/td&gt;
&lt;td&gt;your ChatGPT plan's usage; "Code Review usage applies only when Codex runs reviews through GitHub"; on an API key, "No cloud-based features (GitHub code review, Slack, etc.)"&lt;/td&gt;
&lt;td&gt;the review service on GitHub: not found on the Codex code review page as of 25 October 2026; the &lt;code&gt;/review&lt;/code&gt; command reviews changes in your local checkout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sourcery&lt;/td&gt;
&lt;td&gt;GitHub; GitLab.com and self-managed GitLab on every plan; GitHub Enterprise Server on Enterprise&lt;/td&gt;
&lt;td&gt;Pro $12 per seat per month billed annually, $15 monthly; Team $24 or $30; "You pay only for the developers you assign seats to."; free for public repositories&lt;/td&gt;
&lt;td&gt;"Sourcery can run entirely inside your own infrastructure, under an Enterprise agreement"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sigma&lt;/td&gt;
&lt;td&gt;"Sigma reviews pull requests on GitHub."&lt;/td&gt;
&lt;td&gt;closed beta, by invitation&lt;/td&gt;
&lt;td&gt;not stated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;How the vendor describes noise&lt;/th&gt;
&lt;th&gt;Training on your code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;review and verification run as separate agents (table above)&lt;/td&gt;
&lt;td&gt;"CodeRabbit never uses customer code for model training."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot code review&lt;/td&gt;
&lt;td&gt;"Silence is better than noise."; "Model switching is not supported, as changing the model is likely to compromise reliability, user experience, and the quality of review comments."&lt;/td&gt;
&lt;td&gt;the plans FAQ says "In addition, for Individual subscribers only: GitHub may use Copilot interaction data" to train and improve AI models, and "Individual subscribers can opt out of having their data used for AI model training at any time"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greptile&lt;/td&gt;
&lt;td&gt;TREX checks at runtime, "generally available" per its docs changelog of 16 October 2026 (table above)&lt;/td&gt;
&lt;td&gt;on de-identified data: it "may aggregate and anonymize Customer Data" and "may use such data to train and improve artificial intelligence algorithms and models"; "To opt your organization out of AI training, an organization admin can open Organization Settings"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;"Specialized review agents reason over full codebase context to flag real bugs, rule violations, and requirements gaps with less noise."&lt;/td&gt;
&lt;td&gt;"Your code is analyzed and discarded. Nothing stored, logged, or used to train models."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor Bugbot&lt;/td&gt;
&lt;td&gt;"Bugbot detects the hardest logic bugs with a low false positive rate."&lt;/td&gt;
&lt;td&gt;with Privacy Mode on: "Customer Data will not be used for training by Cursor."; "Privacy Mode is on by default for Enterprise teams."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code (Anthropic)&lt;/td&gt;
&lt;td&gt;"a verification step checks the candidate findings against the code and filters out false positives."&lt;/td&gt;
&lt;td&gt;"Anthropic does not train generative models using code or prompts sent to Claude Code under commercial terms"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graphite Agent&lt;/td&gt;
&lt;td&gt;comment exclusions, "This reduces noise and focuses AI reviews on what matters most to your team."&lt;/td&gt;
&lt;td&gt;"Neither Graphite nor any of its subprocessors use your data to train their models"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI Codex code review&lt;/td&gt;
&lt;td&gt;only P0 and P1 issues in GitHub&lt;/td&gt;
&lt;td&gt;on the Business and Enterprise plans: "No training on your business data by default."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sourcery&lt;/td&gt;
&lt;td&gt;the Quiet and default review profiles (table above)&lt;/td&gt;
&lt;td&gt;"none of your code is used to train any model"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sigma&lt;/td&gt;
&lt;td&gt;"only confirmed candidates are verified findings"; "unverified suspicions are leads, not findings"&lt;/td&gt;
&lt;td&gt;not stated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Static analysis and security platforms on the same lists
&lt;/h2&gt;

&lt;p&gt;Four platforms whose main product is code analysis or security are named on 10 or more of the 27 lists. Each describes AI in its analysis or on pull requests, by its own pages.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Named on, of 27 lists&lt;/th&gt;
&lt;th&gt;What it does on a pull request, in its words&lt;/th&gt;
&lt;th&gt;What you pay for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SonarQube&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;static analysis, "decorating pull requests with actionable issue summaries"; AI review of pull requests is a separate Sonar product, Gitar: "Gitar AI Code Review Reviews every pull request in full context, writes the fix, and iterates until CI passes."&lt;/td&gt;
&lt;td&gt;SonarQube by lines of code, "SonarQube plan pricing starts at $34 monthly for analysis of up to 100k LOC."; a free tier, and "SonarQube Team Plan, free for your private projects up to 50k LOC."; Gitar "Core at $20 per user per month, Pro at $40 per user per month"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snyk&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Snyk Code results "in your IDE and pull requests"; its DeepCode AI models "use training data from millions of permissively licensed open source projects with verified code fixes"; pull request checks start when "A developer creates a pull request (PR) in an SCM integrated with Snyk."&lt;/td&gt;
&lt;td&gt;"Try for Free or from $25/month" on its plans page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codacy&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;"AI Code Reviewer for Pull Requests"&lt;/td&gt;
&lt;td&gt;"Starting at $18 Per dev/mth"; "Free forever for open-source projects"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semgrep&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;"PR checks in GitHub, GitLab, Bitbucket, Azure"; "Combine AI reasoning with rule-based analysis for detection, triage, and remediation"&lt;/td&gt;
&lt;td&gt;"Starting at $30 / month per contributor"; "No charge for up to 10 contributors"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Also named on 5 to 9 of the 27 lists
&lt;/h2&gt;

&lt;p&gt;Counted without the vendor's own list, among names with a pull request reviewer. DeepSource (8): "Powered by 5,000+ deterministic rules along with our state-of-the-art AI review agent."; Team at $24 per user per month billed yearly; self-hosted deployment on Enterprise. CodeAnt AI (5): "AI agents that review every pull request and continuously secure your code, cloud, and runtime."; "Deploy in your VPC on AWS, GCP, or Azure or fully on-premises." on Enterprise. Bito (5): GitHub, GitLab and Bitbucket in the cloud and self-hosted; "Bito hosted or self-hosted ($5/seat/month add-on)". Gitar (5): the Sonar product above, "Gitar is a code change verification agent."&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed recently
&lt;/h2&gt;

&lt;p&gt;The date of a list matters, because several lists still describe products under names or terms their vendors have since replaced. Each row below is a vendor's own statement.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;What its pages say now&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;15 October 2026: "Code Review is out of research preview and available to Claude Team and Enterprise organizations."; "Code Review has no flat per-review price."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;the current plan table puts Bugbot in Premium at $30 a month and leaves it out of Plus, "No Auto, Cloud Agents, Automations, Bugbot, Origin, third-party models, or your own API keys."; older plans "continue for existing customers"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;"Essentials is the new name for Pro, and Team is the new name for Pro Plus."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qodo&lt;/td&gt;
&lt;td&gt;"The current product is Qodo Review (v2)."; "Historical names: Qodo Merge, PR-Agent, Qodo Gen, Codiumate"; PR-Agent is now "a community-maintained legacy project of Qodo"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graphite&lt;/td&gt;
&lt;td&gt;"As of 10/08/2025, the Diamond name has been deprecated, and AI code review capabilities now slot under Graphite Agent"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon&lt;/td&gt;
&lt;td&gt;from 7 November 2025: "After that point, you will only be able to use CodeGuru Reviewer with existing repository associations."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;from 17 July 2026: "the consumer version is shut down, and all code review activities performed by the app end."; "The enterprise version of Gemini Code Assist on GitHub is not affected by these changes."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where your code lives
&lt;/h2&gt;

&lt;p&gt;Every reviewer in the code host table above lists GitHub. On GitHub Enterprise Server: CodeRabbit, Cursor Bugbot, Claude Code's managed Code Review on Team and Enterprise, Greptile, Graphite and Sourcery on Enterprise, and Qodo, whose deployment table marks its "GitHub Enterprise" row for single-tenant, on-prem and air-gapped deployments and not for multi-tenant; "Copilot is not currently available for GitHub Enterprise Server." On GitLab: CodeRabbit, Greptile, Qodo, Bugbot, Sourcery, PR-Agent, Claude Code through &lt;code&gt;/code-review&lt;/code&gt; or GitLab CI/CD in beta, and Codex in preview; GitLab and Bitbucket were not found on Copilot's code review page as of 25 October 2026. On Bitbucket: CodeRabbit, Greptile, Qodo, Bugbot and PR-Agent. On Azure DevOps: CodeRabbit, Qodo, Bugbot (Azure DevOps Services), PR-Agent and Copilot in public preview.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-hosting, data and compliance
&lt;/h2&gt;

&lt;p&gt;Self-hosting comes with a condition on every page that offers it: CodeRabbit from 500 user seats on Enterprise, Greptile, Qodo, Sourcery and DeepSource on Enterprise, PR-Agent as open source you run yourself. Graphite says it has no self-hosted deployment, and Claude's managed Code Review runs on Anthropic infrastructure, while Claude in your own CI pipeline runs on your runners with your own credentials. Some training terms carry conditions: Anthropic's applies to commercial terms, Cursor's to Privacy Mode, OpenAI's to its Business and Enterprise plans, and Greptile's to organizations that opt out, while GitHub's plans FAQ says GitHub may use Copilot interaction data to train and improve AI models "for Individual subscribers only", who can opt out. Certifications are stated on the vendors' own pages, for example "Greptile is SOC 2 Type II compliant." and "Sourcery is SOC 2 Type 2 certified, and the report is available on request."&lt;/p&gt;

&lt;h2&gt;
  
  
  How to measure reliability on your own pull requests
&lt;/h2&gt;

&lt;p&gt;The pages above tell you what each tool intends; only your pull requests tell you how often it is right on your code, and the count needs nothing beyond a spreadsheet. Pick two tools from the tables that fit your code host and your bill, and turn both on for the same repositories for two weeks. For every comment, record one of three outcomes: fixed, dismissed as wrong, or left without action. At the end, divide fixed by all comments for each tool; that share is your reliability number, on your code, with your own definition of a real problem.&lt;/p&gt;

&lt;p&gt;Two more readings make the number useful. Run one large pull request through each tool twice, a day apart, and compare the two sets of findings: a reviewer that reports different problems on the same diff shows you how stable its output is. Then note what each tool cost in its own unit, from its own usage page, before you compare. Two vendors point the same way in their docs: Qodo records why a finding was dismissed, and Sourcery writes of its findings report, "Judge that yourself on a sample."&lt;/p&gt;

&lt;p&gt;Sources, all read on 25 October 2026; the text describes these pages as of that day. Tool lists: 27 pages found by web searches on 9 October 2026, read again on 25 October 2026, counted by name. CodeRabbit: &lt;a href="https://www.coderabbit.ai/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/platforms/overview.md" rel="noopener noreferrer"&gt;platforms&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/self-hosted/overview.md" rel="noopener noreferrer"&gt;self-hosted&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/faq.md" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/overview/architecture" rel="noopener noreferrer"&gt;architecture&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/management/rate-limits.md" rel="noopener noreferrer"&gt;rate limits&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/management/plans.md" rel="noopener noreferrer"&gt;plans&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/management/usage-based-addon.md" rel="noopener noreferrer"&gt;usage-based reviews&lt;/a&gt;, &lt;a href="https://docs.coderabbit.ai/llms-full.txt" rel="noopener noreferrer"&gt;docs index&lt;/a&gt;. GitHub: &lt;a href="https://docs.github.com/en/copilot/concepts/agent-capabilities/agent-powered-workflows-and-operations/code-review" rel="noopener noreferrer"&gt;Copilot code review&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-code-review" rel="noopener noreferrer"&gt;using code review&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/get-started/plans" rel="noopener noreferrer"&gt;plans (docs)&lt;/a&gt;, &lt;a href="https://github.com/features/copilot/plans" rel="noopener noreferrer"&gt;plans and FAQ&lt;/a&gt;, &lt;a href="https://github.blog/ai-and-ml/github-copilot/60-million-copilot-code-reviews-and-counting/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;. Greptile: &lt;a href="https://www.greptile.com/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://www.greptile.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/code-review-bot/billing-seats.md" rel="noopener noreferrer"&gt;credits&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/security/selfhost.md" rel="noopener noreferrer"&gt;self-hosting&lt;/a&gt;, &lt;a href="https://www.greptile.com/security" rel="noopener noreferrer"&gt;security&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/llms-full.txt" rel="noopener noreferrer"&gt;docs index&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/changelog.md" rel="noopener noreferrer"&gt;changelog&lt;/a&gt;, &lt;a href="https://www.greptile.com/docs/trex/overview.md" rel="noopener noreferrer"&gt;TREX&lt;/a&gt;. Qodo: &lt;a href="https://www.qodo.ai/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://www.qodo.ai/pricing/" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://docs.qodo.ai/code-review/overview.md" rel="noopener noreferrer"&gt;how review works&lt;/a&gt;, &lt;a href="https://docs.qodo.ai/install-qodo/deployment-model-support.md" rel="noopener noreferrer"&gt;deployment models&lt;/a&gt;, &lt;a href="https://docs.qodo.ai/llms.txt" rel="noopener noreferrer"&gt;docs index&lt;/a&gt;, &lt;a href="https://docs.qodo.ai/llms-full.txt" rel="noopener noreferrer"&gt;full docs&lt;/a&gt;, &lt;a href="https://github.com/The-PR-Agent/pr-agent" rel="noopener noreferrer"&gt;PR-Agent&lt;/a&gt;. Cursor: &lt;a href="https://cursor.com/bugbot" rel="noopener noreferrer"&gt;Bugbot&lt;/a&gt;, &lt;a href="https://cursor.com/docs/bugbot.md" rel="noopener noreferrer"&gt;Bugbot docs&lt;/a&gt;, &lt;a href="https://cursor.com/help/account-and-billing/bugbot-usage-based-billing.md" rel="noopener noreferrer"&gt;Bugbot billing&lt;/a&gt;, &lt;a href="https://cursor.com/docs/models-and-pricing.md" rel="noopener noreferrer"&gt;models and pricing&lt;/a&gt;, &lt;a href="https://cursor.com/data-use" rel="noopener noreferrer"&gt;data use&lt;/a&gt;, &lt;a href="https://cursor.com/docs/enterprise/privacy-and-data-governance.md" rel="noopener noreferrer"&gt;privacy&lt;/a&gt;. Anthropic: &lt;a href="https://code.claude.com/docs/en/code-review.md" rel="noopener noreferrer"&gt;Code Review&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review" rel="noopener noreferrer"&gt;Code Review hosts&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review-costs" rel="noopener noreferrer"&gt;costs&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review-local.md" rel="noopener noreferrer"&gt;/code-review&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/gitlab-ci-cd.md" rel="noopener noreferrer"&gt;GitLab CI/CD&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/github-enterprise-server.md" rel="noopener noreferrer"&gt;GitHub Enterprise Server&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/data-usage.md" rel="noopener noreferrer"&gt;data usage&lt;/a&gt;, &lt;a href="https://claude.com/resources/articles/code-review-is-now-generally-available" rel="noopener noreferrer"&gt;general availability&lt;/a&gt;. Graphite: &lt;a href="https://graphite.com/docs/ai-reviews.md" rel="noopener noreferrer"&gt;AI reviews&lt;/a&gt;, &lt;a href="https://graphite.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://graphite.com/docs/github-enterprise-server.md" rel="noopener noreferrer"&gt;GitHub Enterprise Server&lt;/a&gt;, &lt;a href="https://graphite.com/docs/ai-privacy-and-security.md" rel="noopener noreferrer"&gt;AI privacy&lt;/a&gt;, &lt;a href="https://graphite.com/blog/series-b-diamond-launch" rel="noopener noreferrer"&gt;name change&lt;/a&gt;, &lt;a href="https://graphite.com/docs/llms-full.txt" rel="noopener noreferrer"&gt;docs index&lt;/a&gt;. OpenAI: &lt;a href="https://learn.chatgpt.com/docs/code-review.md" rel="noopener noreferrer"&gt;Codex code review&lt;/a&gt;, &lt;a href="https://learn.chatgpt.com/docs/third-party/github.md" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, &lt;a href="https://learn.chatgpt.com/docs/pricing.md" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;. Sourcery: &lt;a href="https://www.sourcery.ai/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://www.sourcery.ai/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://docs.sourcery.ai/trust/self-hosted-sourcery/" rel="noopener noreferrer"&gt;self-hosted&lt;/a&gt;, &lt;a href="https://docs.sourcery.ai/trust/code-retention/" rel="noopener noreferrer"&gt;code retention&lt;/a&gt;, &lt;a href="https://docs.sourcery.ai/trust/compliance/" rel="noopener noreferrer"&gt;compliance&lt;/a&gt;, &lt;a href="https://docs.sourcery.ai/llms-full.txt" rel="noopener noreferrer"&gt;docs index&lt;/a&gt;. Sonar: &lt;a href="https://www.sonarsource.com/plans-and-pricing/" rel="noopener noreferrer"&gt;plans&lt;/a&gt;, &lt;a href="https://www.sonarsource.com/products/sonarqube/" rel="noopener noreferrer"&gt;SonarQube&lt;/a&gt;, &lt;a href="https://www.sonarsource.com/products/gitar/" rel="noopener noreferrer"&gt;Gitar&lt;/a&gt;. Snyk: &lt;a href="https://snyk.io/product/snyk-code/" rel="noopener noreferrer"&gt;Snyk Code&lt;/a&gt;, &lt;a href="https://snyk.io/platform/deepcode-ai/" rel="noopener noreferrer"&gt;DeepCode AI&lt;/a&gt;, &lt;a href="https://snyk.io/plans/" rel="noopener noreferrer"&gt;plans&lt;/a&gt;, &lt;a href="https://docs.snyk.io/scan-with-snyk/pull-requests/pull-request-checks.md" rel="noopener noreferrer"&gt;pull request checks&lt;/a&gt;. Codacy: &lt;a href="https://www.codacy.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://www.codacy.com/ai-reviewer" rel="noopener noreferrer"&gt;AI Reviewer&lt;/a&gt;. Semgrep: &lt;a href="https://semgrep.dev/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://semgrep.dev/pricing/" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;. DeepSource: &lt;a href="https://deepsource.com/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://deepsource.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;. CodeAnt AI: &lt;a href="https://docs.codeant.ai/index.md" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, &lt;a href="https://codeant.ai/enterprise" rel="noopener noreferrer"&gt;enterprise&lt;/a&gt;. Bito: &lt;a href="https://bito.ai/product/ai-code-review-agent/" rel="noopener noreferrer"&gt;code review&lt;/a&gt;, &lt;a href="https://bito.ai/pricing/" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;. Amazon: &lt;a href="https://docs.aws.amazon.com/codeguru/latest/reviewer-ug/welcome.html" rel="noopener noreferrer"&gt;reviewer guide&lt;/a&gt;, &lt;a href="https://docs.aws.amazon.com/codeguru/latest/reviewer-ug/doc-history.html" rel="noopener noreferrer"&gt;document history&lt;/a&gt;. Google: &lt;a href="https://developers.google.com/gemini-code-assist/docs/deprecations/consumer-code-review" rel="noopener noreferrer"&gt;consumer deprecation&lt;/a&gt;. Sigma: &lt;a href="https://sigma.mnemoverse.com/?src=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=which-ai-is-best-for-code-review" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://sigma.mnemoverse.com/docs?src=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=which-ai-is-best-for-code-review" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, &lt;a href="https://sigma.mnemoverse.com/docs/reading-a-review?src=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=which-ai-is-best-for-code-review" rel="noopener noreferrer"&gt;reading a review&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>github</category>
      <category>devtools</category>
    </item>
    <item>
      <title>How are you guys handling code reviews when a lot of the code is written by AI?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Mon, 26 Oct 2026 10:13:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/how-are-you-guys-handling-code-reviews-when-a-lot-of-the-code-is-written-by-ai-3idk</link>
      <guid>https://dev.to/izgorodin/how-are-you-guys-handling-code-reviews-when-a-lot-of-the-code-is-written-by-ai-3idk</guid>
      <description>&lt;p&gt;GitHub, Google, Anthropic's Claude Code team and one team that published its checks write down these changes between them. Keep pull requests small: Google's engineering practices guide says "In general, the right size for a CL is one self-contained change", and GitHub's docs say "Small, focused pull requests are easier to review and safer to merge." Run checks before a person reads the diff: GitHub's tutorial on how to review AI-generated code begins its first step with "Always run automated tests and static analysis tools first." Make the author explain the change: the Claude Code team's pull request template asks how the change was tested and how to undo it. Let an AI pass go first, with the limits its vendors write themselves, and keep a person on what your rules reserve for people.&lt;/p&gt;

&lt;p&gt;Every fact below comes from the pages listed at the end, as I read them on 25 October 2026, and none of their authors saw this text before publication.&lt;/p&gt;

&lt;h2&gt;
  
  
  What teams change when agents write the code
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;th&gt;What the reviewer gets&lt;/th&gt;
&lt;th&gt;Written down by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Smaller pull requests, or a stack of them&lt;/td&gt;
&lt;td&gt;one self-contained change at a time, with its tests&lt;/td&gt;
&lt;td&gt;Google's engineering practices, "Small CLs"; GitHub, "Helping others review your changes" and "About stacked pull requests"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Checks that must pass before a person reads&lt;/td&gt;
&lt;td&gt;a diff that already compiles and passes its tests, linting and static analysis&lt;/td&gt;
&lt;td&gt;GitHub's tutorial "Review AI-generated code"; GitHub's required status checks on protected branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The author explains the change&lt;/td&gt;
&lt;td&gt;a description of how it was tested, its risk and how to undo it, after the author's own self-review&lt;/td&gt;
&lt;td&gt;GitHub's pull request templates and "Helping others review your changes"; the Claude Code team's post of 15 October 2026; Claude Code's best practices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;An AI pass before the human one&lt;/td&gt;
&lt;td&gt;routine mistakes already found, and findings that each need an answer&lt;/td&gt;
&lt;td&gt;the Claude Code team's post; GitHub's tutorial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A person on what the rules keep for people&lt;/td&gt;
&lt;td&gt;a teammate on complex, sensitive or risky changes&lt;/td&gt;
&lt;td&gt;GitHub's docs on Copilot cloud agent pull requests and on protected branches; GitHub's tutorial; the Claude Code team's post&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Someone owns the change&lt;/td&gt;
&lt;td&gt;the person who directed the agent answers for it&lt;/td&gt;
&lt;td&gt;the Claude Code team's post: "A person is accountable for every change that ships, whoever typed it."; GitHub: whoever assigned Copilot the issue cannot approve the pull request it raised&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each row comes from the page named in it, read on 25 October 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smaller pull requests
&lt;/h2&gt;

&lt;p&gt;Smaller pull requests give the reviewer one change to judge at a time. Google's engineering practices guide, which is about Google's own changes (it calls them CLs), puts the right size at one self-contained change, says "The CL should include related test code", and gives a range with a condition: "100 lines is usually a reasonable size for a CL, and 1000 lines is usually too large, but it's up to the judgment of your reviewer." It sets a lower bound too, "The CL is not so small that its implications are difficult to understand.", and adds "Reviewers rarely complain about getting CLs that are too small."&lt;/p&gt;

&lt;p&gt;GitHub's docs say "When a change grows large, consider splitting it into smaller pull requests that each serve one purpose." For changes that depend on each other, GitHub documents stacked pull requests: "Break large code changes into a chain of smaller, dependent pull requests you can review and merge independently." Review rules hold on each one, "Branch protection rules, such as CODEOWNER approvals, are enforced on every pull request in the stack", and the page lists agents among the places to use stacks, "For agents, via the gh-stack skill". Graphite's docs open with "Learn how to create, review, and merge stacked pull requests with Graphite." The Claude Code team ties size to ownership: "Changes are small, so they're easy to review, debug and revert."&lt;/p&gt;

&lt;h2&gt;
  
  
  Checks that run before anyone reads the diff
&lt;/h2&gt;

&lt;p&gt;Machines go first, so the reviewer starts from a diff that builds. GitHub's tutorial says "Make sure the code compiles and all tests pass. Check for any new warnings or errors." For AI output it names what to look for: "Look for hallucinated APIs, ignored constraints, or incorrect logic.", "Watch for tests that are deleted or skipped, instead of fixed.", and "Check if suggested dependencies exist and are actively maintained." It advises "Set up CI checks for style, linting, security, code quality and code coverage."&lt;/p&gt;

&lt;p&gt;A branch protection rule turns those checks into a gate: "After enabling required status checks, all required status checks must pass before collaborators can merge changes into the protected branch." On the Claude Code team, Claude runs the tests, build and linter before a pull request exists, and "Then a subagent reviews the diff with fresh context." On the pull request, required CI and a separate security review run, and "A PR can't merge while any finding from the bug review or the security review is still open."&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the author explain the change
&lt;/h2&gt;

&lt;p&gt;The first person to read an agent's diff can be the one who asked for it. GitHub's docs say "Reviewing your own pull request before asking others to review it helps you catch mistakes early." and "A self-review can include reading the diff, checking for accidental changes, and making sure relevant builds or tests have run." A template makes the questions routine: "When you add a pull request template to your repository, project contributors will automatically see the template's contents in the pull request body." If a tool drafts the description, GitHub's advice is "A generated summary can help reviewers understand the main changes, but you should review it carefully and add context that only you know."&lt;/p&gt;

&lt;p&gt;The Claude Code team describes its own template: "The PR template asks how the change was tested and how to undo it. Claude can fill that in, but the person who asked for the change signs off on it." Its advice to other teams is to require CI and to add &lt;code&gt;Testing&lt;/code&gt;, &lt;code&gt;Risk&lt;/code&gt; and &lt;code&gt;How to revert&lt;/code&gt; to the pull request template. Claude Code's best practices ask the agent for evidence instead of a claim: "Have Claude show evidence rather than asserting success: the test output, the command it ran and what it returned, or a screenshot of the result." GitHub's tutorial suggests writing your expectations down: "Use a CONTRIBUTING.md file in your repository to document your expectations for AI-generated source code and content". LLVM's AI tool policy asks contributors to "label contributions that contain substantial amounts of tool-generated content" and says "Contributors should note tool usage in their pull request description, commit message, or wherever authorship is normally indicated for the work."&lt;/p&gt;

&lt;p&gt;Ahmet Zeybek describes on dev.to the checks his team added after an agent began opening many of its pull requests. The description declares the intended scope as a list of files or directories, and a CI check fails any file outside it; another check requires a non-empty section of behavior changes when certain paths change; reviewers read the code before the tests, because "A green suite written by the code's author is weaker evidence than one written by someone else, and with agents it's always the same author." Size has a hard limit: "The limit we settled on is 400 changed lines, not counting generated files and lockfiles, and a check enforces it." And the template says "by opening this PR you confirm you've read every changed line and can explain it."&lt;/p&gt;

&lt;h2&gt;
  
  
  An AI pass first, and what the vendors say it is not
&lt;/h2&gt;

&lt;p&gt;On the Claude Code team, "Most changes have been reviewed and fixed by Claude at least once before a human is asked to look." Every finding of that review needs a reply: "Every finding has to be answered. You either fix it or resolve the thread with a reason." GitHub's tutorial suggests a similar step for your own team: "build a self-reviewing agent that evaluates draft pull requests against your standards, checking for accuracy, appropriate tone, and business logic before requesting human review."&lt;/p&gt;

&lt;p&gt;The vendors of these passes write their limits themselves. GitHub on Copilot code review: "Copilot is not guaranteed to spot all problems or issues in a pull request. Sometimes it will make mistakes." and "Supplement Copilot's feedback with a human review." Anthropic on Claude Code Review: "Code Review uses AI to review code and may miss bugs, security vulnerabilities, or other issues. A review with no findings doesn't mean your code is error-free or secure." OpenAI on Codex: "Code review rules guide Codex; they don't replace tests, branch protections, or required approvals." Cursor on PR Routing &amp;amp; Approval, which "routes pull requests to the right reviewers and can approve low-risk changes": "It does not replace a full code review."&lt;/p&gt;

&lt;p&gt;Sigma (Mnemoverse, the author's company), in closed beta, reviews pull requests on GitHub; its homepage calls it "A useful second look" and says "Sigma checks potential issues and brings the evidence back to your code." Its docs say a fresh verifier "confirms, rejects or reclassifies each one", that "only confirmed candidates are verified findings" while suspicions no verifier confirmed stay labeled separately, and that "A verification label is agent-produced evidence, not proof that the code is correct." Its docs also say "Sigma never merges." Sigma runs on Claude Code and OpenAI models. Teams can request access on its homepage, which says "A request does not grant access automatically."&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a person still has to look
&lt;/h2&gt;

&lt;p&gt;GitHub asks for the same review on pull requests from its own agent: "Copilot pull requests deserve the same thorough review as any contribution." Its approval rule keeps a second person in the loop: "If your repository requires pull request approvals, your approval of a Copilot pull request won't count toward the required number. Another reviewer must approve the pull request before it can be merged." CI does not start on its own either: "By default, GitHub Actions workflows will not run automatically when Copilot pushes changes to a pull request." GitHub's tutorial adds "Ask teammates to review complex or sensitive changes."&lt;/p&gt;

&lt;p&gt;The Claude Code team lists what stays with people, among them "Reviewing risky code such as billing, the auto-updater and CI workflows." and reading the evidence: "If you can't say what the checks would miss, ask for a real review rather than a quick approval." Its advice includes "Add automated security review, and require every review thread resolved before merge." On GitHub, the branch protection setting for this is Require conversation resolution before merging, which "Requires all comments on the pull request to be resolved before it can be merged to a protected branch."&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and method
&lt;/h2&gt;

&lt;p&gt;Each quotation was checked word for word against its page on the reading day.&lt;/p&gt;

&lt;p&gt;Related on this account: &lt;a href="https://dev.to/izgorodin/why-does-codex-keep-finding-new-issues-every-time-it-reviews-its-own-code-23kc"&gt;Why does Codex keep finding new issues every time it reviews its own code?&lt;/a&gt;, on review loops.&lt;/p&gt;

&lt;p&gt;Sources, all read on 25 October 2026; this text describes them as of that date. Google: &lt;a href="https://google.github.io/eng-practices/review/developer/small-cls.html" rel="noopener noreferrer"&gt;Small CLs&lt;/a&gt;. GitHub: &lt;a href="https://docs.github.com/en/copilot/tutorials/review-ai-generated-code" rel="noopener noreferrer"&gt;Review AI-generated code&lt;/a&gt;, &lt;a href="https://docs.github.com/en/pull-requests/concepts/helping-others-review-your-changes" rel="noopener noreferrer"&gt;helping others review your changes&lt;/a&gt;, &lt;a href="https://docs.github.com/en/pull-requests/get-started/about-stacked-prs" rel="noopener noreferrer"&gt;stacked pull requests&lt;/a&gt;, &lt;a href="https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository" rel="noopener noreferrer"&gt;pull request templates&lt;/a&gt;, &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches" rel="noopener noreferrer"&gt;protected branches&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/use-copilot-agents/review-copilot-output" rel="noopener noreferrer"&gt;Copilot pull requests&lt;/a&gt;, &lt;a href="https://docs.github.com/en/pull-requests/how-tos/review-pull-requests/approving-a-pull-request-with-required-reviews" rel="noopener noreferrer"&gt;approving with required reviews&lt;/a&gt;, &lt;a href="https://docs.github.com/en/copilot/concepts/agent-capabilities/agent-powered-workflows-and-operations/code-review" rel="noopener noreferrer"&gt;Copilot code review&lt;/a&gt;. Graphite: &lt;a href="https://graphite.com/docs/get-started" rel="noopener noreferrer"&gt;overview&lt;/a&gt;. Anthropic: &lt;a href="https://claude.dev/blog/solving-code-review-at-anthropic/" rel="noopener noreferrer"&gt;How the Claude Code team does code review&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/code-review" rel="noopener noreferrer"&gt;Code Review&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/best-practices" rel="noopener noreferrer"&gt;best practices&lt;/a&gt;. OpenAI: &lt;a href="https://learn.chatgpt.com/docs/third-party/github" rel="noopener noreferrer"&gt;Codex in GitHub&lt;/a&gt;. Cursor: &lt;a href="https://cursor.com/docs/approval-agents" rel="noopener noreferrer"&gt;PR Routing &amp;amp; Approval&lt;/a&gt;. LLVM: &lt;a href="https://llvm.org/docs/AIToolPolicy.html" rel="noopener noreferrer"&gt;AI Tool Use Policy&lt;/a&gt;. Ahmet Zeybek: &lt;a href="https://dev.to/zeybek/how-we-review-pull-requests-that-an-agent-wrote-59l6"&gt;How we review pull requests that an agent wrote&lt;/a&gt;. Sigma: &lt;a href="https://sigma.mnemoverse.com/?src=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=code-reviews-ai-written-code" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, &lt;a href="https://sigma.mnemoverse.com/docs/reading-a-review?src=devto&amp;amp;utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=code-reviews-ai-written-code" rel="noopener noreferrer"&gt;reading a review&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>github</category>
      <category>claude</category>
    </item>
  </channel>
</rss>
