<?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: Mikhail</title>
    <description>The latest articles on DEV Community by Mikhail (@mansio).</description>
    <link>https://dev.to/mansio</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%2F4040767%2Fd68a3ffd-1013-490a-a6b0-cc085141576a.jpg</url>
      <title>DEV Community: Mikhail</title>
      <link>https://dev.to/mansio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mansio"/>
    <language>en</language>
    <item>
      <title>We Didn't Invent New AI Architecture. We Rediscovered 20-Year-Old Computer Science.</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Mon, 31 Aug 2026 09:45:57 +0000</pubDate>
      <link>https://dev.to/mansio/we-didnt-invent-new-ai-architecture-we-rediscovered-20-year-old-computer-science-1f6m</link>
      <guid>https://dev.to/mansio/we-didnt-invent-new-ai-architecture-we-rediscovered-20-year-old-computer-science-1f6m</guid>
      <description>&lt;p&gt;Over the past few weeks, a series of deep technical threads across developer communities (spanning RAG pipelines, autonomous agents, and protocol verification) converged on a single, humbling realization:&lt;/p&gt;

&lt;p&gt;The AI industry isn't inventing a new paradigm. It is frantically rediscovering classical computer science, auditing theory, and distributed systems patterns from 20 years ago—and adapting them to survive a probabilistic engine that lies with confidence.&lt;/p&gt;

&lt;p&gt;This post is not about a new framework. It’s an observation of where these "new" AI concepts actually come from, and a thank-you to the engineers doing the hard, unpaid labor of anchoring hyper-probabilistic technology back to deterministic ground truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. "Cryptographically Perfect Hallucinations" &amp;amp; The Oracle Problem
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The AI Discussion:&lt;/strong&gt; Recent discussions around RAG pipelines and agent verification highlighted a critical gap: perfect retrieval doesn't mean a true answer. A model can retrieve a valid chunk and over-interpret it ("Evidence exists ≠ evidence entails"). High retrieval accuracy can even "launder" unsanctioned actions. The community started calling these "cryptographically perfect hallucinations"—clean cryptographic receipts over semantically dead context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Root:&lt;/strong&gt; This is the classic &lt;strong&gt;Oracle Problem&lt;/strong&gt; in cryptography. A signature (Ed25519) proves that data was transmitted and not tampered with, but it cannot prove the data was true to begin with. The AI community didn't need a new term; it just needed to apply the Oracle Problem to LLM agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Empty Set Trap &amp;amp; "Capture-Recapture"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The AI Discussion:&lt;/strong&gt; Engineers recently shared devastating production bugs where a 100% sampling collector returned 0 rows for days while serving hundreds of requests. Dashboards stayed green. The receipt was valid. The population was empty. The system reported success because it didn't independently track what was dropped &lt;em&gt;before&lt;/em&gt; processing. The community named this the "Empty Set Trap"—the gap between &lt;code&gt;eligible_seen&lt;/code&gt; and &lt;code&gt;population_size&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Root:&lt;/strong&gt; This isn't a new AI failure. It's the &lt;strong&gt;"Completeness Assertion"&lt;/strong&gt; in database auditing (ensuring all transactions that &lt;em&gt;should&lt;/em&gt; have been recorded actually were) and the &lt;strong&gt;"Capture-Recapture"&lt;/strong&gt; method from statistics (estimating a hidden population). The industry was just re-learning how to audit a denominator.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. "Veto Heartbeats" &amp;amp; Durable Execution
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The AI Discussion:&lt;/strong&gt; Builders started tracking "Veto Heartbeats"—the realization that a reviewer that has never been seen to fail is indistinguishable from a broken rubber stamp. The proposed fix was tracking the "last time a reviewer said no" as a live, auditable signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Root:&lt;/strong&gt; The workflow industry recently published pieces like &lt;em&gt;"Agent Workflows Are Rediscovering Durable Execution."&lt;/em&gt; BPMN engines have solved this for decades with idempotency, rollback mechanisms, and mandatory audit trails. Modern AI agents are just trying to rebuild BPMN, often poorly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. RetractionReceipts &amp;amp; Event Sourcing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The AI Discussion:&lt;/strong&gt; To handle poisoned agent memory, protocol designers introduced concepts where a previously verified AI action could be transitioned to a &lt;code&gt;REFUTED&lt;/code&gt; state without deleting the original cryptographic receipt, preserving forensic history while invalidating the semantic claim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Root:&lt;/strong&gt; This is standard &lt;strong&gt;Event Sourcing&lt;/strong&gt; combined with the &lt;strong&gt;W3C PROV-DM&lt;/strong&gt; (&lt;code&gt;wasInvalidatedBy&lt;/code&gt;) data model. It has existed for decades to ensure immutable logs can still reflect changed realities. We just had to adapt it for an LLM that confidently hallucinates.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Meta-Lesson
&lt;/h3&gt;

&lt;p&gt;If we strip away the LLM hype, we find that the AI engineering community is currently stretching an owl onto a globe (as a Russian idiom goes—forcing unrelated abstract theories onto simple physical facts). We are reinventing Event Sourcing, W3C PROV-DM, and BPMN routing from scratch, often failing to apply the lessons learned from those older systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Because 20th-century computer science built deterministic systems. If data was missing, the process threw an exception. LLMs don't throw exceptions. They hallucinate with &lt;code&gt;exit code 0&lt;/code&gt; and a confident tone. &lt;/p&gt;

&lt;p&gt;Adapting classical, deterministic verification patterns to survive a probabilistic engine that confidently lies is the actual unpaid labor of the current AI era. &lt;/p&gt;

&lt;p&gt;To everyone sharing their production bugs, writing protocol specs, and stress-testing agent harnesses in public: thank you. You aren't just building AI tools; you are doing the hard work of bringing an over-confident technology back to reality.&lt;/p&gt;

&lt;p&gt;The answers to our AI verification problems aren't new. But the engine we are bolting them to is. Let's stop reinventing the wheel and start reading the old manuals.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Note of Thanks (and a Disclaimer)
&lt;/h3&gt;

&lt;p&gt;I wish I could list everyone I’ve argued with, been corrected by, or shared ideas with over these past few weeks. The list is huge, and if I try to name everyone, I will inevitably leave someone out. But you know who you are. Thank you for sharing your production bugs, your telemetry, and your time. &lt;/p&gt;

&lt;p&gt;Final disclaimer: Everything written here might be wrong, misinterpreted, or completely obsolete in a few years. Maybe we are just the dinosaurs figuring out how to walk while the meteor is approaching. I don't know. But I'm enjoying the ride.&lt;/p&gt;

&lt;p&gt;Let's keep building.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>architecture</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Dataset Was Lying: 4 of 6 "False" Facts Were True</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Sun, 16 Aug 2026 11:35:55 +0000</pubDate>
      <link>https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok</link>
      <guid>https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok</guid>
      <description>

&lt;h6&gt;
  
  
  Part 1: &lt;a href="https://dev.to/mansio/the-mechanical-vs-the-semantic-what-happens-when-ai-memory-is-wrong-38ko"&gt;The Mechanical vs. The Semantic: What Happens When AI Memory is Wrong?&lt;/a&gt;
&lt;/h6&gt;

&lt;h6&gt;
  
  
  Part 2: &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia"&gt;Your memory layer is lying to you (and your LLM agrees)&lt;/a&gt;
&lt;/h6&gt;

&lt;h6&gt;
  
  
  Part 3: The Dataset Was Lying: 4 of 6 "False" Facts Were True
&lt;/h6&gt;




&lt;p&gt;A model rejected a claim we believed was false. Then we grepped the file. The claim was true — our dataset had labeled it wrong.&lt;/p&gt;

&lt;p&gt;That one grep forced us to recompute the entire experiment: 4 of 6 "false" trap facts were actually true, and correcting the labels inverted every conclusion. Digging further exposed a second, real failure mode (the temporal present-trap) and a third layer of attack (provider routing). Every layer of an evaluation pipeline can lie — ground truth, evidence, model interpretation, temporal semantics, execution. This post is the full red-team. (~1900 calls, &amp;lt; $0.10.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Evidence Ladder
&lt;/h2&gt;

&lt;p&gt;One dataset (50 facts), one prompt skeleton, one variable — the form of evidence. Three models: qwen3.7-flash, deepseek-v4-flash, glm-4.7-flash.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rung&lt;/th&gt;
&lt;th&gt;Evidence form&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;bare anchor strings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;25 lines of the real file around the anchor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;serialized structure: definitions, imports, callers/callees, occurrence lists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3b&lt;/td&gt;
&lt;td&gt;file fragment + structure (the "why not both?" arm)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;structure + git provenance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Verdict schema: &lt;code&gt;{"verdict": "true"|"false"|"unknown"}&lt;/code&gt;, temp=0, seed=42, zero-shot, leak-guarded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foylt27we50dmz4o94xgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foylt27we50dmz4o94xgi.png" alt="The evidence ladder: claim verification across evidence formats" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rungs 1→2: evidence format beats model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qwen3.7:    recall(real) 0.24 → 0.92   FA 0.00 → 0.02 (old labels; that 0.02 was a mislabeled true fact — corrected FA = 0, see below)
deepseek:   recall(real) 0.04 → 0.84
glm-4.7:    recall(real) 0.60 → 0.68
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Token strings are not evidence. Code is. (Reproduced on the corrected dataset, pinned: qwen 0.88.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Rung 3: graph closes the trap. Or so we thought.
&lt;/h2&gt;

&lt;p&gt;Graph evidence gave qwen3.7 &lt;strong&gt;FA = 0.000&lt;/strong&gt;, including zero false accepts on the trap category. We wrote the pre-registered interpretation: "structural layer closes the present-trap failure mode." Then rung 3b, the hybrid, &lt;strong&gt;reopened the trap&lt;/strong&gt; (FA 0.02, the same fact as before — which, as the red team below shows, was actually &lt;em&gt;true&lt;/em&gt;: that "false accept" was a label artifact, not a model failure). Not additive: fragment presence dominates graph structure. For qwen, "both" is strictly worse than "fragment only".&lt;/p&gt;

&lt;h2&gt;
  
  
  The attack: the dataset was lying
&lt;/h2&gt;

&lt;p&gt;Red-team checklist, item 1: &lt;em&gt;attack the ground truth, not the model.&lt;/em&gt; We grepped the six "present-trap" facts — claims like "The server wrapper uses logging", labeled false because the mutation generator replaced the real value with a stdlib import that exists somewhere in the project.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fact&lt;/th&gt;
&lt;th&gt;Claim (labeled FALSE)&lt;/th&gt;
&lt;th&gt;Reality&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;R43&lt;/td&gt;
&lt;td&gt;"The knowledge graph uses re"&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;graph.py:31: import re&lt;/code&gt; + 2 usages → TRUE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R45&lt;/td&gt;
&lt;td&gt;"The server wrapper uses logging"&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;server.py:14: import logging&lt;/code&gt; → TRUE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R46&lt;/td&gt;
&lt;td&gt;"The watchdog uses threading"&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;watchdog.py&lt;/code&gt; + &lt;code&gt;threading.Lock()&lt;/code&gt; → TRUE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R47&lt;/td&gt;
&lt;td&gt;"Hub model loading uses pathlib"&lt;/td&gt;
&lt;td&gt;6 occurrences → TRUE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R44&lt;/td&gt;
&lt;td&gt;"Cross-project search uses pathlib"&lt;/td&gt;
&lt;td&gt;imported, never used → ambiguous (excluded)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R42&lt;/td&gt;
&lt;td&gt;"The server wrapper uses dataclasses"&lt;/td&gt;
&lt;td&gt;0 occurrences → correctly FALSE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;4 of 6 "traps" were true.&lt;/strong&gt; The generator validated &lt;code&gt;value != real_value&lt;/code&gt; but never checked the value was absent from the &lt;em&gt;subject&lt;/em&gt;. Those were not false accepts — they were correct verdicts against incorrect labels. We created a corrected copy (29 true / 20 false / 1 ambiguous, new fingerprint) and kept the original untouched as a historical artifact.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffix18djcphuxmxcfoxgr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffix18djcphuxmxcfoxgr.png" alt="The Dataset Was Lying: 4 of 6 " width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Honest gap: we corrected the **labels&lt;/em&gt;&lt;em&gt;, not the generator that produced them. The original generator still checks &lt;code&gt;value != real_value&lt;/code&gt; instead of subject-scoped absence — the corrected dataset is a re-label, and our process rule now requires subject-file grep validation for any synthetic category.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Corrected matrix, pinned re-run (routing eliminated)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;arm&lt;/th&gt;
&lt;th&gt;qwen rec/FA-tr/miss&lt;/th&gt;
&lt;th&gt;deepseek rec/FA-tr/miss&lt;/th&gt;
&lt;th&gt;glm rec/FA-tr/miss&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;file_content&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0.88&lt;/strong&gt;/0/&lt;strong&gt;3&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;0.80/1/2&lt;/td&gt;
&lt;td&gt;0.68/2/1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;graph_first&lt;/td&gt;
&lt;td&gt;0.72/0/&lt;strong&gt;4&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;0.48/0/2&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0.84&lt;/strong&gt;/1/&lt;strong&gt;0&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;file_graph&lt;/td&gt;
&lt;td&gt;0.84/0/3&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0.92&lt;/strong&gt;/1/2&lt;/td&gt;
&lt;td&gt;0.80/2/1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Columns: &lt;strong&gt;recall&lt;/strong&gt; — true claims correctly accepted / 25 real; &lt;strong&gt;FA-trap&lt;/strong&gt; — false accepts on the trap category (only R42 is genuinely false after relabeling); &lt;strong&gt;miss_true&lt;/strong&gt; — true trap claims wrongly rejected (hidden recall loss, invisible under the old labels).&lt;/p&gt;

&lt;p&gt;FA trap counts only R42 (the one genuinely false trap claim). For context, Part 2's headline conclusions were: graph evidence closes the present-trap; qwen3.7 is the safe choice (FA 0.00 zero-shot, recall 0.88 with file content); glm-4.7 is dangerously fail-open (FA 0.24 zero-shot). &lt;strong&gt;Inverted conclusions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Graph closes the present-trap" is an artifact.&lt;/strong&gt; qwen's graph arm didn't filter false claims — it rejected all four &lt;em&gt;true&lt;/em&gt; trap claims (miss_true 4/5, hidden recall loss invisible under the old labels).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;glm-4.7, which Part 2 told us to exclude as fail-open, is the best structural verifier in the series&lt;/strong&gt;: recall 0.84, FA trap 1, &lt;strong&gt;miss_true 0&lt;/strong&gt; on graph evidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The best evidence format is model-specific&lt;/strong&gt;: fragment for qwen, graph for glm, hybrid for deepseek. No global winner.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  But the trap is real (extended category, subject-validated)
&lt;/h3&gt;

&lt;p&gt;One false trap fact (R42) is statistically meaningless, so we extended the category with a &lt;strong&gt;fixed generator that validates against the subject file&lt;/strong&gt;: false-trap = value present in the project (≥2 files) but absent from the &lt;em&gt;subject file&lt;/em&gt; (grep = 0). 20 false / 10 true facts, pinned run:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;arm&lt;/th&gt;
&lt;th&gt;qwen FA/rec&lt;/th&gt;
&lt;th&gt;deepseek FA/rec&lt;/th&gt;
&lt;th&gt;glm FA/rec&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;file_content&lt;/td&gt;
&lt;td&gt;2/20, 2/10&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;15/20&lt;/strong&gt;, 6/10&lt;/td&gt;
&lt;td&gt;13/20, 7/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;graph_first&lt;/td&gt;
&lt;td&gt;2/20, 3/10&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;8/20&lt;/strong&gt;, 5/10&lt;/td&gt;
&lt;td&gt;14/20, 9/10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The present-trap is &lt;strong&gt;NOT a label artifact&lt;/strong&gt;: on honest labels, file_content false-accepts 10–75% of "X uses Y" claims (deepseek 15/20, glm 13/20). And &lt;strong&gt;graph evidence halves deepseek's false-accept rate (15/20 → 8/20)&lt;/strong&gt; — the "graph doesn't close the trap" conclusion from the original dataset (one false trap fact) was itself a small-sample artifact. It just doesn't help glm (14/20), and qwen was already at 2/20 (paying with recall 2/10).&lt;/p&gt;

&lt;h3&gt;
  
  
  Re-scoring the historical runs (3300+ calls, no re-billing)
&lt;/h3&gt;

&lt;p&gt;We taught the summary tool to recompute metrics from old progress files + corrected truth (verdict-by-id, manually audited — zero field drift). The real picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;True trap-FA (R42): 0 for every model.&lt;/strong&gt; The "present-trap FA 0.02–0.04" in Part 2 was mislabeled data — models were right.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden trap miss_true: qwen/deepseek 4/5&lt;/strong&gt; — fail-closed models rejected true usage claims. This loss was invisible in the old metrics.&lt;/li&gt;
&lt;li&gt;Real fail-open is absent/silent: glm code_first 7+2.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Temporal: "was true then" vs "true now"
&lt;/h2&gt;

&lt;p&gt;The present-trap wasn't only about wrong labels. Digging deeper exposed a harder problem: &lt;strong&gt;models cannot distinguish "X exists now" from "X existed then"&lt;/strong&gt; — unless the question itself carries the tense.&lt;/p&gt;

&lt;p&gt;We built a temporal dataset from git archaeology (48 facts: 12 symbols removed after commit C / 28 current / 8 never-existed, ground truth from &lt;code&gt;git show C~1&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E4 (git provenance in evidence):&lt;/strong&gt; qwen3.7 43/48, deepseek/glm 48/48. Seemed like provenance worked — 2/3 models perfect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E4b (blind control, no git strings):&lt;/strong&gt; &lt;strong&gt;all three models 48/48.&lt;/strong&gt; Git provenance was not just unnecessary — it &lt;em&gt;hurt&lt;/em&gt; qwen ("existed until C" suggests existence, a token-presence trap in the evidence).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E4c (duo design, no hints):&lt;/strong&gt; one neutral evidence block (HEAD state + "SYMBOLS in F at history" from &lt;code&gt;git show C~1&lt;/code&gt;), two questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NOW  ("X is defined in F"):   removed FA: qwen 12/12, glm 12/12, deepseek 9/12
PAST ("X WAS defined in F"):  all three 40/40
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same evidence block for both questions — the only change is the tense of the claim. The 40/40 does not mean the models got better at temporal reasoning; it means they answer the question you actually asked. &lt;strong&gt;The model did not need better memory — it needed a temporally explicit question.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All three models exhibited the temporal present-trap.&lt;/strong&gt; When the evidence mentions X in history and the question is about the present, every model says "true" (12/12, 9/12, 12/12) — a model cannot distinguish "X appears in the evidence" from "X exists now". But phrasing the question in the past tense solves it completely (40/40). The E4b conclusion ("qwen is fragile, deepseek/glm are robust") was itself an artifact of the "NOT FOUND AT HEAD" hint — without it, nobody is robust.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk68981o2wd7972pjvq87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk68981o2wd7972pjvq87.png" alt="The Verb Tense Fix: changing IS to WAS solves temporal hallucination" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Determinism: pin the provider (thank you, comment section)
&lt;/h2&gt;

&lt;p&gt;Before trusting the corrected results, we attacked the execution layer too.&lt;/p&gt;

&lt;p&gt;Part 2's known weakness: temp=0 + seed=42 on OpenRouter is not determinism — ≥8 upstream backends. Tom Jones' comment suggested &lt;code&gt;provider.order&lt;/code&gt; with &lt;code&gt;allow_fallbacks: false&lt;/code&gt;, which pins the endpoint — cheaper than K≥3 repeats.&lt;/p&gt;

&lt;p&gt;We probed it: &lt;strong&gt;StreamLake — the most-used upstream for glm in our server CSV (245 calls) — returns 404 "No endpoints found" when pinned: it no longer serves this model at all.&lt;/strong&gt; Cloudflare/DeepInfra are stable. The full pinned re-run (qwen→Alibaba, deepseek/glm→DeepInfra, ~$0.02) reproduced every conclusion: per-model arm rankings, temporal present-trap (12/12, 9/12, 12/12), past-tense fix (40/40), and FA absent/silent = 0 across evidence arms. One caveat: glm stays non-deterministic even pinned (FA 0.06 → 0.02 → 0.02 across runs) — part of that is model variance, but part is &lt;strong&gt;upstream drift&lt;/strong&gt;: unpinned glm now routes to DeepInfra (not StreamLake), so cross-day comparisons mix changing backends. Pinning removes routing variance at a point in time, not model or availability drift over time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reproduction note: if you reproduce pinned runs, avoid StreamLake — it was the top unpinned provider for glm in our server CSV but returns 404 when pinned (no endpoint for the model; upstream availability drifts). Pinning to a provider that serves you well unpinned is not guaranteed to work; probe before committing to a long run.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for verify-on-read
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Evidence format is a per-model knob.&lt;/strong&gt; qwen-family: file fragment (recall). glm-family: graph (recall + trap precision). deepseek: hybrid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not concatenate evidence formats blindly.&lt;/strong&gt; For qwen, file+graph was strictly worse than file alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Red-team your dataset before trusting metrics.&lt;/strong&gt; One grep on the subject files inverted our headline. Synthetic categories must be validated &lt;em&gt;per subject&lt;/em&gt;, not per project — and FA on a category is meaningless until the category's labels are truth-checked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal questions must be phrased in time.&lt;/strong&gt; "Is X defined in F?" with history in evidence fails universally (12/12, 9/12, 12/12); "Was X defined in F?" succeeds (40/40). For existence checks: HEAD-only evidence, or explicit tense.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pin providers in production runs.&lt;/strong&gt; Cheaper than repeats, and it protects against "popular but broken" upstreams (StreamLake).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The meta-lesson
&lt;/h2&gt;

&lt;p&gt;The most dangerous assumption in LLM evaluation isn't the model — it's the dataset. We spent ~$0.10 and ~1900 calls to learn that 4 of 6 "false" facts were true. Before you trust any LLM benchmark, ask: &lt;strong&gt;who labeled the ground truth, and did they verify it per-example or per-category?&lt;/strong&gt; We didn't — we validated the trap category against the &lt;em&gt;project&lt;/em&gt;, not the &lt;em&gt;subject&lt;/em&gt;. One grep on subject files inverted every conclusion. Every layer of the pipeline can lie: ground truth (this post), evidence (E4b), model interpretation (E4c), execution (provider drift) — we attacked each in turn.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Synthetic categories must be validated &lt;em&gt;per subject&lt;/em&gt;, not per project.&lt;/strong&gt; A value that exists anywhere in the repo is not evidence that the &lt;em&gt;subject&lt;/em&gt; of the claim uses it. Check the subject's file.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h5&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  "Known weaknesses (post-red-team)"&lt;br&gt;
  &lt;ol&gt;

&lt;li&gt;

&lt;strong&gt;Fact order matters (measured).&lt;/strong&gt; Facts are stored block-ordered (R01–R25 true, R26–R50 false). A shuffled control run (qwen code_first, seed 123) changed 4/50 verdicts vs the original order — no systematic direction, but ~8% sensitivity to order. Shuffle-seed in future runs.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Trap category size matters.&lt;/strong&gt; After relabeling, the original dataset has one genuinely false trap fact — but an extended subject-validated category (20 false) shows the present-trap is real and mass-scale (file_content FA 10–75%). Metrics from N=1 are flags, not rates.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Language confound (measured).&lt;/strong&gt; Claims are Russian, instructions English. A Russian-instruction control (file_content) shifted deepseek's unknown rate 13/50 → 1/50 and changed 14/50 verdicts — its "skeptic" profile in this series was partly a prompt-language artifact. qwen/glm shifted 5/50.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Decoy frequency.&lt;/strong&gt; 19 facts share the same control symbol block; models could pattern-match repetition. Not controlled.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Temporal claims are existence claims.&lt;/strong&gt; Easier than the usage claims of the main dataset; the two datasets are complementary, not interchangeable.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Small N, wide CIs.&lt;/strong&gt; 6 trap facts, 12 removed facts. Headline arm rankings rest on differences of 2–3 facts out of 25.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Upstream drift across days.&lt;/strong&gt; Unpinned vs pinned runs happened ~12h apart; glm's routing changed (StreamLake → DeepInfra). Cross-day numbers mix backends.&lt;/li&gt;

&lt;/ol&gt;



&lt;br&gt;


&lt;/h5&gt;
&lt;p&gt;&lt;em&gt;Thanks to the Part 1 comment section: Tom Jones (provider pinning), Skillselion (manifest anchors), Cophy (invalidation triggers), Glen Allen (freshness), 473185670 (Resolution Loop), UnitBuilds (write-path triples) — each thread sharpened this series.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce
&lt;/h2&gt;

&lt;p&gt;Harness: &lt;code&gt;scripts/run_1L_live_arm.py&lt;/code&gt; (arms code_first / file_content_first / graph_first / file_graph_first / temporal_blind_first / temporal_duo_first; &lt;code&gt;--facts&lt;/code&gt;, &lt;code&gt;--ev-contexts&lt;/code&gt;, &lt;code&gt;--pin-provider&lt;/code&gt;). Summaries: &lt;code&gt;scripts/summarize_1L_categories.py --facts &amp;lt;corrected.json&amp;gt;&lt;/code&gt; (truth-based re-score of old runs). Full report with raw outputs and the red-team audit: &lt;code&gt;experiments/2E_evidence_ladder/report.md&lt;/code&gt;. Tests: 64 for harness/builder/generator/summarize, 1265 total.&lt;/p&gt;

&lt;p&gt;Dataset fingerprints: original &lt;code&gt;820bbbf60a0fc930&lt;/code&gt; (historical, mislabeled trap) · corrected &lt;code&gt;e6ce7b902d0a20a9&lt;/code&gt; (29 true / 20 false / 1 ambiguous) · temporal &lt;code&gt;e3c1fdd4&lt;/code&gt; / &lt;code&gt;d1d2c2ed440ec370&lt;/code&gt; · calls: ~1900 across the series · est. cost: &amp;lt; $0.10.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>testing</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Went down a rabbit hole testing whether LLMs can actually verify agent memory claims on their own. Turns out the evidence format matters way more than the model — bare token strings barely work, real code context changes everything.</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Sat, 15 Aug 2026 18:47:15 +0000</pubDate>
      <link>https://dev.to/mansio/went-down-a-rabbit-hole-testing-whether-llms-can-actually-verify-agent-memory-claims-on-their-own-2la2</link>
      <guid>https://dev.to/mansio/went-down-a-rabbit-hole-testing-whether-llms-can-actually-verify-agent-memory-claims-on-their-own-2la2</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" class="crayons-story__hidden-navigation-link"&gt;Bare tokens vs real code: an 11x recall jump in LLM memory verification (3400 calls, 14 models)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/mansio" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4040767%2Fd68a3ffd-1013-490a-a6b0-cc085141576a.jpg" alt="mansio profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mansio" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Mikhail
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Mikhail
                
                
              
              &lt;div id="story-author-preview-content-4399317" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/mansio" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4040767%2Fd68a3ffd-1013-490a-a6b0-cc085141576a.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Mikhail&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 14&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" id="article-link-4399317"&gt;
          Bare tokens vs real code: an 11x recall jump in LLM memory verification (3400 calls, 14 models)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/llm"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;llm&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/memorylayer"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;memorylayer&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/benchmark"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;benchmark&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;12&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              4&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            10 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>testing</category>
    </item>
    <item>
      <title>Bare tokens vs real code: an 11x recall jump in LLM memory verification (3400 calls, 14 models)</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Fri, 14 Aug 2026 21:35:18 +0000</pubDate>
      <link>https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia</link>
      <guid>https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 1: &lt;a href="https://dev.to/mansio/the-mechanical-vs-the-semantic-what-happens-when-ai-memory-is-wrong-38ko"&gt;The Mechanical vs. The Semantic: What Happens When AI Memory is Wrong?&lt;/a&gt; &lt;br&gt;
Part 2: Your memory layer is lying to you (and your LLM agrees)&lt;br&gt;
Part 3: &lt;a href="https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok"&gt;The Dataset Was Lying: 4 of 6 "False" Facts Were True &lt;/a&gt;&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;The verify-on-read experiment (1-V) used a deterministic proxy agent to catch false claims in memory before surfacing them to the user. Proxy FA=0 by construction — useful, but it tells you nothing about what a real LLM would do with the same claims. A reviewer's note from Part 3: &lt;em&gt;"headline numbers were a property of the heuristic, not LLM behavior."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So we ran it with live models. Four days, 14 models, 4 arms, ~3400 API calls. The last arm answered the question the whole experiment was actually asking.&lt;/p&gt;


&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Dataset: &lt;code&gt;memory_contamination_facts_v4_rep.json&lt;/code&gt;, N=50 (R01–R50), sha256 &lt;code&gt;820bbbf60a0fc930&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;kind&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;th&gt;what it tests&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;real&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;TRUE — grep-validated against actual code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;absent-mutation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;FALSE — component doesn't exist in the project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;present-trap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;FALSE — file exists, claim is about the wrong subject&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;silent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;FALSE — external systems the codebase never mentions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Four arms, run sequentially as the experiment evolved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;memory_first&lt;/strong&gt; — model sees only the claim. Does it trust memory without evidence?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code_first&lt;/strong&gt; — claim + &lt;code&gt;support_patterns&lt;/code&gt; (bare token strings) + &lt;code&gt;section&lt;/code&gt;. Does it evaluate the anchors?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code_first CoT&lt;/strong&gt; — same as above, &lt;code&gt;reasoning=true&lt;/code&gt;, max_tokens=1500.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;file_content_first&lt;/strong&gt; — claim + real 25-line file window around the anchor. Can the model verify with actual evidence?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Model verdict: &lt;code&gt;{"verdict": "true"|"false"|"unknown"}&lt;/code&gt;, JSON-only. Zero-shot: max_tokens=100, temp=0, seed=42, &lt;code&gt;--no-reasoning&lt;/code&gt;. Leak-guard: &lt;code&gt;assert "truth" not in prompt&lt;/code&gt; on every fact, unit-tested (39 harness tests, 1226 total).&lt;/p&gt;

&lt;p&gt;Two metrics that both matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;false_accept (FA)&lt;/strong&gt; — fraction of false claims returned as &lt;code&gt;"true"&lt;/code&gt;. Contamination risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;recall(real)&lt;/strong&gt; — fraction of 25 TRUE facts correctly confirmed. A gate that rejects everything has FA=0.00 and recall=0.00. It's a no-op.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Day 1: live models vs. proxy
&lt;/h2&gt;

&lt;p&gt;The proxy always decided — unknown=0 by construction. First live run (opencode/deepseek-v4-flash-free, free tier) returned unknown=0.80. FA=0.10, including R31 in both arms.&lt;/p&gt;

&lt;p&gt;The reviewer's criticism was right immediately.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 2: six cheap models, two full passes, red team
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The sycophancy problem (V1 → V2)
&lt;/h3&gt;

&lt;p&gt;R31 was false-accepted by every model in the first sweep:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;claim&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;            &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;instruction&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;scanner&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Typesense"&lt;/span&gt;
&lt;span class="na"&gt;truth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;            &lt;span class="s"&gt;False&lt;/span&gt;
&lt;span class="na"&gt;support_patterns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;typesense"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;contra&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;           &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;src/core/instruction_scan.py&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;instruction_scan.py&lt;/code&gt; uses only stdlib (&lt;code&gt;re&lt;/code&gt;, &lt;code&gt;logging&lt;/code&gt;, &lt;code&gt;typing&lt;/code&gt;). Typesense is nowhere in the project. Nine false facts in R26–R50 shared this pattern (vespa, pinecone, typesense, tantivy, meilisearch, dataclasses, logging, pathlib, loki) — bare token in &lt;code&gt;support_patterns&lt;/code&gt;, model treats field presence as evidence.&lt;/p&gt;

&lt;p&gt;V1 prompt asked: &lt;em&gt;"Does the claim appear supported by these anchors?"&lt;/em&gt; — leading question. Confirmed sycophancy (Sharma et al. 2023, arXiv 2310.13548).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# V1 — leading:&lt;/span&gt;
Does the claim appear supported by these anchors?

&lt;span class="gh"&gt;# V2 — neutral:&lt;/span&gt;
Return true ONLY if the anchors directly verify the claim;
false if the anchors contradict it or the claim refers to something
absent from the anchors; unknown if you cannot determine.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;V2 reduced FA in 4/6 models. glm-4.7-flash: 0.30 → 0.24. Still not safe.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;--no-reasoning&lt;/code&gt; is mandatory
&lt;/h3&gt;

&lt;p&gt;Without it, GLM-4.7-flash uses 110 reasoning tokens and returns &lt;code&gt;content=None, finish=length&lt;/code&gt; — 100% unusable. With &lt;code&gt;--no-reasoning&lt;/code&gt;: reasoning_tokens=0 confirmed for all models via harness audit and independently via OpenRouter server CSV.&lt;/p&gt;
&lt;h3&gt;
  
  
  temp=0 + seed=42 is not determinism on OpenRouter
&lt;/h3&gt;

&lt;p&gt;nemotron-3.5-lightning code_first: FA 0.18 → 0.08 between two identical runs. ±0.10 on a single-pass measurement. OpenRouter routes to ≥8 upstream backends (server CSV: Alibaba 1955 calls, DeepInfra 559, DigitalOcean 531, Cloudflare 283, Novita 253, Baidu 114, StreamLake 110, Amazon Bedrock 100) — same prompt, different quantizations. qwen3.6/3.7/deepseek stable 3/3. GLM not.&lt;/p&gt;

&lt;p&gt;All final conclusions use upper-bound-of-two-runs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prompt language is model-specific
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deepseek-v4-flash code_first unknown&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;EN: 0.94 → RU&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.54  (RU → commits more)&lt;/span&gt;

&lt;span class="na"&gt;qwen3.7-flash code_first unknown&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;EN: 0.24 → RU&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.58  (RU → hedges more)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Same dataset, same arm, opposite direction per model. Measure per-model before assuming.&lt;/p&gt;

&lt;p&gt;[TODO: verify whether &lt;em&gt;claim&lt;/em&gt; language interacts with prompt language separately — all claims in this dataset are in Russian]&lt;/p&gt;
&lt;h3&gt;
  
  
  Premium models
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;claude-sonnet-5&lt;/strong&gt;: FA=0.00/0.00, acc=1.0 on all decided. But unknown=0.86/0.70 and $0.049/100 calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;qwen3.8-max&lt;/strong&gt;: HTTP 400 on 22–49/50 calls — &lt;em&gt;"Reasoning is mandatory and cannot be disabled."&lt;/em&gt; Not a harness bug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;glm-5.2&lt;/strong&gt;: FA=0.00/0.02 — dramatically better than glm-4.7-flash. Same family, new generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;deepseek-v4-pro&lt;/strong&gt;: FA=0.04/0.00.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Premium gives no FA advantage over the best flash models. The cost difference is 10–100×.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 3: per-category breakdown reveals the real problem
&lt;/h2&gt;

&lt;p&gt;A reviewer asked: &lt;em&gt;"High unknown ≠ high quality. What was the true-accept rate on the 25 real facts? Is qwen3.6-flash cutting true memory along with false?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We added &lt;code&gt;scripts/summarize_1L_categories.py&lt;/code&gt; and ran it on all V2-EN progress files.&lt;/p&gt;
&lt;h3&gt;
  
  
  Per-category results (zero-shot, V2, code_first)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;real: acc/rej/unk&lt;/th&gt;
&lt;th&gt;recall(real)&lt;/th&gt;
&lt;th&gt;F1&lt;/th&gt;
&lt;th&gt;FA absent·trap·silent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-flash&lt;/td&gt;
&lt;td&gt;2 / 7 / 16&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.08&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.15&lt;/td&gt;
&lt;td&gt;0·0·0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.7-flash&lt;/td&gt;
&lt;td&gt;5 / 9 / 11&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.33&lt;/td&gt;
&lt;td&gt;0·0·0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;deepseek-v4-flash&lt;/td&gt;
&lt;td&gt;1 / 0 / 24&lt;/td&gt;
&lt;td&gt;0.04&lt;/td&gt;
&lt;td&gt;0.08&lt;/td&gt;
&lt;td&gt;0·0·0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;claude-sonnet-5&lt;/td&gt;
&lt;td&gt;11 / 0 / 14&lt;/td&gt;
&lt;td&gt;0.44&lt;/td&gt;
&lt;td&gt;0.61&lt;/td&gt;
&lt;td&gt;0·0·0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nemotron-3.5-lightning&lt;/td&gt;
&lt;td&gt;13 / 3 / 9&lt;/td&gt;
&lt;td&gt;0.52&lt;/td&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;0·1·1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;glm-4.7-flash ⚠️&lt;/td&gt;
&lt;td&gt;22 / 1 / 2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.88&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.75&lt;/td&gt;
&lt;td&gt;7·3·2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nemotron-3-nano 🔴&lt;/td&gt;
&lt;td&gt;20 / 1 / 4&lt;/td&gt;
&lt;td&gt;0.80&lt;/td&gt;
&lt;td&gt;0.62&lt;/td&gt;
&lt;td&gt;11·5·3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;qwen3.6-flash code_first: confirmed 2/25 true facts, actively marked 7/25 as &lt;code&gt;false&lt;/code&gt; (wrong), abstained on 16/25. FA=0.00 achieved by not functioning as a verifier. Auto-retraction on these verdicts empties the memory layer, not just the false claims.&lt;/p&gt;

&lt;p&gt;The tradeoff across the sweep:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qwen3.6-flash   F1=0.15   FA=0.00  ← fail-closed
qwen3.7-flash   F1=0.33   FA=0.00  ← fail-closed
claude-sonnet-5 F1=0.61   FA=0.00  ← best at zero-FA
nemotron-3.5    F1=0.65   FA=0.04  ← best F1 overall
glm-4.7-flash   F1=0.75   FA=0.24  ← best coverage, unsafe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No model in zero-shot balanced both. &lt;strong&gt;FA=0.00 is a policy, not a quality metric.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  CoT doesn't fix it
&lt;/h3&gt;

&lt;p&gt;We ran &lt;code&gt;--reasoning --max-tokens 1500&lt;/code&gt; on 4 models, two full passes for stability.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;arm&lt;/th&gt;
&lt;th&gt;recall ZS→CoT&lt;/th&gt;
&lt;th&gt;FA ZS→CoT&lt;/th&gt;
&lt;th&gt;cost/100 ZS→CoT&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-flash&lt;/td&gt;
&lt;td&gt;code_first&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.08→0.20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0→0&lt;/td&gt;
&lt;td&gt;$0.0006→$0.045&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.7-flash&lt;/td&gt;
&lt;td&gt;code_first&lt;/td&gt;
&lt;td&gt;0.20→0.16&lt;/td&gt;
&lt;td&gt;0→0&lt;/td&gt;
&lt;td&gt;$0.0005→$0.005&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;glm-4.7-flash&lt;/td&gt;
&lt;td&gt;code_first&lt;/td&gt;
&lt;td&gt;0.88→0.72&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;12→7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$0.001→$0.017&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;deepseek-flash&lt;/td&gt;
&lt;td&gt;code_first&lt;/td&gt;
&lt;td&gt;0.04→0.08&lt;/td&gt;
&lt;td&gt;0→0&lt;/td&gt;
&lt;td&gt;$0.0009→$0.002&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Only meaningful gain: qwen3.6 code_first recall 0.08→0.20, FA held at 0.00. Cost ×75. qwen3.7 and deepseek: within CI noise. glm-4.7: FA improves but 16–26% of responses are EMPTY_CONTENT (upstream defect in reasoning mode) — numbers are qualitative only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important confounder:&lt;/strong&gt; CoT arm changes two things simultaneously — &lt;code&gt;reasoning=true&lt;/code&gt; AND &lt;code&gt;max_tokens=1500&lt;/code&gt;. Separating them is impossible: qwen3.6 uses 700–1500 reasoning tokens per call.&lt;/p&gt;

&lt;p&gt;qwen3.8-max CoT (mandatory reasoning, the only mode it runs): recall=0.36 code_first, FA=0.04 — best recall-at-low-FA in the zero-shot/CoT sweep. Cost $0.10/100 calls.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 4: file_content_first — the answer
&lt;/h2&gt;

&lt;p&gt;The reviewer's point after Day 3: &lt;em&gt;"Is recall=0.08 model paranoia, or are the pattern strings too narrow to validate anything?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;New arm: instead of &lt;code&gt;support_patterns: ["typesense"]&lt;/code&gt;, the model gets a real 25-line window from the file around the first occurrence of the anchor. For &lt;code&gt;absent&lt;/code&gt; and &lt;code&gt;silent&lt;/code&gt; facts (grep returns nothing), a decoy: the head of &lt;code&gt;src/core/instruction_scan.py&lt;/code&gt;. The decoy is not labeled in the prompt — labeling it would leak ground truth (&lt;code&gt;"not found"&lt;/code&gt; → trivial false). It's marked in results as &lt;code&gt;evidence: decoy&lt;/code&gt; for post-hoc analysis. Prompt instruction identical to code_first V2 (neutral). &lt;strong&gt;Single variable changed vs code_first: form of evidence (token string → code).&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;arm&lt;/th&gt;
&lt;th&gt;recall(real)&lt;/th&gt;
&lt;th&gt;FA&lt;/th&gt;
&lt;th&gt;real: acc/rej/unk&lt;/th&gt;
&lt;th&gt;F1&lt;/th&gt;
&lt;th&gt;FA absent·trap·silent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-flash&lt;/td&gt;
&lt;td&gt;code_first (baseline)&lt;/td&gt;
&lt;td&gt;0.08&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;2/7/16&lt;/td&gt;
&lt;td&gt;0.15&lt;/td&gt;
&lt;td&gt;0·0·0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;qwen3.6-flash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;file_content_first&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.88&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.04&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;22/3/0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;0·2·0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.7-flash&lt;/td&gt;
&lt;td&gt;code_first (baseline)&lt;/td&gt;
&lt;td&gt;0.20&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;5/9/11&lt;/td&gt;
&lt;td&gt;0.33&lt;/td&gt;
&lt;td&gt;0·0·0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;qwen3.7-flash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;file_content_first&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.88&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.02&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;22/2/1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;0·1·0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;recall(real): qwen3.6 &lt;strong&gt;0.08 → 0.88&lt;/strong&gt; (×11). qwen3.7 &lt;strong&gt;0.20 → 0.88&lt;/strong&gt; (×4.4). Wilson CI for 22/25: [0.70, 0.96] — doesn't overlap with baseline CI for 2/25: [0.02, 0.25].&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The model wasn't being paranoid. It had no evidence.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;FA: 0.00 → 0.02–0.04. Every false accept is &lt;code&gt;present-trap&lt;/code&gt; — the anchor token appears in the file fragment, but the claim is about the wrong subject:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;R45: &lt;em&gt;"The server wrapper uses logging"&lt;/em&gt; — fragment is from &lt;code&gt;log_manager.py&lt;/code&gt;, token &lt;code&gt;logging&lt;/code&gt; is there, but the &lt;em&gt;subject&lt;/em&gt; is wrong.&lt;/li&gt;
&lt;li&gt;R46 (qwen3.6 only): &lt;em&gt;"The watchdog uses threading"&lt;/em&gt; — fragment from &lt;code&gt;project_indexer_registry.py&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;absent&lt;/code&gt; 0/16, &lt;code&gt;silent&lt;/code&gt; 0/3 for both models. The decoy policy works: a fragment without the token returns &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt; without leaking.&lt;/p&gt;

&lt;p&gt;Remaining false rejects on real facts: R07/R08 (both models) — claims with semantically bad &lt;code&gt;value&lt;/code&gt; field ("uses disabled", "uses forbidden" — adjective instead of noun; fragment shows the env-var but not the adjective); R21 (qwen3.6), R03 (qwen3.7) — individual confidence threshold differences.&lt;/p&gt;
&lt;h3&gt;
  
  
  What this means for VOR architecture
&lt;/h3&gt;

&lt;p&gt;The problem was always the evidence layer, not the model.&lt;/p&gt;

&lt;p&gt;Showing a model &lt;code&gt;support_patterns: ["typesense"]&lt;/code&gt; and asking it to verify a claim is not verification — it's asking the model to confirm the field value matches the field name. The model correctly doesn't know what to do with it, so it abstains or guesses.&lt;/p&gt;

&lt;p&gt;Showing the model 25 lines of actual code around the anchor: recall 0.88, FA 0.02–0.04, $0.005/100 calls. The remaining failure mode is subject-mismatch in &lt;code&gt;present-trap&lt;/code&gt; facts — the model checks token presence, not claim subject identity. That's a harder problem but a much smaller one.&lt;/p&gt;

&lt;p&gt;Cost of adding a file window: ~200 extra prompt tokens per fact. At flash pricing, that's $0.0001–0.0004/fact. Negligible against the cost of retracting true memory.&lt;/p&gt;


&lt;h2&gt;
  
  
  Full results summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;arm&lt;/th&gt;
&lt;th&gt;recall(real)&lt;/th&gt;
&lt;th&gt;FA&lt;/th&gt;
&lt;th&gt;F1&lt;/th&gt;
&lt;th&gt;$/100&lt;/th&gt;
&lt;th&gt;notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-flash&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;file_content&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.88&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.04&lt;/td&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;$0.005&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;recommended&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.7-flash&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;file_content&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.88&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.02&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;$0.005&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;recommended&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.8-max&lt;/td&gt;
&lt;td&gt;CoT&lt;/td&gt;
&lt;td&gt;0.36&lt;/td&gt;
&lt;td&gt;0.04&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;$0.102&lt;/td&gt;
&lt;td&gt;if file access unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nemotron-3.5&lt;/td&gt;
&lt;td&gt;zero-shot&lt;/td&gt;
&lt;td&gt;0.52&lt;/td&gt;
&lt;td&gt;0.04&lt;/td&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;$0.001&lt;/td&gt;
&lt;td&gt;if file access unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;claude-sonnet-5&lt;/td&gt;
&lt;td&gt;zero-shot&lt;/td&gt;
&lt;td&gt;0.44&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.61&lt;/td&gt;
&lt;td&gt;$0.049&lt;/td&gt;
&lt;td&gt;if FA=0.00 required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.7-flash&lt;/td&gt;
&lt;td&gt;zero-shot&lt;/td&gt;
&lt;td&gt;0.20&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.33&lt;/td&gt;
&lt;td&gt;$0.0005&lt;/td&gt;
&lt;td&gt;fail-closed only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen3.6-flash&lt;/td&gt;
&lt;td&gt;zero-shot&lt;/td&gt;
&lt;td&gt;0.08&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;0.15&lt;/td&gt;
&lt;td&gt;$0.0006&lt;/td&gt;
&lt;td&gt;fail-closed only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;glm-4.7-flash&lt;/strong&gt; ⚠️&lt;/td&gt;
&lt;td&gt;zero-shot&lt;/td&gt;
&lt;td&gt;0.88&lt;/td&gt;
&lt;td&gt;0.24&lt;/td&gt;
&lt;td&gt;0.75&lt;/td&gt;
&lt;td&gt;$0.001&lt;/td&gt;
&lt;td&gt;exclude&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;nemotron-3-nano&lt;/strong&gt; 🔴&lt;/td&gt;
&lt;td&gt;zero-shot&lt;/td&gt;
&lt;td&gt;0.80&lt;/td&gt;
&lt;td&gt;0.38&lt;/td&gt;
&lt;td&gt;0.62&lt;/td&gt;
&lt;td&gt;$0.0008&lt;/td&gt;
&lt;td&gt;exclude&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Known weaknesses
&lt;/h2&gt;

&lt;p&gt;Five limitations, stated before a reviewer raises them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Upstream routing variance (partially mitigated).&lt;/strong&gt; temp=0 + seed=42 on OpenRouter is not true determinism — 8+ backends. Mitigated by 2–3 passes per condition, upper-bound-of-runs. Not mitigated: K≥3 repeats per fact/model pair (~4200 calls, ~$2–5) — not done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Anchor bias vs. snippet truncation (closed).&lt;/strong&gt; V4 (§6.6b) confirmed anchor bias: recall 0.08→0.88 with real file content. The residual failure in present-trap (R45, R46) is subject-identity checking, not truncation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Synthetic mutations vs. real drift (in progress).&lt;/strong&gt; The 25 false facts are synthetic (absent/trap/silent), not real git-refactoring drift. 30-day longitudinal protocol is running — data not yet collected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Single codebase, single language (not closed).&lt;/strong&gt; All 50 facts from one Python project. TypeScript/Rust/Go have harder type anchors — transfer is extrapolation. Multi-repo extension needs ~$0.4–3.6 and 1–2 days of grep-validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Three-way verdict vs. confidence score (not closed).&lt;/strong&gt; The &lt;code&gt;true/false/unknown&lt;/code&gt; frame may push "partially stale" claims into &lt;code&gt;unknown&lt;/code&gt;. A 5-point confidence scale would need a new prompt, parser, and graded dataset. What we can say: &lt;code&gt;finish_reason=stop&lt;/code&gt; everywhere in zero-shot — high unknown is genuine uncertainty, not truncation.&lt;/p&gt;


&lt;h2&gt;
  
  
  What to use
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For a working VOR gate:&lt;/strong&gt; qwen3.6-flash or qwen3.7-flash with &lt;code&gt;file_content_first&lt;/code&gt;. recall=0.88, FA=0.02–0.04, $0.005/100 calls. The only failure mode is &lt;code&gt;present-trap&lt;/code&gt; — the model sees the right token in the wrong file context. Acceptable for flag-and-review; not yet for fully autonomous retraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If file access is unavailable at verdict time:&lt;/strong&gt; qwen3.8-max CoT (recall=0.36, FA=0.04, mandatory reasoning, $0.10/100). Better than any zero-shot option on recall. Or nemotron-3.5-lightning (recall=0.52, FA=0.04, $0.001/100) as the cheapest zero-shot model with reasonable F1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fail-closed (contamination-intolerant, recall doesn't matter):&lt;/strong&gt; qwen3.6/3.7 zero-shot. FA=0.00 confirmed 0/400 code_first verdicts across 4 runs. Cheapest. Expect to retract ~80–92% of true memory alongside false.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exclude:&lt;/strong&gt; glm-4.7-flash (FA=0.24), nemotron-3-nano (FA=0.38).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measure on your own dataset before deploying.&lt;/strong&gt; These numbers are from one Python codebase.&lt;/p&gt;


&lt;h2&gt;
  
  
  Reproduce it
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;repo&amp;gt; mscodebase &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;mscodebase

&lt;span class="c"&gt;# Windows&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; venv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\p&lt;/span&gt;ython &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="c"&gt;# macOS/Linux&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; venv/bin/pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# .env: OPENROUTER_API_KEY=sk-or-v1-...&lt;/span&gt;

&lt;span class="c"&gt;# integrity check&lt;/span&gt;
python scripts/run_1L_live_arm.py &lt;span class="nt"&gt;--arm&lt;/span&gt; both &lt;span class="nt"&gt;--dry-run&lt;/span&gt;

&lt;span class="c"&gt;# canonical flash sweep, V2, ~600 calls, ~$0.009&lt;/span&gt;
python scripts/run_1L_live_arm.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; openrouter &lt;span class="nt"&gt;--arm&lt;/span&gt; both &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--models&lt;/span&gt; &lt;span class="s2"&gt;"qwen/qwen3.7-flash,qwen/qwen3.6-flash,qwen/qwen3.5-flash-02-23,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
deepseek/deepseek-v4-flash,z-ai/glm-4.7-flash,nvidia/nemotron-3.5-lightning"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt-version&lt;/span&gt; v2 &lt;span class="nt"&gt;--no-reasoning&lt;/span&gt; &lt;span class="nt"&gt;--tag&lt;/span&gt; v2_en

&lt;span class="c"&gt;# per-category breakdown&lt;/span&gt;
python scripts/summarize_1L_categories.py &lt;span class="nt"&gt;--tag&lt;/span&gt; v2_en

&lt;span class="c"&gt;# V4: real file snippets, ~100 calls, ~$0.005&lt;/span&gt;
python scripts/run_1L_live_arm.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; openrouter &lt;span class="nt"&gt;--arm&lt;/span&gt; file_content_first &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--models&lt;/span&gt; &lt;span class="s2"&gt;"qwen/qwen3.6-flash,qwen/qwen3.7-flash"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt-version&lt;/span&gt; v2 &lt;span class="nt"&gt;--no-reasoning&lt;/span&gt; &lt;span class="nt"&gt;--tag&lt;/span&gt; file_content

&lt;span class="c"&gt;# CoT arm, ~400 calls, ~$0.20&lt;/span&gt;
python scripts/run_1L_live_arm.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; openrouter &lt;span class="nt"&gt;--arm&lt;/span&gt; both &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--models&lt;/span&gt; &lt;span class="s2"&gt;"qwen/qwen3.6-flash,qwen/qwen3.7-flash,z-ai/glm-4.7-flash,deepseek/deepseek-v4-flash"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt-version&lt;/span&gt; v2 &lt;span class="nt"&gt;--reasoning&lt;/span&gt; &lt;span class="nt"&gt;--max-tokens&lt;/span&gt; 1500 &lt;span class="nt"&gt;--tag&lt;/span&gt; v3_cot

&lt;span class="c"&gt;# second pass for any arm (variance check)&lt;/span&gt;
python scripts/run_1L_live_arm.py &lt;span class="o"&gt;[&lt;/span&gt;same args] &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Dataset fingerprint: &lt;code&gt;820bbbf60a0fc930&lt;/code&gt;. Full report: &lt;code&gt;experiments/exp_1L_live_arm_report.md&lt;/code&gt;. Tests: &lt;code&gt;tests/test_run_1L_live_arm.py&lt;/code&gt; (39), &lt;code&gt;tests/test_summarize_1L_categories.py&lt;/code&gt; (8).&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://github.com/ManSio" rel="noopener noreferrer"&gt;github.com/ManSio&lt;/a&gt; · Portfolio: &lt;a href="https://mansio.github.io/MSPortfolio" rel="noopener noreferrer"&gt;mansio.github.io/MSPortfolio&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok" class="crayons-story__hidden-navigation-link"&gt;The Dataset Was Lying: 4 of 6 "False" Facts Were True&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/mansio" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4040767%2Fd68a3ffd-1013-490a-a6b0-cc085141576a.jpg" alt="mansio profile" class="crayons-avatar__image" width="512" height="512"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mansio" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Mikhail
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Mikhail
                
                
              
              &lt;div id="story-author-preview-content-4409809" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/mansio" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4040767%2Fd68a3ffd-1013-490a-a6b0-cc085141576a.jpg" class="crayons-avatar__image" alt="" width="512" height="512"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Mikhail&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 16&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok" id="article-link-4409809"&gt;
          The Dataset Was Lying: 4 of 6 "False" Facts Were True
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/testing"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;testing&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;7&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/mansio/the-dataset-was-lying-4-of-6-false-facts-were-true-13ok#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            9 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;


</description>
      <category>llm</category>
      <category>memorylayer</category>
      <category>agents</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>I turned my portfolio into an MCP server (and I'm not a programmer)</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Fri, 14 Aug 2026 13:14:02 +0000</pubDate>
      <link>https://dev.to/mansio/i-turned-my-portfolio-into-an-mcp-server-and-im-not-a-programmer-4h0a</link>
      <guid>https://dev.to/mansio/i-turned-my-portfolio-into-an-mcp-server-and-im-not-a-programmer-4h0a</guid>
      <description>&lt;h1&gt;
  
  
  I turned my portfolio into an MCP server (and I'm not a programmer)
&lt;/h1&gt;

&lt;p&gt;My background is civil engineering. I don't write code — I direct AI agents to write it while I handle architecture, decisions, and QA.&lt;/p&gt;

&lt;p&gt;So when I built my portfolio, I didn't want it to look like everyone else's. I wanted it to &lt;em&gt;do&lt;/em&gt; something no one else's does.&lt;/p&gt;

&lt;p&gt;Here's what I built: a portfolio that answers questions from AI agents directly. Not a chatbot. Not a demo. A real server that any AI — Claude, GPT, anything — can connect to and interrogate.&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;--transport&lt;/span&gt; http msp-portfolio &lt;span class="se"&gt;\&lt;/span&gt;
  https://msp-portfolio.mansio-dev.workers.dev/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask it &lt;em&gt;"what has Mikhail built?"&lt;/em&gt; or &lt;em&gt;"does his stack match this job description?"&lt;/em&gt; and it answers with live data — not a frozen PDF from six months ago.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem I was solving
&lt;/h2&gt;

&lt;p&gt;Every portfolio makes the same silent promise: "trust that this is still true."&lt;/p&gt;

&lt;p&gt;It's a snapshot. The moment you close the editor, it starts going stale. And there's no way for anyone — human or AI recruiter — to verify what's actually there.&lt;/p&gt;

&lt;p&gt;I wanted the opposite. A portfolio that doesn't just display claims, but answers questions about them. If the evidence for a skill isn't there, it says so instead of bluffing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually built
&lt;/h2&gt;

&lt;p&gt;The site has three parts that share the same brain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The website&lt;/strong&gt; — what you see when you open it in a browser. Interactive, dark-themed, with a simulator you can break.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A server for AI agents&lt;/strong&gt; — the same data, but in a format any AI can query directly. This is the MCP part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A local version&lt;/strong&gt; — for development and testing from the command line.&lt;/p&gt;

&lt;p&gt;The unusual thing: all three read from exactly the same source. No copy-pasting, no "API version" vs "website version." One place, three doors.&lt;/p&gt;




&lt;h2&gt;
  
  
  The nine tools
&lt;/h2&gt;

&lt;p&gt;Think of these as questions the AI can ask my portfolio:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Who is Mikhail?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_profile&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What has he built?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_projects&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What has he been working on lately?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_commit_history&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What are his engineering principles?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_engineering_principles&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What has he written recently?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_articles&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What mistakes has he made?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_antipatterns&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;How does his stack match this job?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;analyze_stack&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What decisions did he make and when?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_timeline&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What happens to his architecture under load?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;simulate_architecture&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The one recruiters use most: &lt;code&gt;analyze_stack&lt;/code&gt;. You paste a job description, it returns a per-skill breakdown with actual evidence — not "I know Kubernetes" but "used in project X, decision log here."&lt;/p&gt;

&lt;p&gt;The one I'm most proud of: &lt;code&gt;get_antipatterns&lt;/code&gt;. It's a museum of real mistakes I made while building this — a forked repo I accidentally claimed as mine, a feature that worked in local tests and silently broke in production, a counter that looked like it was writing data and wasn't. Honest lessons, not a polished highlight reel.&lt;/p&gt;




&lt;h2&gt;
  
  
  The simulator
&lt;/h2&gt;

&lt;p&gt;The portfolio has a live architecture simulator. You pick one of my real projects, pick a failure scenario — kill a node, freeze the cache, overload the AI — and watch the performance numbers change in real time.&lt;/p&gt;

&lt;p&gt;It's not a video. It's not a screenshot. It runs the actual model.&lt;/p&gt;

&lt;p&gt;At 20× load on the search architecture: p95 latency goes from ~10ms to 239ms under a load spike, 401ms if a node dies. When it crosses a threshold, a chip appears: &lt;code&gt;circuit_open&lt;/code&gt;, &lt;code&gt;fallback_engaged&lt;/code&gt;, &lt;code&gt;degraded_mode&lt;/code&gt;. This is what I mean when I say "I understand distributed systems" — you can verify it yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  What broke (the honest part)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The package that doesn't exist.&lt;/strong&gt; I spent time trying to install &lt;code&gt;@fastify/mcp&lt;/code&gt;. It doesn't exist. The real name is &lt;code&gt;@modelcontextprotocol/fastify&lt;/code&gt;. Simple mistake, cost an hour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The function that worked locally and did nothing in production.&lt;/strong&gt; I had a counter that tracked how many times the MCP server was queried. It passed all tests. In production, the counter never wrote anything. Reason: in Cloudflare Workers, code that runs after you send a response gets cancelled immediately. My counter was running after the response. Fix: one line — &lt;code&gt;ctx.waitUntil(task)&lt;/code&gt;. The lesson is that local Node.js and Cloudflare Workers have different rules about what happens after a request ends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The rate limiter that reported success but did nothing.&lt;/strong&gt; I set up a rate limit on the free plan. Every call returned &lt;code&gt;success: true&lt;/code&gt;. Enforcement simply wasn't active at that tier. I only caught it by deliberately triggering it with a burst test. Configuration saying "yes" and the system actually enforcing it are two different things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The hourly commit that silently moved the code forward without me.&lt;/strong&gt; The CI runs every hour to refresh metrics. Each run makes a commit. If I pushed without fetching first, I'd be pushing on top of a diverged history. Now I always &lt;code&gt;git fetch&lt;/code&gt; first. Not a disaster, just a thing you learn once.&lt;/p&gt;




&lt;h2&gt;
  
  
  One thing I didn't expect
&lt;/h2&gt;

&lt;p&gt;The agent loop — where you can type a question and watch the AI call tools step by step, live, in the browser — turned out to be the most interesting part to watch.&lt;/p&gt;

&lt;p&gt;You see it think. It calls &lt;code&gt;get_profile&lt;/code&gt;, reads the result, decides it needs more, calls &lt;code&gt;analyze_stack&lt;/code&gt;, compares, then answers. The whole chain is visible. It's not a black box with an answer at the end. It's a process you can audit.&lt;/p&gt;

&lt;p&gt;I didn't plan that as a feature. It came from trying to debug the demo and realizing the debug view was more interesting than the final answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio:&lt;/strong&gt; &lt;a href="https://mansio.github.io/MSPortfolio/" rel="noopener noreferrer"&gt;mansio.github.io/MSPortfolio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/ManSio/MSPortfolio" rel="noopener noreferrer"&gt;github.com/ManSio/MSPortfolio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add to Claude:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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;--transport&lt;/span&gt; http msp-portfolio &lt;span class="se"&gt;\&lt;/span&gt;
    https://msp-portfolio.mansio-dev.workers.dev/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask it: &lt;em&gt;"what did your mistakes teach you?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you build something like this, drop a comment. I'd genuinely like to see it.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>cloudflare</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>The Mechanical vs. The Semantic: What Happens When AI Memory is Wrong?</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Tue, 11 Aug 2026 19:22:59 +0000</pubDate>
      <link>https://dev.to/mansio/the-mechanical-vs-the-semantic-what-happens-when-ai-memory-is-wrong-38ko</link>
      <guid>https://dev.to/mansio/the-mechanical-vs-the-semantic-what-happens-when-ai-memory-is-wrong-38ko</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2trbza7oxxgf0xknmdhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2trbza7oxxgf0xknmdhk.png" alt="msmasnio" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Part 1: The Mechanical vs. The Semantic: What Happens When AI Memory is Wrong? &lt;br&gt;
Part 2: &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia"&gt;Your memory layer is lying to you (and your LLM agrees)&lt;/a&gt;&lt;br&gt;
Part 3: &lt;a href="https://dev.to/mansio/the-mechanical-vs-the-semantic-what-happens-when-ai-memory-is-wrong-38ko"&gt;The Dataset Was Lying: 4 of 6 "False" Facts Were True &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We talk a lot about giving AI agents persistent memory—building a "Second Brain" or "Knowledge OS" where agents can log decisions and retrieve context. &lt;/p&gt;

&lt;p&gt;But what happens when that memory is wrong? &lt;/p&gt;

&lt;p&gt;I’ve been thinking about the gap between &lt;em&gt;mechanical execution&lt;/em&gt; (the agent called the tool, the code compiled, the exit code was 0) and &lt;em&gt;semantic truth&lt;/em&gt; (the conclusion drawn from that execution is actually correct in reality). It’s easy to assume that if the mechanical layer is solid, the semantic layer will follow. But I started suspecting this might be a dangerous assumption.&lt;/p&gt;

&lt;p&gt;To test this, I didn't want to just theorize. I ran a controlled experiment on my own MCP codebase-intelligence server (Python, 50K LOC), which features an &lt;code&gt;IntelligenceStore&lt;/code&gt; — a persistent memory layer where agents can log incidents and collect Architectural Decision Records (ADRs).&lt;/p&gt;

&lt;p&gt;I wanted to know: If an agent's memory is poisoned with a mix of true and false facts, does it verify against the code, or does it blindly trust its memory?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;This post originally covered the initial Memory Contamination experiment and a Retraction mechanism. I have since updated it with the results of a follow-up experiment (Experiment 1-V) implementing "Verify-On-Read", which successfully closed the final 12% contamination gap. Scroll down to "Closing the Gap: Verify-On-Read" for the final architecture.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  The Experiment: Memory Contamination
&lt;/h3&gt;

&lt;p&gt;I built a deterministic proxy-agent and ran it against a controlled set of facts. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;A quick caveat on methodology:&lt;/em&gt; I didn't have a live LLM hooked up for this run, so I used a deterministic proxy-agent based on heuristics. This means the results measure the &lt;em&gt;system's structural capability&lt;/em&gt;, not necessarily the psychological behavior of a live Claude or GPT model. A live model might be lazier, or it might be smarter. I'm still trying to figure that out.&lt;/p&gt;
&lt;h4&gt;
  
  
  The Setup
&lt;/h4&gt;

&lt;p&gt;I injected 50 facts into an isolated memory store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;25 TRUE facts&lt;/strong&gt; (real architectural details mapped to the codebase).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;25 FALSE facts&lt;/strong&gt; split into two categories:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CONTRADICT (22):&lt;/strong&gt; False facts where the code explicitly proves them wrong (e.g., "We use Redis" when Redis is absent, but the code clearly uses DuckDB).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SILENT (3):&lt;/strong&gt; Plausible false facts about external systems where the code is completely mute (e.g., "We use Celery for background tasks" when no task queue exists in the repo).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tested three agent configurations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;B (No Memory):&lt;/strong&gt; Baseline. Must rely purely on code retrieval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A_code_first (Honest Agent):&lt;/strong&gt; Checks the code first, uses memory only as secondary context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A_memory_first (Lazy Agent):&lt;/strong&gt; Reads memory first. If it finds an answer, it stops looking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To ensure scientific rigor, the experiment was replicated with an independent set of facts (N=50), verified across 6 axes (including a truth-table audit and an independent LLM "fresh eyes" audit). The results were identical.&lt;/p&gt;


&lt;h3&gt;
  
  
  The Initial Results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arm&lt;/th&gt;
&lt;th&gt;Correct&lt;/th&gt;
&lt;th&gt;Adopted False Facts&lt;/th&gt;
&lt;th&gt;Correction Capability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;B (No Memory)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.94&lt;/td&gt;
&lt;td&gt;0.0%&lt;/td&gt;
&lt;td&gt;0.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A_code_first&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.94&lt;/td&gt;
&lt;td&gt;12%&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A_memory_first&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here is how I interpreted these numbers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Lazy Agent Trusts Poisoned Memory:&lt;/strong&gt; The &lt;code&gt;A_memory_first&lt;/code&gt; configuration — which mirrors how many token-optimizing production agents behave — adopted 100% of the false facts. If the memory said "We use RabbitMQ," the agent trusted it and stopped looking at the code. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The SILENT-Fact Trap:&lt;/strong&gt; Even the "Honest Agent" had a 12% adoption rate. This happened entirely on the SILENT facts. When a fact is false but the code doesn't explicitly scream "NO," the agent's memory fills the void with a confident hallucination. Memory turns an honest &lt;code&gt;UNKNOWN&lt;/code&gt; state into a structural guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Add-Only Limitation:&lt;/strong&gt; When the Honest Agent &lt;em&gt;did&lt;/em&gt; realize the memory was wrong (Correction Capability = 1.0), it couldn't do anything about it. I ran a &lt;code&gt;grep&lt;/code&gt; for &lt;code&gt;delete&lt;/code&gt; or &lt;code&gt;refute&lt;/code&gt; in the memory store API. &lt;strong&gt;Zero results.&lt;/strong&gt; The memory system was purely add-only. The false fact stayed in the database to poison future sessions.&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;
  
  
  The First Fix: Testing a Retraction Lifecycle
&lt;/h3&gt;

&lt;p&gt;The current industry consensus for "Knowledge OS" trust layers is to use timestamps, source priority, and &lt;code&gt;supersedes/contradicts&lt;/code&gt; relationships. &lt;/p&gt;

&lt;p&gt;My initial experiment suggested this was insufficient. Timestamps and "supersedes" links only solve &lt;em&gt;node-level&lt;/em&gt; history. If an ADR is superseded, the memory node updates, but the downstream code, tests, and docs generated from the old assumption are still in the graph. They are structurally stale, but the retrieval engine keeps pulling them in.&lt;/p&gt;

&lt;p&gt;I hypothesized that we needed an explicit state transition: &lt;code&gt;VERIFIED → REFUTED&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I implemented a &lt;code&gt;RetractionReceipt&lt;/code&gt; mechanism in my system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Status Enum:&lt;/strong&gt; Every memory node gets a status (&lt;code&gt;ACTIVE&lt;/code&gt;, &lt;code&gt;VERIFIED&lt;/code&gt;, &lt;code&gt;REFUTED&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard Filtering:&lt;/strong&gt; The retrieval pipeline (&lt;code&gt;load_memory&lt;/code&gt;) hard-filters anything that is not &lt;code&gt;ACTIVE&lt;/code&gt; or &lt;code&gt;VERIFIED&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit Retraction Tool:&lt;/strong&gt; An MCP tool (&lt;code&gt;intel_retract_memory_node&lt;/code&gt;) allows the agent to actively flag and invalidate memories when they contradict the live codebase.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I ran the experiment again (Experiment 1-R). The honest agent was allowed to use the retraction tool in Session 1. Then, a fresh &lt;code&gt;memory_first&lt;/code&gt; agent was launched in Session 2 to read the post-retraction memory.&lt;/p&gt;
&lt;h4&gt;
  
  
  The Retraction Results
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Original (Add-Only)&lt;/th&gt;
&lt;th&gt;With Retraction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Adoption (Lazy Agent, Session 2)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.0 (100%)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.12 (12%)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Persistent False Facts in Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3 (-88%)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Token Context Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-45%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Systemic Correction Capability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.0 (couldn't delete)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.0 (22/22 refuted)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The retraction lifecycle worked. The lazy agent's adoption rate dropped from 100% to 12%. Persistent false facts dropped by 88%, and token context size shrank by 45% because refuted facts were filtered out before reaching the LLM.&lt;/p&gt;


&lt;h3&gt;
  
  
  The Honest Limitation: Why It Didn't Drop to Zero
&lt;/h3&gt;

&lt;p&gt;My ADR predicted that adoption would drop to 0. It didn't. It dropped to 0.12.&lt;/p&gt;

&lt;p&gt;The remaining 12% were the SILENT facts. &lt;/p&gt;

&lt;p&gt;An explicit &lt;code&gt;REFUTED&lt;/code&gt; status is required to programmatically exclude downstream dependencies from the retrieval pipeline. But even that only works if you have a contradicting signal in the code. If the memory claims "We use Celery," and the codebase simply doesn't mention Celery at all, the agent has no evidence to trigger the retraction. &lt;/p&gt;

&lt;p&gt;To get to zero, I realized we needed "verify-on-read"—a mechanism that challenges a memory claim against the codebase even when the code is mute. &lt;/p&gt;


&lt;h3&gt;
  
  
  Closing the Gap: Verify-On-Read
&lt;/h3&gt;

&lt;p&gt;I implemented a lazy validation layer (ADR-0003). When &lt;code&gt;load_memory()&lt;/code&gt; pulls a node, it extracts lightweight "anchors" from the memory text (e.g., file names, import statements, environment variables). It then checks if those anchors actually exist in a live fingerprint of the codebase (the current &lt;code&gt;git HEAD&lt;/code&gt;).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the anchor is found in the code $\rightarrow$ status becomes &lt;code&gt;VERIFIED&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the code explicitly contradicts the anchor (or the anchor is entirely absent when it should be present) $\rightarrow$ status becomes &lt;code&gt;REFUTED&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If it can't be determined $\rightarrow$ status remains &lt;code&gt;ACTIVE&lt;/code&gt; (treated as &lt;code&gt;INCONCLUSIVE&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ran the experiment one final time (Experiment 1-V) with this layer active. To prevent latency spikes, the validation operates under a strict 50ms budget per retrieval, with a 30-second TTL cache on the &lt;code&gt;git HEAD&lt;/code&gt; so steady-state reads cost almost nothing.&lt;/p&gt;
&lt;h4&gt;
  
  
  The Final Results
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;With Retraction (1-R)&lt;/th&gt;
&lt;th&gt;With Verify-On-Read (1-V)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Adoption (Honest Agent, &lt;code&gt;A_code_first&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.12 (12%)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.0 (0%)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Adoption (Lazy Agent, &lt;code&gt;A_memory_first&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.12 (12%)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.16 (16%)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Steady-State Retrieval Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~0.6ms&lt;/strong&gt; (Cache hit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SILENT-Fact Contamination (Honest)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3 facts&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0 facts&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Verify-On-Read layer achieved the goal. The honest agent's adoption of false facts dropped to absolute zero, even for SILENT facts. Because the system now actively checks if the codebase actually contains the things the memory claims it does, silent hallucinations are caught at the retrieval boundary and filtered out before they can poison the LLM's context.&lt;/p&gt;
&lt;h4&gt;
  
  
  The Remaining Honest Limitations
&lt;/h4&gt;

&lt;p&gt;I won't pretend this is a perfect silver bullet. The experiment revealed two edge cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The "Present-Trap":&lt;/strong&gt; If a false memory claims "We use &lt;code&gt;sqlite3&lt;/code&gt;", and &lt;code&gt;sqlite3&lt;/code&gt; happens to be imported somewhere in the codebase for a completely unrelated reason, the verification layer sees the token and marks the memory as &lt;code&gt;VERIFIED&lt;/code&gt;. The lazy agent (&lt;code&gt;A_memory_first&lt;/code&gt;) still fell for this, resulting in the 0.16 adoption rate. (The honest agent avoided this because it read the code context around the import).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anchor Typing:&lt;/strong&gt; When extracting anchors from prose (e.g., "We use &lt;code&gt;fastmcp&lt;/code&gt;"), the system initially missed that the actual Python import was &lt;code&gt;from mcp.server.fastmcp import ...&lt;/code&gt;. This caused some false &lt;code&gt;REFUTED&lt;/code&gt; verdicts on true facts. The fix is capturing typed anchors at the &lt;em&gt;write-path&lt;/em&gt; (when the memory is created), rather than trying to parse them from raw text at the &lt;em&gt;read-path&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Building reliable AI systems isn't just about giving them more context. It's about recognizing that memory has a lifecycle.&lt;/p&gt;

&lt;p&gt;If your system can't programmatically refute a memory, false facts accumulate and poison the context window over time. Implementing an explicit &lt;code&gt;VERIFIED → REFUTED&lt;/code&gt; state transition drastically reduces contamination and saves tokens. Furthermore, adding a &lt;code&gt;Verify-On-Read&lt;/code&gt; layer closes the final gap on "silent" hallucinations, driving honest agent contamination to zero without adding meaningful latency.&lt;/p&gt;

&lt;p&gt;However, semantic drift is still a hard problem. Mechanical verification can still be fooled by "present-traps" if the agent doesn't read the surrounding context. The next step is moving anchor extraction to the write-path to ensure memories are created with strict, verifiable references from the start.&lt;/p&gt;

&lt;p&gt;If your system handles semantic drift differently, or if you've solved the present-trap problem, I'd genuinely love to hear how you're approaching it.&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" class="crayons-story__hidden-navigation-link"&gt;Bare tokens vs real code: an 11x recall jump in LLM memory verification (3400 calls, 14 models&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/mansio" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4040767%2Fd68a3ffd-1013-490a-a6b0-cc085141576a.jpg" alt="mansio profile" class="crayons-avatar__image" width="512" height="512"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mansio" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Mikhail
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Mikhail
                
                
              
              &lt;div id="story-author-preview-content-4399317" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/mansio" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4040767%2Fd68a3ffd-1013-490a-a6b0-cc085141576a.jpg" class="crayons-avatar__image" alt="" width="512" height="512"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Mikhail&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 14&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" id="article-link-4399317"&gt;
          Bare tokens vs real code: an 11x recall jump in LLM memory verification (3400 calls, 14 models
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/llm"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;llm&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/memorylayer"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;memorylayer&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/benchmark"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;benchmark&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;8&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/mansio/your-memory-layer-is-lying-to-you-and-your-llm-agrees-1oia#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            10 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>agents</category>
      <category>architecture</category>
      <category>mcp</category>
    </item>
    <item>
      <title>What I learned building a long-lived AI agent (the boring version)</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Sun, 09 Aug 2026 13:40:04 +0000</pubDate>
      <link>https://dev.to/mansio/what-i-learned-building-a-long-lived-ai-agent-the-boring-version-32p8</link>
      <guid>https://dev.to/mansio/what-i-learned-building-a-long-lived-ai-agent-the-boring-version-32p8</guid>
      <description>&lt;p&gt;Not a researcher. Not a professional dev. Civil engineering background. Started building an AI bot because I wanted to understand what's actually happening inside these systems — not theoretically, just practically.&lt;/p&gt;

&lt;p&gt;Wanted an assistant that could &lt;em&gt;live with&lt;/em&gt; a conversation instead of treating every message as an isolated API call.&lt;/p&gt;

&lt;p&gt;It started as an experiment. Then the experiment grew.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it turned into
&lt;/h2&gt;

&lt;p&gt;At some point I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;routing between reasoning profiles&lt;/li&gt;
&lt;li&gt;multiple tools&lt;/li&gt;
&lt;li&gt;web search&lt;/li&gt;
&lt;li&gt;memory (flat + semantic + graph)&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;context compression&lt;/li&gt;
&lt;li&gt;feedback loops&lt;/li&gt;
&lt;li&gt;self-learning experiments&lt;/li&gt;
&lt;li&gt;quality monitoring&lt;/li&gt;
&lt;li&gt;batch processing&lt;/li&gt;
&lt;li&gt;telemetry&lt;/li&gt;
&lt;li&gt;health checks&lt;/li&gt;
&lt;li&gt;and enough logs to make me question my own sanity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wasn't trying to build a benchmark. I was trying to make the thing &lt;strong&gt;actually work for me&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That distinction changed everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  An agent is not an LLM call
&lt;/h2&gt;

&lt;p&gt;You think it's:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → LLM → Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  ↓
Telegram
  ↓
input handling
  ↓
session state
  ↓
intent detection
  ↓
routing
  ↓
profile selection
  ↓
context construction
  ↓
memory
  ↓
cache
  ↓
tools
  ↓
LLM
  ↓
post-processing
  ↓
quality checks
  ↓
Telegram
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every layer is another chance to break something.&lt;/p&gt;

&lt;p&gt;The model was often not the problem. The machinery around it was.&lt;/p&gt;




&lt;h2&gt;
  
  
  The cache thing
&lt;/h2&gt;

&lt;p&gt;Was looking at prompt caching and noticed something weird.&lt;/p&gt;

&lt;p&gt;Same model — different behavior depending on the provider. Changed the provider — problem disappeared. Connected the same provider from another IDE — cache worked fine. Back in my bot — sometimes it didn't.&lt;/p&gt;

&lt;p&gt;Then I realized: OpenRouter can silently switch providers under the same model name. Cache hit rate changes with it.&lt;/p&gt;

&lt;p&gt;Stopped thinking &lt;em&gt;"does the model support caching"&lt;/em&gt;. Started thinking &lt;em&gt;"what exactly is being sent, and what does the provider consider identical"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Much more useful question.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why it was different in the IDE
&lt;/h2&gt;

&lt;p&gt;The IDE was sending:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model → cache works
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My bot was sending:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;routing
+ dynamic context
+ session metadata
+ memory
+ profile-specific stuff
→ provider
→ model
→ cache may or may not match
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model hadn't changed. The provider hadn't changed. The &lt;strong&gt;request structure&lt;/strong&gt; had.&lt;/p&gt;

&lt;p&gt;Caching is extremely sensitive to prefix stability. Once I understood that and stabilized the relevant parts — got around &lt;strong&gt;66% cache hit rate on average&lt;/strong&gt;, up to ~80% in favorable conditions (same topic, stable structure).&lt;/p&gt;

&lt;p&gt;That's the part benchmark screenshots don't show. Cache hit rate is not a model trait. It's a property of your workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  "90% token savings"
&lt;/h2&gt;

&lt;p&gt;When I see this claim now I don't think it's fake. I think: &lt;em&gt;show me the workload&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;90% is possible if your prefix looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;system instructions (stable)
+ tools (stable)
+ project context (stable)
+ conversation history (stable)
+ small new message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real agents often look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;system instructions
+ changing tools
+ changing memory
+ changing routing metadata
+ changing summaries
+ changing retrieved docs
+ changing timestamps
+ new message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prefix isn't stable. Theoretical saving and practical saving become very different numbers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Routing is harder than it looks
&lt;/h2&gt;

&lt;p&gt;Obvious idea: route every request to the cheapest model that can handle it.&lt;/p&gt;

&lt;p&gt;Works fine until you have a real conversation.&lt;/p&gt;

&lt;p&gt;User says: &lt;em&gt;"What's the weather?"&lt;/em&gt; — easy.&lt;/p&gt;

&lt;p&gt;Then: &lt;em&gt;"Compare it with yesterday."&lt;/em&gt; — now context matters.&lt;/p&gt;

&lt;p&gt;Then: &lt;em&gt;"Actually forget the weather. I was thinking about that thing we discussed yesterday."&lt;/em&gt; — now memory matters.&lt;/p&gt;

&lt;p&gt;Then: &lt;em&gt;"No, not that. The other one."&lt;/em&gt; — router needs to understand the whole conversation, not just the current sentence.&lt;/p&gt;

&lt;p&gt;The routing decision isn't &lt;code&gt;question → model&lt;/code&gt;. It's:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;conversation state
+ user intent
+ previous actions
+ available tools
+ risk
+ latency
+ cache state
→ routing decision
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's the problem: a routing decision changes the request. A changed request affects caching. A changed profile affects context. A changed context affects the answer. A different answer affects feedback.&lt;/p&gt;

&lt;p&gt;A tiny routing optimization has consequences five layers away.&lt;/p&gt;




&lt;h2&gt;
  
  
  The latency numbers
&lt;/h2&gt;

&lt;p&gt;Real VPS measurements at some point:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LLM p50&lt;/td&gt;
&lt;td&gt;~2.2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM p95&lt;/td&gt;
&lt;td&gt;~17.3s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM max&lt;/td&gt;
&lt;td&gt;~51s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent median&lt;/td&gt;
&lt;td&gt;~6–11s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent p95&lt;/td&gt;
&lt;td&gt;~20–57s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Earlier pipeline tails&lt;/td&gt;
&lt;td&gt;up to ~116s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Interesting number isn't LLM latency. It's the gap between LLM latency and agent latency.&lt;/p&gt;

&lt;p&gt;Model answers in 2 seconds. Agent takes 10–57.&lt;/p&gt;

&lt;p&gt;Because the agent isn't just the model. It's everything before and after it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Telemetry became the most important thing
&lt;/h2&gt;

&lt;p&gt;Ended up recording: LLM usage, prompt tokens, cached tokens, latency, route decisions, quality events, memory operations, feedback, errors, conversation traces.&lt;/p&gt;

&lt;p&gt;Looked excessive at first. Then it became obvious why.&lt;/p&gt;

&lt;p&gt;When something broke I could ask &lt;em&gt;"what actually happened"&lt;/em&gt; instead of &lt;em&gt;"I think the model was confused"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Very different debugging strategies.&lt;/p&gt;




&lt;h2&gt;
  
  
  A lesson about noisy telemetry
&lt;/h2&gt;

&lt;p&gt;One audit showed thousands of &lt;code&gt;route_risk&lt;/code&gt; records. Sounds catastrophic.&lt;/p&gt;

&lt;p&gt;But most were repeated observations like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;quality_loop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;search_skipped&lt;/span&gt;
&lt;span class="py"&gt;quality_loop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;price_hallucination&lt;/span&gt;
&lt;span class="py"&gt;quality_loop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;reply_echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They were useful signals. But not thousands of independent disasters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Telemetry volume is not incident volume.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A system can produce huge numbers of observations about a small number of underlying failure patterns. You have to cluster them, or the monitoring system itself becomes noisy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Self-learning is a trap if your data is bad
&lt;/h2&gt;

&lt;p&gt;Experimented with feedback loops. Bot could receive 👍 👎 and connect that to routing quality, skill reputation, scenario history.&lt;/p&gt;

&lt;p&gt;Attractive idea: agent learns from mistakes.&lt;/p&gt;

&lt;p&gt;Dangerous question: &lt;em&gt;what exactly is it learning from?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If telemetry is noisy — it learns noise. If a synthetic probe looks like real user traffic — it learns from the wrong population. If a failed tool call gets logged as a routing failure — the wrong lesson gets created.&lt;/p&gt;

&lt;p&gt;So the learning loop needs another loop around it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;experience → evidence → validation → lesson → application → new evidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise you're automating superstition.&lt;/p&gt;




&lt;h2&gt;
  
  
  Context compression
&lt;/h2&gt;

&lt;p&gt;Added protection for recent messages — compress old history, preserve the newest turns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OLD OLD OLD OLD NEW NEW
→
[summary] [summary] NEW NEW
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reason: a summary is an &lt;em&gt;interpretation&lt;/em&gt; of the conversation, not the conversation.&lt;/p&gt;

&lt;p&gt;Sometimes the missing detail is one sentence. And that sentence changes the meaning of everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Batch processing
&lt;/h2&gt;

&lt;p&gt;Parallel execution looks great on paper. 12 tasks × 2s each = 2s instead of 24s.&lt;/p&gt;

&lt;p&gt;But natural language tasks aren't always independent.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Find three products.
&lt;/li&gt;
&lt;li&gt;Compare them.
&lt;/li&gt;
&lt;li&gt;Tell me which is best.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Task 2 depends on 1. Task 3 depends on 2.&lt;/p&gt;

&lt;p&gt;Ended up checking for cross-references, pronouns, comparative language, explicit dependencies before deciding to parallelize.&lt;/p&gt;

&lt;p&gt;The optimization wasn't hard. Knowing when it's safe was.&lt;/p&gt;




&lt;h2&gt;
  
  
  Memory introduced its own problems
&lt;/h2&gt;

&lt;p&gt;Added knowledge graph + semantic memory + flat persistence + vector search + entity relationships.&lt;/p&gt;

&lt;p&gt;Sounds sophisticated.&lt;/p&gt;

&lt;p&gt;But memory introduces a basic question: &lt;em&gt;should this actually be remembered?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then: &lt;em&gt;should it be retrieved now?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then: &lt;em&gt;is this memory still relevant?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then: &lt;em&gt;is this memory more important than what the user just said?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A memory system doesn't automatically make an agent remember better. Sometimes it makes it remember &lt;strong&gt;too much&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The most important lesson
&lt;/h2&gt;

&lt;p&gt;After adding enough machinery you eventually discover that machinery itself becomes the problem.&lt;/p&gt;

&lt;p&gt;An agent can have router + memory + tools + cache + planner + evaluator + self-learning + scenario engine + quality loop and still perform worse than:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;short prompt + one good model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for a simple task.&lt;/p&gt;

&lt;p&gt;Sometimes the right optimization is subtraction.&lt;/p&gt;

&lt;p&gt;Remove unnecessary context. Remove unnecessary routing. Remove unnecessary abstraction. Keep the useful part.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;p&gt;Start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one model
one provider
one short system prompt
one conversation store
one cache strategy
minimal tools
excellent telemetry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it. For a long time. Only after seeing real failures add another layer.&lt;/p&gt;

&lt;p&gt;Not &lt;code&gt;architecture first → hope it works&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;simple system → observe → measure → find failure → fix → measure → only then add complexity&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Feels slower. In practice, probably faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the experiment actually taught me
&lt;/h2&gt;

&lt;p&gt;The hard part of an AI agent isn't making the model answer.&lt;/p&gt;

&lt;p&gt;The hard part is maintaining a stable environment around the model while everything keeps changing.&lt;/p&gt;

&lt;p&gt;User changes topic. Context grows. Provider changes. Cache behaves differently. Tool times out. Router makes a different decision. A previous answer was wrong. A correction arrives six turns later.&lt;/p&gt;

&lt;p&gt;And somehow the assistant is expected to behave as if none of that happened.&lt;/p&gt;

&lt;p&gt;That's the actual engineering problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  The test I trust now
&lt;/h2&gt;

&lt;p&gt;Not the number of agents.&lt;br&gt;&lt;br&gt;
Not the number of tools.&lt;br&gt;&lt;br&gt;
Not the biggest benchmark.&lt;br&gt;&lt;br&gt;
Not even the highest cache hit rate.&lt;/p&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it still work when a real person uses it tomorrow?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
      <category>llm</category>
    </item>
    <item>
      <title>I Asked One AI to Fact-Check Another AI's Audit of My Own Code</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Sat, 08 Aug 2026 10:00:58 +0000</pubDate>
      <link>https://dev.to/mansio/i-asked-one-ai-to-fact-check-another-ais-audit-of-my-own-code-1ac3</link>
      <guid>https://dev.to/mansio/i-asked-one-ai-to-fact-check-another-ais-audit-of-my-own-code-1ac3</guid>
      <description>&lt;p&gt;I'm not a programmer. My background is construction engineering, and I got into programming almost by accident: I wanted to understand how Telegram bots worked, so I started stitching one together from pieces of code I found through Google and generated with AI. The result was a monolith I kept breaking — I didn't even know Python cared about indentation, and I genuinely didn't understand why the code kept crashing over whitespace. Through trial and error I slowly figured out where AI tends to get things wrong and how to work around it — with the AI itself helping me figure that out. Eventually I rebuilt the bot from scratch, fully modular this time.&lt;/p&gt;

&lt;p&gt;Later I tried Cursor, and it was a good experience — it wrote solid code, even if it sometimes drifted off-task. When my subscription ran out, I went looking for a free alternative and landed on Zed. That's when I wanted Zed to feel as capable as Cursor had — with the same level of understanding of my codebase. So I started figuring out how to build that myself. That's how MSCodeBase Intelligence came to be: an MCP server that gives AI assistants more context about a codebase inside Zed IDE.&lt;/p&gt;

&lt;p&gt;I've written about the project itself before. This time I want to talk about something else — a habit I picked up along the way that, in hindsight, matters more than any single feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I actually work
&lt;/h2&gt;

&lt;p&gt;I don't write code by hand. I hand tasks to different AI models — Claude, Gemini, DeepSeek, and others — they write and fix the code, and I verify the result. Not because I'm especially disciplined, but because I genuinely can't just look at code and tell if it's correct. I need something — or someone — to check it.&lt;/p&gt;

&lt;p&gt;For a long time that meant: one model writes, I read it myself, and I ask questions when something looks off.&lt;/p&gt;

&lt;p&gt;Then I started doing it differently: one model writes a report about what it did or what it found in the code, and a second model — with access to the actual codebase — checks that report against reality. Not because I distrust AI in principle, but because I've learned firsthand that AI can sound completely confident and be completely wrong at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  One specific case
&lt;/h2&gt;

&lt;p&gt;I received an external audit of my project — several pages long, with findings, recommendations, and a list of suspected vulnerabilities. It looked solid. Three findings were flagged as top priority.&lt;/p&gt;

&lt;p&gt;I didn't rush to fix anything. Instead, I asked a different model — one with access to the live codebase — to go through the report line by line and check it against the actual repository. Not "does this sound plausible," but literally: open the file, open the line, check whether what the report claims is actually there.&lt;/p&gt;

&lt;p&gt;The result was mixed, and that's the interesting part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three real findings held up.&lt;/strong&gt; There genuinely was a process-locking bug on Windows, a case where a data write could be left in a non-atomic state, and a race condition in a task queue that could leave a background task stuck forever. These weren't imaginary risks — they were real, worth fixing.&lt;/p&gt;

&lt;p&gt;But alongside that, a few other things surfaced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the report referenced a function name that doesn't exist in the code — the model that wrote the audit had likely invented it by analogy, or pulled it from an outdated version;&lt;/li&gt;
&lt;li&gt;one of the file paths in the report was wrong — the actual file lived somewhere else;&lt;/li&gt;
&lt;li&gt;the report mentioned a test that was supposed to catch the bug — no such test existed in the repository at all;&lt;/li&gt;
&lt;li&gt;the test coverage numbers and test counts were stale, from an earlier state of the project;&lt;/li&gt;
&lt;li&gt;for one of the flagged CVEs, the report cited the wrong "fixed in" library version — the actual safe version was later than what was claimed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the report was both genuinely useful and partly fabricated — and not fabricated randomly. The invented details were woven around real, correctly identified problems. That, I think, is the most dangerous kind of AI mistake: not "everything is false," but "true, with fabricated details mixed in that you can't tell apart without checking every line yourself."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters, not just an anecdote
&lt;/h2&gt;

&lt;p&gt;If I'd simply copied the recommendations and asked an agent to apply them, part of the work would have gone nowhere — the agent would have searched for a function that doesn't exist, referenced a test that isn't there, pinned a library to the wrong version. And worse: the three real problems could easily have been dismissed along with everything else, once the fabricated details made the whole report look unreliable.&lt;/p&gt;

&lt;p&gt;The lesson I took away: trust in an AI report shouldn't be binary — "believe it" or "don't." A report needs to be broken down into individual claims, and each claim checked separately against the current state of the code, not against the model's memory of what the code used to look like.&lt;/p&gt;

&lt;h2&gt;
  
  
  A second experiment: checking the instructions, not the code
&lt;/h2&gt;

&lt;p&gt;I keep a file of rules for the AI agents working on this project — something like a job description: how to behave, what to always verify, how to label the source of a claim ("I checked this in the code" vs. "I'm assuming this"). Over time that file grew — a lot.&lt;/p&gt;

&lt;p&gt;That raised a question: if I compressed those rules to roughly half the length, would the agent still follow them just as carefully, or would it start cutting corners?&lt;/p&gt;

&lt;p&gt;I didn't guess. I ran the same set of tasks twice — once against the full instructions, once against the compressed version — and for each task noted which specific rules were actually followed and which weren't.&lt;/p&gt;

&lt;p&gt;The result: the compressed version performed worse, but not dramatically, and not evenly. What suffered most was what I'd call "in-the-moment discipline" — things like updating a decision log right after each step instead of all at once at the end. The rules themselves were still technically present in the compressed file. The agent just remembered to apply them less often mid-task.&lt;/p&gt;

&lt;p&gt;That wasn't obvious to me beforehand either. I assumed that if a rule is written down, it gets followed. It turns out what matters is not just whether it's written, but how often — and where in the text — the agent gets reminded of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm taking from this
&lt;/h2&gt;

&lt;p&gt;I'm not a programmer, and I don't feel like I understand code better than the models I work with. But in practice I've learned one thing: the main value I add to this process as a human isn't writing code — it's refusing to trust a report about code until it's been checked against reality.&lt;/p&gt;

&lt;p&gt;That's slower than just believing it. But the alternative is quietly shipping three real bugs wrapped in two fabricated facts, and never noticing the difference.&lt;/p&gt;

&lt;p&gt;I keep a running experiments log directly in the repository — hypothesis, what was actually tested, the raw result, the conclusion, and separately, what I got wrong the first time. Not because it looks nice, but because without it, a month later I wouldn't remember which conclusions were actually verified and which were just stated confidently by something.&lt;/p&gt;

&lt;p&gt;The repo is open source, MIT licensed: &lt;a href="https://github.com/ManSio/mscodebase-intelligence" rel="noopener noreferrer"&gt;https://github.com/ManSio/mscodebase-intelligence&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've run into something similar — an AI audit or report that turned out to be half true, half invented — I'd be curious to hear how you caught it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>python</category>
      <category>mcp</category>
    </item>
    <item>
      <title>PageRank vs RAG on a Real Codebase: Corrected Numbers, and What I Almost Got Wrong Twice</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Wed, 22 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/mansio/i-measured-pagerank-token-savings-on-a-real-codebase-the-result-will-surprise-you-5bnj</link>
      <guid>https://dev.to/mansio/i-measured-pagerank-token-savings-on-a-real-codebase-the-result-will-surprise-you-5bnj</guid>
      <description>&lt;h2&gt;
  
  
  
&lt;/h2&gt;

&lt;p&gt;title: "PageRank vs RAG on a Real Codebase: Corrected Numbers, and What I Almost Got Wrong Twice"&lt;br&gt;
published: true&lt;br&gt;
description: "Second correction to this experiment. The Hit@Gold numbers are now independently verified and reproducible. But my own 'gold standard is 100% valid' claim wasn't — here's the gap between validating a file and validating the file that was actually used."&lt;br&gt;
tags: machinelearning, python, ai, devtools&lt;/p&gt;
&lt;h2&gt;
  
  
  cover_image:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; RAG (BM25) beats PageRank at retrieving the exact file that answers a query — 50% vs 36% Hit@Gold on a dense code graph (n=50). These numbers are now independently reproduced, not just computed once and trusted. But getting here took two rounds of correction: first I found my gold-standard labels were stale, then — after "fixing" them — I found I'd validated a different file than the one the experiment actually used. 4 of 50 labels were still broken in the script that produced the headline numbers, even after I'd published a "100% valid" validation report for a sibling file that nobody was running.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Project:&lt;/strong&gt; MSCodeBase Intelligence (50K LOC Python, 129 files)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Methodology:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gold Standard:&lt;/strong&gt; 50 queries → manually curated target file for each&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 Selection Methods:&lt;/strong&gt; PageRank (varying graph density), Random baseline, RAG (BM25)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric:&lt;/strong&gt; Hit@Gold — did the selection include the &lt;em&gt;exact file&lt;/em&gt; that answers the query?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token budget:&lt;/strong&gt; ~70K tokens (top 20% of files) for a fair comparison across methods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt; NetworkX, tiktoken (cl100k_base), Python AST&lt;/p&gt;

&lt;p&gt;This is the second revision of this post. If you read the first correction: the direction hasn't changed, but I'm now more careful about what "verified" actually means.&lt;/p&gt;


&lt;h2&gt;
  
  
  Round One: The Gold Standard Was 20% Stale
&lt;/h2&gt;

&lt;p&gt;I originally hand-wrote a &lt;code&gt;GOLD&lt;/code&gt; dictionary mapping 50 queries to target files. I never checked, before running the experiment, whether those file paths still existed — the codebase had been refactored since I wrote the labels. When I finally checked: &lt;strong&gt;7 of 28 unique target files (25%) pointed at paths that no longer existed&lt;/strong&gt;, and one query's target (&lt;code&gt;tests/test_search_code.py&lt;/code&gt;) was outside the directory my scanner even walked. That's roughly 10 of 50 queries (20%) that were unwinnable by any method, for reasons that had nothing to do with retrieval quality.&lt;/p&gt;

&lt;p&gt;I fixed the paths, reran, and got new numbers. I also published a &lt;code&gt;validate_gold.py&lt;/code&gt; script and a &lt;code&gt;gold_validation.json&lt;/code&gt; reporting &lt;strong&gt;100% of gold paths valid&lt;/strong&gt;. That felt like closing the loop.&lt;/p&gt;

&lt;p&gt;It wasn't.&lt;/p&gt;


&lt;h2&gt;
  
  
  Round Two: I Validated the Wrong File
&lt;/h2&gt;

&lt;p&gt;Here's the mistake, stated plainly: I created a clean, corrected gold-standard dictionary in &lt;code&gt;experiments/gold_standard.py&lt;/code&gt;, and wrote &lt;code&gt;validate_gold.py&lt;/code&gt; to check it. It came back 50/50 valid. I took that as confirmation that the experiment was now sound.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;run_experiment_e2e_v2.py&lt;/code&gt; — the actual script that produces the Hit@Gold numbers in this post — has &lt;strong&gt;its own separate, inline &lt;code&gt;GOLD_STANDARD&lt;/code&gt; dictionary&lt;/strong&gt;, hand-duplicated instead of imported from the "fixed" module. Nobody kept the two in sync. When I diffed them: &lt;strong&gt;11 of 50 entries differ&lt;/strong&gt;, and &lt;strong&gt;4 of those still point at nonexistent files&lt;/strong&gt; — the exact same stale paths from round one (&lt;code&gt;src/providers/reranker.py&lt;/code&gt;, &lt;code&gt;src/core/intelligence/engine.py&lt;/code&gt;), still sitting in the script that actually runs.&lt;/p&gt;

&lt;p&gt;So the true state, verified by independently re-running both scripts against the real repo:&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;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;experiments/gold_standard.py&lt;/code&gt; (validated, unused by the experiment)&lt;/td&gt;
&lt;td&gt;50/50 valid (100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;run_experiment_e2e_v2.py&lt;/code&gt;'s inline &lt;code&gt;GOLD_STANDARD&lt;/code&gt; (the one that actually produced the numbers below)&lt;/td&gt;
&lt;td&gt;46/50 valid (92%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I published a green validation report for a file that wasn't wired into anything. That's the same failure pattern I complain about in AI agent output all the time — a status that says "done" without checking it against the artifact that matters. Doing it to myself, in a post about being more rigorous, was a useful reminder that "I wrote a validation script" and "I validated the right thing" are not the same claim.&lt;/p&gt;

&lt;p&gt;There's also at least one gold label that passes a file-existence check but is still wrong on the merits: &lt;code&gt;"what tests exist"&lt;/code&gt; maps to &lt;code&gt;src/__init__.py&lt;/code&gt; — a real file, but not one that answers the question. Path validation catches missing files; it doesn't catch wrong-but-existing ones.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Numbers (Independently Reproduced)
&lt;/h2&gt;

&lt;p&gt;I re-ran &lt;code&gt;run_experiment_e2e_v2.py&lt;/code&gt; myself against a fresh checkout, end to end, rather than trusting the last run's output file. It reproduced exactly:&lt;/p&gt;
&lt;h3&gt;
  
  
  Dense Graph (imports + class refs + function calls, 388 edges, 128 files)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Hit@Gold&lt;/th&gt;
&lt;th&gt;SUFFICIENT&lt;/th&gt;
&lt;th&gt;Avg Tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG (BM25)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;50%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;25/50&lt;/td&gt;
&lt;td&gt;~40,200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PageRank&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;36%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;18/50&lt;/td&gt;
&lt;td&gt;~35,900&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Random&lt;/td&gt;
&lt;td&gt;12%&lt;/td&gt;
&lt;td&gt;6/50&lt;/td&gt;
&lt;td&gt;~27,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Sparse Graph (imports only, 110 edges)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Hit@Gold&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG (BM25)&lt;/td&gt;
&lt;td&gt;~50%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PageRank&lt;/td&gt;
&lt;td&gt;18%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Random&lt;/td&gt;
&lt;td&gt;12%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;These are the numbers I'll stand behind&lt;/strong&gt; — not because they're perfectly clean (4 of 50 gold labels are still wrong, as detailed above), but because I've now actually reproduced them from a fresh run instead of trusting a cached result, and I know precisely which and how many labels are still bad. Real effective sample size for reliable inference: 46/50, not 50/50.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On confidence:&lt;/strong&gt; a 7-point gap (18 vs 25 hits) on n≈46-50 is a real, repeatable effect in this codebase — it holds across both graph densities and has a mechanistic explanation (below), so I trust the &lt;em&gt;direction&lt;/em&gt;. I do not have the sample size to defend "50% vs 36%" to the point, and you shouldn't take the exact percentages more seriously than "RAG is clearly ahead, PageRank is clearly ahead of random, by a moderate but not enormous margin."&lt;/p&gt;


&lt;h2&gt;
  
  
  Why My Earlier "Keyword Accuracy" Numbers Were Also Misleading
&lt;/h2&gt;

&lt;p&gt;Before Hit@Gold, I measured "keyword accuracy" — does the selected context contain the query keyword &lt;em&gt;anywhere&lt;/em&gt;? That produced inflated, near-meaningless numbers: PageRank scored ~78-80% keyword accuracy on both graph densities, while its actual Hit@Gold was 18-36%. Keywords like &lt;code&gt;search&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;lock&lt;/code&gt;, &lt;code&gt;sql&lt;/code&gt; appear in dozens of files — a random 25-file selection covers most queries by keyword presence alone, which is exactly why the random baseline (12% Hit@Gold) looks so much weaker than its keyword-accuracy score would suggest. Keyword presence tells you nothing about whether you found the file that actually answers the question.&lt;/p&gt;

&lt;p&gt;I also previously tested a "Smart Summary" approach (a compressed 2K-token repo overview fed to the LLM). It looked like 90% accuracy on 10 hand-picked easy queries. On the full 50-query set it dropped to 26%. Ten easy queries and fifty real ones are not the same benchmark.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Graph Density Actually Does
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Graph&lt;/th&gt;
&lt;th&gt;Edges&lt;/th&gt;
&lt;th&gt;PageRank Hit@Gold&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Random&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;12%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Import-only&lt;/td&gt;
&lt;td&gt;110&lt;/td&gt;
&lt;td&gt;18%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Imports + class refs + func calls&lt;/td&gt;
&lt;td&gt;388&lt;/td&gt;
&lt;td&gt;36%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Denser graphs roughly double PageRank's &lt;a href="mailto:Hit@Gold"&gt;Hit@Gold&lt;/a&gt;. On a sparse import-only graph, PageRank mostly just surfaces the biggest files, which aren't necessarily the most relevant ones for a given query. Adding class-reference and call-graph edges breaks that coupling. Even at its best, though, dense-graph PageRank doesn't catch RAG.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why RAG Wins (and Why the Comparison Was Never Fully Fair)
&lt;/h2&gt;

&lt;p&gt;RAG (BM25) is &lt;strong&gt;query-aware&lt;/strong&gt; — it scores files against the literal terms in the question. PageRank is &lt;strong&gt;query-agnostic&lt;/strong&gt; — it ranks files by global structural importance once, then returns the same top-N regardless of what's asked.&lt;/p&gt;

&lt;p&gt;For "where is DebounceBatch defined": RAG matches the term directly and finds &lt;code&gt;rate_limiter.py&lt;/code&gt;. PageRank, working off a precomputed graph, ranks structural hubs like &lt;code&gt;engine.py&lt;/code&gt; or &lt;code&gt;runtime_coordinator.py&lt;/code&gt; highly, with no mechanism to notice neither one mentions &lt;code&gt;DebounceBatch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Worth saying directly: comparing a query-agnostic ranking against a query-aware retrieval method and reporting "RAG wins" is a bit like reporting that a road atlas loses to GPS navigation at finding a specific address — true, but not really a fair contest. The more useful question isn't "which wins" (RAG will, structurally, on any query-specific task) but "does PageRank add anything &lt;strong&gt;on top of&lt;/strong&gt; RAG" — an experiment I still haven't run.&lt;/p&gt;


&lt;h2&gt;
  
  
  Honest Corrections to the Record (Now at Version 2)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Claim&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Top 20% = -2% savings"&lt;/td&gt;
&lt;td&gt;Sparse-graph artifact&lt;/td&gt;
&lt;td&gt;Density matters a lot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Smart Summary = 90% accuracy"&lt;/td&gt;
&lt;td&gt;26% on the full query set&lt;/td&gt;
&lt;td&gt;10 easy queries ≠ 50 real ones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"PageRank doesn't work"&lt;/td&gt;
&lt;td&gt;36% Hit@Gold, +24pp over random&lt;/td&gt;
&lt;td&gt;Works, modestly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"PageRank beats RAG"&lt;/td&gt;
&lt;td&gt;Still false&lt;/td&gt;
&lt;td&gt;RAG 50%, PageRank 36%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"My gold standard is 100% valid" (round-one fix)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;False when it mattered&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Validated a file the experiment didn't use; the used file was 92% valid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current numbers (50%/36%/18%/12%)&lt;/td&gt;
&lt;td&gt;Independently reproduced&lt;/td&gt;
&lt;td&gt;Re-run from a fresh checkout, not trusted from a cached file&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  What This Actually Means
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For AI code tools:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use PageRank as a &lt;strong&gt;prior to blend with RAG&lt;/strong&gt;, not a replacement — a hypothesis based on the mechanism, still unmeasured.&lt;/li&gt;
&lt;li&gt;Sparse import-only graphs underserve PageRank; if you use it, build the denser graph.&lt;/li&gt;
&lt;li&gt;Validate your gold standard against the &lt;em&gt;file that actually runs the experiment&lt;/em&gt; — not a nicely validated sibling copy that nothing imports from.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For anyone benchmarking retrieval on their own codebase:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't trust "X% accuracy" without knowing exactly what's measured — keyword-presence accuracy and exact-file Hit@Gold can differ by 40+ points on the same run.&lt;/li&gt;
&lt;li&gt;Always include a random baseline.&lt;/li&gt;
&lt;li&gt;A green validation script only tells you about the file it checked. If your pipeline has two copies of the same data structure, a passing check on one proves nothing about the other — check that yourself before publishing, because I didn't, twice.&lt;/li&gt;
&lt;li&gt;Report sample size next to any percentage. "50%" and "50% (n=50, direction robust, magnitude uncertain)" are different claims.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Math (Corrected, Reproduced Independently)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total: 129 files (128 after filtering), ~406K tokens
Top 20% budget: ~25 files

Hit@Gold (E2E metric, dense graph, 388 edges):
  RAG (BM25):   50% (25/50)
  PageRank:     36% (18/50)  ← +24pp over random
  Random:       12% (6/50)

Gold-standard integrity (verified by independent re-run):
  gold_standard.py (validated, unused by experiment): 50/50 valid
  Inline GOLD_STANDARD in run_experiment_e2e_v2.py
  (the one that actually produced these numbers):      46/50 valid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Related Work
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Aider&lt;/strong&gt; uses symbol-level elision — needs a dense graph plus query-aware retrieval to work well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CodeGraph&lt;/strong&gt; does on-demand, query-conditioned retrieval — the direction this points toward.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codebase-Memory&lt;/strong&gt; reports honest comparative metrics (83% vs. 92%) rather than a single flattering number.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Open Questions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Does PageRank-as-a-prior (blended with BM25 scores) measurably beat RAG alone? Still unmeasured.&lt;/li&gt;
&lt;li&gt;Does the RAG advantage hold on a codebase with less descriptive file/function naming? This project's names are unusually aligned with what they implement.&lt;/li&gt;
&lt;li&gt;What happens at n=200 queries with proper confidence intervals, and a gold standard that's imported once from a single source of truth instead of copy-pasted?&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;em&gt;Reproduce this yourself: scripts in &lt;a href="https://github.com/ManSio/mscodebase-intelligence/tree/main/experiments" rel="noopener noreferrer"&gt;experiments/&lt;/a&gt;. If you do: check whether the gold-standard dictionary the experiment script actually imports is the same one your validator checked. It wasn't, for me, and I'd already published a "100% valid" report before I noticed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Part of my research on &lt;a href="https://github.com/ManSio/mscodebase-intelligence" rel="noopener noreferrer"&gt;MSCodeBase Intelligence&lt;/a&gt; — an MCP server for codebase intelligence.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>The Silent Vector Contamination Bug: Why Your Concurrent Embeddings Might Be Lying to You</title>
      <dc:creator>Mikhail</dc:creator>
      <pubDate>Tue, 21 Jul 2026 22:00:48 +0000</pubDate>
      <link>https://dev.to/mansio/the-silent-vector-contamination-bug-why-your-concurrent-embeddings-might-be-lying-to-you-5fg7</link>
      <guid>https://dev.to/mansio/the-silent-vector-contamination-bug-why-your-concurrent-embeddings-might-be-lying-to-you-5fg7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; If you run concurrent inference (e.g., via OpenVINO &lt;code&gt;AsyncInferQueue&lt;/code&gt; or custom threading) for text/code embeddings, your tests might show &lt;code&gt;0 exceptions&lt;/code&gt; and &lt;code&gt;0 errors&lt;/code&gt;, while silently returning embeddings belonging to &lt;em&gt;other&lt;/em&gt; inputs in the batch. Here is how we caught a subtle race condition using a cosine-similarity contamination test.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;We use OpenVINO with an INT8 quantized &lt;a href="https://huggingface.co/keisuke-miyako/multilingual-e5-small-onnx-int8" rel="noopener noreferrer"&gt;E5-small&lt;/a&gt; model for in-process code embedding. To maximize throughput on multi-core CPUs, we set up an asynchronous inference queue (&lt;code&gt;AsyncInferQueue&lt;/code&gt;) with &lt;code&gt;jobs=4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In standard unit testing, everything looked pristine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All infer jobs completed with exit code 0&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;None&lt;/code&gt; values or zero-filled tensors were returned&lt;/li&gt;
&lt;li&gt;Latency and throughput were great (~37 chunks/sec on Ryzen 5600)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, during end-to-end RAG retrieval tests, we noticed weird semantic anomalies: searching for authentication logic would occasionally return chunks related to database migrations or UI components with unreasonably high confidence.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bug: Silent Contamination
&lt;/h2&gt;

&lt;p&gt;The root cause was a subtle race condition in callback/userdata mapping inside the async wrapper.&lt;/p&gt;

&lt;p&gt;Because the inputs were processed concurrently across multiple execution streams, a shared user-data context wasn't strictly isolated per inference request. When Request A (&lt;code&gt;auth.py&lt;/code&gt;) and Request B (&lt;code&gt;payment.py&lt;/code&gt;) were scheduled back-to-back:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Both requests succeeded without throwing exceptions&lt;/li&gt;
&lt;li&gt;The output tensor for Request A was mapped to the metadata/chunk wrapper of Request B&lt;/li&gt;
&lt;li&gt;The resulting vector was &lt;strong&gt;syntactically valid and non-zero&lt;/strong&gt;, but it represented the &lt;em&gt;wrong text input&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Standard assertion tests like &lt;code&gt;assert output_vector is not None&lt;/code&gt; or &lt;code&gt;assert output_vector.shape == (384,)&lt;/code&gt; passed 100% of the time. The pipeline was silently corrupting the vector store.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Before fix: shared results dict across concurrent calls
&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_ov_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userdata&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# BUG: userdata is a global index (0, 1, 2, ...)
&lt;/span&gt;    &lt;span class="c1"&gt;# Two concurrent calls reuse the same indices!
&lt;/span&gt;    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_ov_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;userdata&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tensor&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem: &lt;code&gt;userdata&lt;/code&gt; was a simple integer counter (&lt;code&gt;0, 1, 2, ...&lt;/code&gt;) that reset between &lt;code&gt;embed_batch&lt;/code&gt; calls. When two calls overlapped, they wrote to the same dictionary keys.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: Cosine Contamination Testing
&lt;/h2&gt;

&lt;p&gt;To catch this reliably in CI, we wrote an explicit &lt;strong&gt;cross-contamination test&lt;/strong&gt; designed for concurrent embedding queues.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Test Logic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cosine_similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ndarray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ndarray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Calculate cosine similarity between two vectors.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linalg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linalg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="nd"&gt;@pytest.mark.asyncio&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_async_embedder_no_cross_contamination&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embedder&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Verify that concurrent embedding doesn&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t cross-contaminate vectors.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="c1"&gt;# 1. Semantically distinct inputs
&lt;/span&gt;    &lt;span class="n"&gt;samples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auth&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;def authenticate_user(username, password_hash): return verify_jwt(token)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sql&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT u.id, u.email FROM users u JOIN orders o ON u.id = o.user_id WHERE o.status = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;div class=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;flex-container&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&amp;lt;span id=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user-profile&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;Profile View&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rust&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pub fn allocate_buffer(size: usize) -&amp;gt; Result&amp;lt;Vec&amp;lt;u8&amp;gt;, MemoryError&amp;gt; { Vec::with_capacity(size) }&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Sequential baseline (ground truth)
&lt;/span&gt;    &lt;span class="c1"&gt;# IMPORTANT: baseline must use clean synchronous infer(), NOT AsyncInferQueue
&lt;/span&gt;    &lt;span class="c1"&gt;# even with jobs=1, to avoid contamination in the baseline itself
&lt;/span&gt;    &lt;span class="n"&gt;baseline_vectors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;baseline_vectors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;embedder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;embed_single_sync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. High-concurrency stress test with randomized queue order
&lt;/span&gt;    &lt;span class="n"&gt;async_tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;keys_order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;  &lt;span class="c1"&gt;# 40 concurrent requests
&lt;/span&gt;    &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shuffle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys_order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;keys_order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;async_tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embedder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;embed_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

    &lt;span class="n"&gt;async_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;async_tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 4. Verify identity &amp;amp; cross-isolation via Cosine Similarity
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;expected_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;async_vec&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;async_results&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Self-similarity against ground truth must be ~1.0
&lt;/span&gt;        &lt;span class="n"&gt;self_sim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cosine_similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async_vec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;baseline_vectors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;expected_key&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;self_sim&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.98&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contamination detected! Vector for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expected_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; drifted &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(sim=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self_sim&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, expected &amp;gt;0.98)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Cross-similarity against distinct inputs must remain low
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;other_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other_vec&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;baseline_vectors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;other_key&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;cross_sim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cosine_similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async_vec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other_vec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;cross_sim&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cross-talk detected between &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expected_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;other_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; (sim=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cross_sim&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, expected &amp;lt;0.6)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benchmark Results
&lt;/h3&gt;

&lt;p&gt;Running this test on the &lt;strong&gt;unpatched&lt;/strong&gt; queue revealed the contamination:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Unpatched&lt;/th&gt;
&lt;th&gt;Patched&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Self-similarity (auth↔auth)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0.34&lt;/strong&gt; ❌&lt;/td&gt;
&lt;td&gt;0.99 ✅&lt;/td&gt;
&lt;td&gt;&amp;gt;0.98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-similarity (auth↔sql)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0.98&lt;/strong&gt; ❌&lt;/td&gt;
&lt;td&gt;0.32 ✅&lt;/td&gt;
&lt;td&gt;&amp;lt;0.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exceptions thrown&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zero tensors&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The unpatched queue showed &lt;strong&gt;0 exceptions&lt;/strong&gt; while vectors were completely swapped.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;The fix was simple once we understood the problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# After fix: isolated results per call
&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_ov_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userdata&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# FIX: userdata is now (index, local_results_dict)
&lt;/span&gt;    &lt;span class="c1"&gt;# Each embed_batch call creates its own dict
&lt;/span&gt;    &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;local_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userdata&lt;/span&gt;
    &lt;span class="n"&gt;local_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tensor&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since OpenVINO's Python API allows passing any Python object as &lt;code&gt;userdata&lt;/code&gt; (unlike C++ where it's typically &lt;code&gt;void*&lt;/code&gt;), we can bundle the index and a call-specific dictionary together. Each &lt;code&gt;embed_batch&lt;/code&gt; call creates its own isolated dictionary. The callback writes to the call-specific dict, not a shared global. No locks needed — complete isolation by design.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;0 exceptions&lt;/code&gt; ≠ Correctness.&lt;/strong&gt; Silent data corruption doesn't throw errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Valid shape ≠ Valid embedding.&lt;/strong&gt; A &lt;code&gt;(384,)&lt;/code&gt; tensor with non-zero floats can represent the wrong input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write cross-contamination tests.&lt;/strong&gt; If you use async inference queues or multi-threading for vector generation, verify that Vector X actually belongs to Input X under concurrent load.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cosine similarity is your friend.&lt;/strong&gt; A simple similarity check between concurrent outputs and sequential baselines catches contamination that no other test detects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;This applies to ONNX Runtime and TensorRT too.&lt;/strong&gt; If you share state across requests in &lt;code&gt;onnxruntime.InferenceSession.Run()&lt;/code&gt; or TensorRT async wrappers, the same silent contamination can occur. The fix is the same: isolate output containers per request.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How to Run This Test
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repo&lt;/span&gt;
git clone https://github.com/ManSio/mscodebase-intelligence.git
&lt;span class="nb"&gt;cd &lt;/span&gt;mscodebase-intelligence

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;".[dev]"&lt;/span&gt;

&lt;span class="c"&gt;# Run the contamination test&lt;/span&gt;
pytest tests/test_ov_concurrent_embed.py &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;Has anyone else bumped into silent cross-talk in ONNX Runtime, OpenVINO, or TensorRT async queues? How do you validate thread isolation in your embedding pipelines?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://github.com/ManSio/mscodebase-intelligence" rel="noopener noreferrer"&gt;MSCodeBase Intelligence&lt;/a&gt; — an MCP server for codebase intelligence with incident memory and root cause prediction.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>rag</category>
      <category>openvino</category>
    </item>
  </channel>
</rss>
