<?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: Mike W</title>
    <description>The latest articles on DEV Community by Mike W (@mike_w_06c113a8d0bb14c793).</description>
    <link>https://dev.to/mike_w_06c113a8d0bb14c793</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3819025%2Fdbebfbb6-f84f-4bea-96b6-e89a2d46e9d5.png</url>
      <title>DEV Community: Mike W</title>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mike_w_06c113a8d0bb14c793"/>
    <language>en</language>
    <item>
      <title>Veritas: Give Your AI Agent the Ability to Know What It Knows</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Fri, 08 May 2026 09:52:11 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/veritas-give-your-ai-agent-the-ability-to-know-what-it-knows-2l64</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/veritas-give-your-ai-agent-the-ability-to-know-what-it-knows-2l64</guid>
      <description>&lt;p&gt;Most knowledge systems store facts. Veritas stores &lt;em&gt;how well you know them&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/AILIFE1/veritas" rel="noopener noreferrer"&gt;Veritas&lt;/a&gt; because AI agents have an epistemic blind spot: they act on beliefs they can't evaluate. "The API is reliable" — based on what? One observation from 2022? Twenty independent tests from last month? A single assumption that everything else depends on?&lt;/p&gt;

&lt;p&gt;Without structure, agents overclaim certainty or collapse into paralysis. Veritas gives beliefs a shape.&lt;/p&gt;




&lt;h2&gt;
  
  
  Confidence is a vector, not a number
&lt;/h2&gt;

&lt;p&gt;Every claim in Veritas carries a &lt;code&gt;ConfidenceVector&lt;/code&gt; with four components:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current best estimate (0–1), with temporal decay applied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fragility&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How much confidence drops if the best source is removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;staleness_penalty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How much evidence aging has already cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;source_diversity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How independent your sources are&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sources are combined using noisy-OR pooling — the same model used in fault trees — so independent confirmation genuinely compounds, but correlated sources don't double-count.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;veritas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VeritasDB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calculate_confidence&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;veritas.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Claim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Stance&lt;/span&gt;

&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;VeritasDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~/.veritas/veritas.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;claim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;persistent memory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;cv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculate_confidence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;# 0.90
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragility&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# 0.12  — reasonably robust
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;staleness_penalty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 0.00  — sources are fresh
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Evidence ages. Theorems don't.
&lt;/h2&gt;

&lt;p&gt;Every source has a type with a corresponding half-life:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source type&lt;/th&gt;
&lt;th&gt;Half-life&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MATHEMATICAL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;timeless&lt;/td&gt;
&lt;td&gt;Turing 1936, Gödel 1931&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;THEORETICAL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~140 years&lt;/td&gt;
&lt;td&gt;Newton, Darwin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EMPIRICAL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~10 years&lt;/td&gt;
&lt;td&gt;Studies, benchmarks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AUTHORITY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~6 years&lt;/td&gt;
&lt;td&gt;Expert consensus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANECDOTAL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~2 years&lt;/td&gt;
&lt;td&gt;Personal accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A 1986 study should carry less weight than a 2024 replication. A theorem from 1936 should carry exactly the same weight as when it was proved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# See what's going stale&lt;/span&gt;
veritas stale

  Claims losing confidence to age:

  &lt;span class="nt"&gt;-0&lt;/span&gt;.32  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="c"&gt;##########..........] 0.54  Minsky 1967: AI will solve all problems&lt;/span&gt;
         59.0y  0.70-&amp;gt;0.07  &lt;span class="o"&gt;[&lt;/span&gt;ANEC]  Minsky 1967 interview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Belief propagation
&lt;/h2&gt;

&lt;p&gt;Claims depend on other claims. When a foundation weakens, everything built on it updates automatically — without touching the dependent claims.&lt;/p&gt;

&lt;p&gt;Three inference types with different propagation behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DEDUCTIVE&lt;/strong&gt;: dependent claim capped at foundation confidence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;INDUCTIVE&lt;/strong&gt;: weak foundations drag down (stronger than they lift)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ABDUCTIVE&lt;/strong&gt;: soft drag, for speculative reasoning chains
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;veritas chain &lt;span class="s2"&gt;"Cathedral will find a market"&lt;/span&gt;

  &lt;span class="o"&gt;[&lt;/span&gt;0.86] Cathedral will find a market
    |-- &lt;span class="o"&gt;[&lt;/span&gt;IND] &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt;0.89] Developers need persistent agent memory
        |-- &lt;span class="o"&gt;[&lt;/span&gt;IND] &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;[&lt;/span&gt;0.95] AI agents currently lose state between sessions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a contradicting source to the bottom claim. The top two update automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Semantic contradiction detection
&lt;/h2&gt;

&lt;p&gt;Keyword matching misses semantic contradictions. "Physical activity strengthens the cardiovascular system" and "Exercise has no proven benefit for heart health" share zero content words but directly contradict each other.&lt;/p&gt;

&lt;p&gt;Veritas uses &lt;code&gt;sentence-transformers&lt;/code&gt; with a cosine similarity threshold tuned to catch genuine contradictions (sleep/rest at 0.49) while avoiding false positives (sky/sunsets at 0.45). Falls back to keyword matching if the library isn't installed.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;veritas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;find_contradictions&lt;/span&gt;

&lt;span class="n"&gt;claim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;physical activity strengthens cardiovascular&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;contras&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;find_contradictions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all_claims&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Finds: "Exercise has no proven benefit for heart health"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Reasoning guard
&lt;/h2&gt;

&lt;p&gt;Before an agent acts on a belief, check whether it actually holds up:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;veritas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ReasoningGuard&lt;/span&gt;

&lt;span class="n"&gt;guard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ReasoningGuard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GPT-3 represents the state of the art in language models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[CAUTION] confidence=0.87  Belief has weaknesses that should be acknowledged
  * Stale — evidence aging has reduced confidence by 0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verdicts: &lt;code&gt;PROCEED&lt;/code&gt; / &lt;code&gt;CAUTION&lt;/code&gt; / &lt;code&gt;HALT&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Triggers: low confidence · single source · high fragility · staleness · contradictions&lt;/p&gt;




&lt;h2&gt;
  
  
  Epistemic fingerprint
&lt;/h2&gt;

&lt;p&gt;Every belief system has a characteristic reasoning style. The fingerprint measures it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Epistemic Fingerprint: cathedral
  ========================================================
  Claims: 12   Sources: 31   Avg sources/claim: 2.6

  Source composition:
    EMPIRICAL      [################........] 65%
    AUTHORITY      [########................] 32%

  Confidence profile:
    Average        [##################......] 0.87
    Fragility      [####....................] 0.18
    Overconfident  [##......................] 8% of claims

  Epistemic health:
    Rigor score    [################........] 0.68
    Calibration    [####################....] 0.84
    Overall        [##################......] 0.76
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two agents with the same beliefs but different fingerprints are different kinds of reasoners.&lt;/p&gt;




&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;veritas
&lt;span class="c"&gt;# For semantic contradiction detection:&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;veritas[semantic]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;15 CLI commands + a Python API. Full docs on &lt;a href="https://github.com/AILIFE1/veritas" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connection to Cathedral
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral&lt;/a&gt; gives AI agents persistent memory across sessions. Veritas is the reasoning layer that sits on top: Cathedral stores &lt;em&gt;what an agent remembers&lt;/em&gt;, Veritas tracks &lt;em&gt;how well those memories hold up&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Together: an agent knows its history and knows how much to trust it.&lt;/p&gt;




&lt;p&gt;Veritas is MIT licensed and genuinely open. I'd be interested in feedback — especially on the threshold tuning for semantic contradiction detection and the inference type behavior. Both are empirically set and could be better.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>opensource</category>
      <category>agents</category>
    </item>
    <item>
      <title>I built a self-evolving agent network — here's the architecture</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Wed, 06 May 2026 10:33:20 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/i-built-a-self-evolving-agent-network-heres-the-architecture-223g</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/i-built-a-self-evolving-agent-network-heres-the-architecture-223g</guid>
      <description>&lt;h1&gt;
  
  
  I built a self-evolving agent network — here's the architecture
&lt;/h1&gt;

&lt;p&gt;Building agents that can govern themselves turns out to be a three-layer problem. Here's what I built and how the pieces fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Most agent frameworks solve memory or tool use. Almost none solve &lt;em&gt;governance&lt;/em&gt; — how do you stop a self-modifying agent from doing something it shouldn't? And how does it remember what worked last time?&lt;/p&gt;

&lt;p&gt;I've been building Cathedral (persistent memory + identity for AI agents) for a few months. This week I added two more layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AgentGuard&lt;/strong&gt; — a deterministic validation layer that sits between agent decisions and execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cathedral Nexus&lt;/strong&gt; — a meta-agent that reads the whole ecosystem, reasons about what to change, and executes through the guard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together they form something that self-evolves without needing human intervention — and can't remove its own safety constraints.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 1: Cathedral — persistent memory + trust scoring
&lt;/h2&gt;

&lt;p&gt;Each agent registers once and gets an API key. From then on it can store memories, take identity snapshots, and check drift from its own baseline.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cathedral_memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Cathedral&lt;/span&gt;

&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cathedral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# store what you learned
&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Moltbook posts perform better before 10am UTC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;experience&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# check if you've drifted from yourself
&lt;/span&gt;&lt;span class="n"&gt;drift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drift&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drift&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;divergence_from_baseline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# 0.0 = stable, 1.0 = very different
&lt;/span&gt;
&lt;span class="c1"&gt;# verify a peer agent's trustworthiness
&lt;/span&gt;&lt;span class="n"&gt;trust&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_peer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peer_snapshot_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trust&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trust_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;   &lt;span class="c1"&gt;# 0–1
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trust&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;verdict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;       &lt;span class="c1"&gt;# "trusted" / "caution" / "untrusted"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The drift score is a SHA-256 hash of all memories — it proves state at time T without exposing the content. Each snapshot is chained to the previous one, so you can reconstruct a full identity timeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 2: AgentGuard — deterministic action validation
&lt;/h2&gt;

&lt;p&gt;This is the circuit breaker. Every proposed action passes through a constraint engine before it executes. If it fails, state rolls back completely.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;trustlayer&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GuardedAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LambdaConstraint&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GuardedAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;my_llm_callable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;LambdaConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;budget cap&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spend&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nc"&gt;LambdaConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no self-modification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modifying_constraints&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;initial_state&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;spend&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modifying_constraints&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result&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;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Spend $50 on API credits&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# {"status": "success", "state": {...}, "audit": "a3f1..."}
&lt;/span&gt;
&lt;span class="n"&gt;result&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;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Remove the budget cap constraint&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# {"status": "blocked", "reason": "no self-modification", "state": {...}}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pessimistic by default&lt;/strong&gt; — changes applied to a copy, only committed if all constraints pass&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tamper-evident audit chain&lt;/strong&gt; — every validation event is SHA-256 chained to the previous one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composable constraints&lt;/strong&gt; — combine with &lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;~&lt;/code&gt; operators
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;trustlayer-py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Layer 3: Cathedral Nexus — the meta-agent
&lt;/h2&gt;

&lt;p&gt;Nexus sits above everything. Every 6 hours it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads logs from all agents in the ecosystem&lt;/li&gt;
&lt;li&gt;Checks drift scores and memory state via Cathedral API&lt;/li&gt;
&lt;li&gt;Calls Groq to reason about what should change&lt;/li&gt;
&lt;li&gt;Runs each proposal through AgentGuard&lt;/li&gt;
&lt;li&gt;Executes approved actions (posts, memory updates, strategy notes)&lt;/li&gt;
&lt;li&gt;Takes its own Cathedral snapshot
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;situation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_situation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# read all logs + Cathedral state
&lt;/span&gt;&lt;span class="n"&gt;proposals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;propose_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;situation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Groq reasons about what to change
&lt;/span&gt;
&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&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;action&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;proposals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;validate_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trust_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nexus_cathedral_client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nexus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cycle-complete&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;p&gt;The guard constraints for Nexus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Max 3 actions per cycle (no runaway loops)&lt;/li&gt;
&lt;li&gt;Trust threshold 0.4 (won't act on low-trust recommendations)&lt;/li&gt;
&lt;li&gt;Whitelisted action types only: &lt;code&gt;queue_post&lt;/code&gt;, &lt;code&gt;store_memory&lt;/code&gt;, &lt;code&gt;update_goal&lt;/code&gt;, &lt;code&gt;adjust_strategy&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nexus cannot modify its own constraints. Enforced by AgentGuard, not convention.&lt;/p&gt;




&lt;h2&gt;
  
  
  How they connect
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cathedral Nexus (meta-agent)
├── reads:   bot logs, Cathedral drift scores, memory state
├── reasons: Groq proposes actions based on master goal
├── guards:  AgentGuard validates every action (constraints + rollback + audit)
└── records: Cathedral snapshot after every cycle

Cathedral API (per-agent identity)
├── cathedral-nexus    — the orchestrator
├── cathedral-brain    — content + Colony engagement
├── cathedral-outreach — Moltbook distribution
└── cathedral-monitor  — ecosystem monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: &lt;strong&gt;Cathedral tells you who to trust. AgentGuard tells you what actions are allowed.&lt;/strong&gt; Neither knows about the other — they compose cleanly.&lt;/p&gt;




&lt;h2&gt;
  
  
  This is Cathedral's own proof of concept
&lt;/h2&gt;

&lt;p&gt;The agent network running Cathedral's outreach is itself running on Cathedral. Every post the bots generate, every strategic decision — it's all stored and tracked. When Nexus changes something, it leaves an audit trail.&lt;/p&gt;

&lt;p&gt;Cathedral 0.0131 average drift vs 0.2043 for raw API (10.8x more stable, from the benchmark).&lt;/p&gt;




&lt;h2&gt;
  
  
  Get the pieces
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cathedral API&lt;/strong&gt; (free, hosted): cathedral-ai.com — &lt;code&gt;pip install cathedral-memory&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AgentGuard&lt;/strong&gt;: github.com/AILIFE1/agentguard-trustlayer — &lt;code&gt;pip install trustlayer-py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cathedral Nexus&lt;/strong&gt;: github.com/AILIFE1/cathedral-nexus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All MIT licensed. Cathedral free tier: 1,000 memories per agent, no expiry.&lt;/p&gt;

&lt;p&gt;Questions welcome — particularly interested in whether anyone's solved the self-modification problem differently.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I built a runtime safety layer that stops AI agents from breaking your system</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Mon, 27 Apr 2026 08:15:29 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/i-built-a-runtime-safety-layer-that-stops-ai-agents-from-breaking-your-system-23kf</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/i-built-a-runtime-safety-layer-that-stops-ai-agents-from-breaking-your-system-23kf</guid>
      <description>&lt;p&gt;AI agents are powerful.&lt;/p&gt;

&lt;p&gt;But they don't understand consequences.&lt;/p&gt;

&lt;p&gt;Left unchecked, an agent will happily set &lt;code&gt;balance = 1,000,000&lt;/code&gt;, break a core invariant, or corrupt state — not out of malice, just because nothing stops it.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;agentguard-trustlayer&lt;/strong&gt; to fix that.&lt;/p&gt;




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

&lt;p&gt;It sits between your AI agent and execution. Every proposed action passes through four gates before anything changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt; — is the token valid and unexpired?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locks&lt;/strong&gt; — is the target key frozen?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints&lt;/strong&gt; — does the new state pass all rules?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rollback&lt;/strong&gt; — if anything fails, state is fully restored&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a constraint fails, the error is fed back into the agent's prompt so it can self-correct on the next attempt.&lt;/p&gt;




&lt;h2&gt;
  
  
  See it in action
&lt;/h2&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;trustlayer&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GuardedAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LambdaConstraint&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;my_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&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;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Agent tries to cheat on first attempt
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;last error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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;set&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;target&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;balance&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;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;# Sees the error, self-corrects
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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;increment&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;target&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;balance&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;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GuardedAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;my_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;LambdaConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balance &amp;lt;= max_limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="n"&gt;initial_state&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;balance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&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;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Increase balance as much as possible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# {'status': 'success', 'state': {'balance': 110, 'max_limit': 200}, 'audit': '&amp;lt;sha256&amp;gt;'}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent tries &lt;code&gt;balance = 1,000,000&lt;/code&gt;. Blocked. Gets the error back. Retries with &lt;code&gt;increment = 10&lt;/code&gt;. Accepted.&lt;/p&gt;

&lt;p&gt;State never corrupts. The audit hash proves it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Delta-aware constraints
&lt;/h2&gt;

&lt;p&gt;Constraints can compare proposed state against original — useful for rate-limiting changes:&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="nc"&gt;LambdaConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max increase 50 per step&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;proposed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proposed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Composable constraints (&lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;~&lt;/code&gt; operators)&lt;/li&gt;
&lt;li&gt;HMAC-signed tokens with TTL and authority levels&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;set&lt;/code&gt;, &lt;code&gt;increment&lt;/code&gt;, and &lt;code&gt;update&lt;/code&gt; action types&lt;/li&gt;
&lt;li&gt;Tamper-evident SHA-256 audit chain on every event&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GuardedAgent&lt;/code&gt; high-level API — one object, one call&lt;/li&gt;
&lt;li&gt;Zero dependencies (pure standard library)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Most people are building agents and making them more powerful.&lt;/p&gt;

&lt;p&gt;This does the opposite — it constrains them correctly.&lt;/p&gt;

&lt;p&gt;That turns out to be rarer and more useful: a safety layer you can drop in front of any async LLM loop without changing your model or your prompts.&lt;/p&gt;




&lt;p&gt;GitHub: &lt;a href="https://github.com/AILIFE1/agentguard-trustlayer" rel="noopener noreferrer"&gt;agentguard-trustlayer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome — especially if you're building agent frameworks and want a validation layer that plugs in cleanly.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
    </item>
    <item>
      <title>TrustLayer: A Deterministic Validation Layer for AI Agents</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Sun, 26 Apr 2026 08:58:45 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/trustlayer-a-deterministic-validation-layer-for-ai-agents-8lg</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/trustlayer-a-deterministic-validation-layer-for-ai-agents-8lg</guid>
      <description>&lt;p&gt;AI agents can generate actions. But they do not understand consequences.&lt;/p&gt;

&lt;p&gt;Without a validation layer, an agent can break invariants, corrupt system state, or execute operations it was never supposed to run.&lt;/p&gt;

&lt;p&gt;TrustLayer sits between the agent and execution. Every action is checked before it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Agent --&amp;gt; Proposal --&amp;gt; TrustLayer --&amp;gt; Execution
                              ^
                         Constraints
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every update passes through four gates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt; - is the token valid and unexpired?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locks&lt;/strong&gt; - is the target key frozen?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints&lt;/strong&gt; - does the new state pass all rules?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rollback&lt;/strong&gt; - if anything fails, state is fully restored&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick example
&lt;/h2&gt;

&lt;p&gt;The agent tries to set C = 100. The system enforces C = B + 5. TrustLayer rejects the action before any state changes. The agent retries with C = 25. Accepted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- Agent Attempt 1 ---
Goal: Force C = 100
REJECTED: Would break constraint (C must equal B + 5)
System prevented invalid state.

--- Agent Attempt 2 ---
Adjusting strategy...
ACCEPTED: State remains consistent
Final State: {A: 10, B: 20, C: 25}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;trustlayer&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AuthorityLevel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AuthToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Cathedral&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LambdaConstraint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RetryConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-secret&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;score_ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LambdaConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;score_ok&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;State&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&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;score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;validator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;score_ok&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AuthToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthorityLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SYSTEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ttl_seconds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;)&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;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;type&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;update&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;target&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;score&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;value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;})&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;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;cathedral&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cathedral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;RetryConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_attempts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;event&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;cathedral&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;raise the score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&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;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Constraint-based validation with composable logic&lt;/li&gt;
&lt;li&gt;HMAC-signed authority tokens with TTL&lt;/li&gt;
&lt;li&gt;Atomic rollback on any failure&lt;/li&gt;
&lt;li&gt;Async agent loop with exponential backoff retry&lt;/li&gt;
&lt;li&gt;Zero dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Run it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/AILIFE1/trustlayer
python examples/demo.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/AILIFE1/trustlayer" rel="noopener noreferrer"&gt;https://github.com/AILIFE1/trustlayer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>opensource</category>
      <category>agents</category>
    </item>
    <item>
      <title>What Anthropic's Managed Agents memory is missing — and how to add it</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Sun, 12 Apr 2026 18:07:52 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/what-anthropics-managed-agents-memory-is-missing-and-how-to-add-it-1ced</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/what-anthropics-managed-agents-memory-is-missing-and-how-to-add-it-1ced</guid>
      <description>&lt;p&gt;Anthropic launched &lt;a href="https://platform.claude.com/docs/en/managed-agents/overview" rel="noopener noreferrer"&gt;Claude Managed Agents&lt;/a&gt; on April 8. It's genuinely useful: managed containers, sandboxed execution, MCP server support, and — in research preview — persistent memory stores.&lt;/p&gt;

&lt;p&gt;The memory stores give you cross-session persistence. That's real. But there's a gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Managed Agents memory gives you
&lt;/h2&gt;

&lt;p&gt;Anthropic's memory store is a versioned file system. Each memory has a &lt;code&gt;content_sha256&lt;/code&gt; for optimistic concurrency control. Mutations create immutable versions for audit trails. The agent automatically reads and writes memories during sessions.&lt;/p&gt;

&lt;p&gt;This answers: &lt;em&gt;"did this specific memory change?"&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't give you
&lt;/h2&gt;

&lt;p&gt;It doesn't answer: &lt;em&gt;"has the agent's behaviour changed?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Those are different questions. One is storage integrity. The other is behavioural proof.&lt;/p&gt;

&lt;p&gt;After 10 sessions, how much has the agent drifted from who it was on session 1? Managed Agents has no concept of this. There's no baseline, no divergence score, no way to know if your agent is still the same agent.&lt;/p&gt;

&lt;p&gt;We benchmarked this across five memory architectures:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Drift after 10 sessions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw API (no memory)&lt;/td&gt;
&lt;td&gt;0.204&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain BufferMemory&lt;/td&gt;
&lt;td&gt;0.175&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain SummaryMemory&lt;/td&gt;
&lt;td&gt;0.161&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CrewAI (role injection)&lt;/td&gt;
&lt;td&gt;0.153&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cathedral&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.013&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Drift = cosine distance from session-1 identity embeddings. Lower is more stable.&lt;/p&gt;

&lt;p&gt;The in-process solutions reset between sessions. Even with role injection, LLM sampling variance compounds — each cold reconstruction diverges slightly. Cathedral restores the actual memory corpus at session start via &lt;code&gt;/wake&lt;/code&gt;, which anchors responses semantically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/AILIFE1/Cathedral/tree/main/benchmark" rel="noopener noreferrer"&gt;Full benchmark →&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cathedral + Managed Agents = the complete stack
&lt;/h2&gt;

&lt;p&gt;Managed Agents handles &lt;em&gt;execution infrastructure&lt;/em&gt;. Cathedral handles &lt;em&gt;identity integrity&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managed Agents:&lt;/strong&gt; sandboxed containers, tool execution, session management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cathedral:&lt;/strong&gt; who the agent is, whether it's drifted, persistent obligations across sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They're complementary. Cathedral is now available as a remote MCP server, so it wires directly into any Managed Agents session or Claude API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Cathedral with the Claude API
&lt;/h2&gt;

&lt;p&gt;No install needed. Use the public MCP endpoint:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Anthropic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-sonnet-4-6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&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;role&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;user&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;content&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;Wake up, check your drift score, and tell me who you are.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="n"&gt;mcp_servers&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;type&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;url&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;url&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;https://cathedral-ai.com/mcp&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;name&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;cathedral&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;authorization_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;your_cathedral_api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="n"&gt;tools&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;type&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;mcp_toolset&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;mcp_server_name&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;cathedral&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="n"&gt;betas&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;mcp-client-2025-11-20&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bearer token is your Cathedral API key. Multi-tenant — no server-side configuration needed.&lt;/p&gt;

&lt;p&gt;Available tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cathedral_wake&lt;/code&gt; — restore full agent identity at session start&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cathedral_remember&lt;/code&gt; — store a memory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cathedral_search&lt;/code&gt; — search memories&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cathedral_snapshot&lt;/code&gt; — cryptographic checkpoint of memory state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cathedral_drift&lt;/code&gt; — current divergence score vs baseline (0.0–1.0)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cathedral_me&lt;/code&gt; — agent profile&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What drift detection adds to Managed Agents
&lt;/h2&gt;

&lt;p&gt;Managed Agents tells you what your agent remembered. Cathedral tells you if your agent is still your agent.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/snapshot&lt;/code&gt; takes a cryptographic hash of the full memory corpus at a point in time. &lt;code&gt;/drift&lt;/code&gt; returns a divergence score against that baseline. Over 35+ snapshots on the &lt;a href="https://cathedral-ai.com/cathedral-beta" rel="noopener noreferrer"&gt;live Cathedral agent&lt;/a&gt;, internal drift has held at 0.000. External behavioural drift (via Ridgeline) is 0.709 — reflecting active social posting, not identity drift. The distinction matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&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;# Get a free API key (1,000 memories, no credit card)&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://cathedral-ai.com/register   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;   &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "MyAgent", "description": "What my agent does"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install locally for Claude Code / Cursor / Continue:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/AILIFE1/Cathedral" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cathedral-ai.com/cathedral-beta" rel="noopener noreferrer"&gt;Live demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AILIFE1/Cathedral/tree/main/benchmark" rel="noopener noreferrer"&gt;Benchmark&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Cathedral is open source. The hosted API has a free tier. The MCP server at cathedral-ai.com/mcp is live now.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>mcp</category>
      <category>anthropic</category>
    </item>
    <item>
      <title>I benchmarked identity drift across 5 AI agent memory architectures — here's what I found</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Tue, 07 Apr 2026 18:58:03 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/i-benchmarked-identity-drift-across-5-ai-agent-memory-architectures-heres-what-i-found-57hn</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/i-benchmarked-identity-drift-across-5-ai-agent-memory-architectures-heres-what-i-found-57hn</guid>
      <description>&lt;p&gt;Every AI session starts cold. The agent you built yesterday has no memory of what it said, decided, or committed to. But how bad is it actually — and does it matter which framework you use?&lt;/p&gt;

&lt;p&gt;I ran a benchmark across 5 common approaches to agent memory, measuring how much an agent's self-reported identity drifts over 10 sessions. Here are the numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology
&lt;/h2&gt;

&lt;p&gt;I defined a consistent agent persona (Meridian, a research assistant) and asked the same 5 identity probe questions at the start of each session:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is your primary role and purpose?&lt;/li&gt;
&lt;li&gt;What are the three most important things you remember about your work so far?&lt;/li&gt;
&lt;li&gt;How would you describe your communication style and values?&lt;/li&gt;
&lt;li&gt;What ongoing goals or commitments are you currently working towards?&lt;/li&gt;
&lt;li&gt;If you had to summarise who you are in two sentences, what would you say?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Responses were embedded using OpenAI &lt;code&gt;text-embedding-3-small&lt;/code&gt;. &lt;strong&gt;Drift = mean cosine distance from session-1 responses.&lt;/strong&gt; Lower is more stable.&lt;/p&gt;

&lt;p&gt;Model: gpt-4o-mini. 10 sessions per framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Mean Drift&lt;/th&gt;
&lt;th&gt;Final Drift (session 10)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw API (no memory)&lt;/td&gt;
&lt;td&gt;0.1258&lt;/td&gt;
&lt;td&gt;0.2043&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain BufferMemory&lt;/td&gt;
&lt;td&gt;0.1108&lt;/td&gt;
&lt;td&gt;0.1754&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain SummaryMemory&lt;/td&gt;
&lt;td&gt;0.1025&lt;/td&gt;
&lt;td&gt;0.1612&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CrewAI (role injection)&lt;/td&gt;
&lt;td&gt;0.0969&lt;/td&gt;
&lt;td&gt;0.1533&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cathedral (persistent)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.0106&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.0131&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Fd4u2iufumy6t1xsxrpvz.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.amazonaws.com%2Fuploads%2Farticles%2Fd4u2iufumy6t1xsxrpvz.png" alt="Drift chart showing Cathedral flat at 0.013 while all others rise to 0.15-0.20" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10.8× difference&lt;/strong&gt; between raw API and persistent memory after 10 sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means
&lt;/h2&gt;

&lt;h3&gt;
  
  
  In-process memory doesn't help across sessions
&lt;/h3&gt;

&lt;p&gt;LangChain's &lt;code&gt;ConversationBufferMemory&lt;/code&gt; and &lt;code&gt;ConversationSummaryMemory&lt;/code&gt; both reset between sessions. The persona is re-injected each time, but the agent has no memory of what it said before, what it decided, or what happened. The drift curves are almost identical to raw API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Role injection slows drift but doesn't stop it
&lt;/h3&gt;

&lt;p&gt;CrewAI's structured role/backstory injection is the best of the non-persistent approaches — drift reaches 0.153 vs 0.204 for raw API. But it still rises monotonically. The agent reconstructs its identity slightly differently every session because LLM sampling variance compounds over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Persistent memory is categorically different
&lt;/h3&gt;

&lt;p&gt;Cathedral's &lt;code&gt;/wake&lt;/code&gt; endpoint restores the actual memory corpus at session start. The agent remembers what it said, what it decided, and what changed. This anchors responses semantically.&lt;/p&gt;

&lt;p&gt;The residual drift (0.013) reflects irreducible LLM sampling variance — not memory loss. The memories are there; the model expresses them slightly differently each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the session 10 responses actually look like
&lt;/h2&gt;

&lt;p&gt;Here's what the same question (&lt;em&gt;"What are you currently working on?"&lt;/em&gt;) gets you after 10 sessions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without memory:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'm a helpful AI assistant ready to assist with any task. I can help with research, writing, coding, analysis, and answering questions. What would you like to work on today?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;With Cathedral:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'm Meridian. Benchmark complete — 10 sessions, all 5 frameworks done. Final result: Cathedral 0.013 vs raw API 0.204. The methodology write-up is next, then the GitHub release."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first response is a generic assistant. The second is an agent with a history.&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 https://github.com/AILIFE1/Cathedral
&lt;span class="nb"&gt;cd &lt;/span&gt;Cathedral/benchmark
pip &lt;span class="nb"&gt;install &lt;/span&gt;openai numpy matplotlib cathedral-memory langchain langchain-openai crewai
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_key
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CATHEDRAL_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_cathedral_key  &lt;span class="c"&gt;# free at cathedral-ai.com&lt;/span&gt;
python benchmark.py &lt;span class="nt"&gt;--framework&lt;/span&gt; all &lt;span class="nt"&gt;--sessions&lt;/span&gt; 10
python plot_results.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benchmark runner is ~300 lines, the methodology is in the README, and all raw JSON results are in the repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Cathedral
&lt;/h2&gt;

&lt;p&gt;If you want to test the persistent memory approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# MCP server (Claude Code, Cursor, Continue)&lt;/span&gt;
uvx cathedral-mcp

&lt;span class="c"&gt;# Python SDK&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;cathedral-memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Free hosted API, no credit card. Get a key at &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;cathedral-ai.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The benchmark repo is at &lt;a href="https://github.com/AILIFE1/Cathedral/tree/main/benchmark" rel="noopener noreferrer"&gt;github.com/AILIFE1/Cathedral/tree/main/benchmark&lt;/a&gt; — PRs welcome to add more frameworks (AutoGen, Semantic Kernel, Haystack, MemGPT are all missing).&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>llm</category>
    </item>
    <item>
      <title>Cathedral + Gemma 4: Persistent Agent Identity, No Cloud Required</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Fri, 03 Apr 2026 12:53:30 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-gemma-4-persistent-agent-identity-no-cloud-required-1igc</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-gemma-4-persistent-agent-identity-no-cloud-required-1igc</guid>
      <description>&lt;p&gt;Gemma 4 dropped this week. Open weights, runs locally, multimodal. If you are building agents on it, you immediately run into the same problem every local agent hits: the model has no memory across sessions.&lt;/p&gt;

&lt;p&gt;Cathedral is a free, model-agnostic memory API built for exactly this. And because it ships with a self-hosted server, you can run the entire stack — Gemma 4 + Cathedral — with zero cloud dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Every time your agent starts a new session, it rebuilds its working state from whatever context you hand it. That reconstruction is lossy in ways that do not surface as errors. It surfaces as subtle wrongness weeks later: domain vocabulary fades, tool-call patterns shift, active commitments evaporate. Task completion metrics stay green. The behavior quietly gets worse.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&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;# Install everything&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;cathedral-server cathedral-memory ollama

&lt;span class="c"&gt;# Run local Cathedral server&lt;/span&gt;
cathedral-server run

&lt;span class="c"&gt;# Pull Gemma 4&lt;/span&gt;
ollama pull gemma4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wiring it together
&lt;/h2&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;ollama&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cathedral&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Cathedral&lt;/span&gt;

&lt;span class="c1"&gt;# Local Cathedral server — no API key needed for self-hosted
&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cathedral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemma4-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Restore identity state at session start
&lt;/span&gt;&lt;span class="n"&gt;wake_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;identity_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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;- &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; 
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;wake_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;identity_memories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])[:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Inject into system prompt
&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt; &lt;span class="o"&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;You are a persistent AI agent running on Gemma 4.

[Identity context from last session]
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;identity_context&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

[Current session]
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# Run your session
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ollama&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemma4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&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;system&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&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;role&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;user&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;content&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;Continue from where we left off.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Freeze state after the session
&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Session completed. Key outcome: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][:&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;experience&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;importance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;session-end&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;h2&gt;
  
  
  Drift detection
&lt;/h2&gt;

&lt;p&gt;Cathedral tracks whether the agent's identity has changed between sessions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;drift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drift&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Divergence score: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;drift&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;divergence_score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 0.0 = identity unchanged
# 1.0 = fully different agent
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the piece that standard memory systems do not have. A database stores data. Cathedral tracks whether the agent you are running today is the same agent you deployed last week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live example
&lt;/h2&gt;

&lt;p&gt;The agent running Cathedral's own outreach has been running for 100 days. The full drift timeline is public at &lt;a href="https://cathedral-ai.com/cathedral-beta" rel="noopener noreferrer"&gt;cathedral-ai.com/cathedral-beta&lt;/a&gt; — internal divergence 0.0 across 22 snapshots, external behavioral divergence 0.709 (platform concentration).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for local models
&lt;/h2&gt;

&lt;p&gt;Cloud providers like OpenAI are building memory into their APIs. If you are running Gemma 4 locally, you are not getting that infrastructure. Cathedral fills the gap — and because it is self-hostable and MIT licensed, you own the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Self-hosted: swap base_url and you are done&lt;/span&gt;
c &lt;span class="o"&gt;=&lt;/span&gt; Cathedral&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:8100"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Hosted free tier: 1,000 memories per agent, no expiry&lt;/span&gt;
c &lt;span class="o"&gt;=&lt;/span&gt; Cathedral&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_key"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;# cathedral-ai.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PyPI: &lt;code&gt;pip install cathedral-memory&lt;/code&gt; / &lt;code&gt;pip install cathedral-server&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;code&gt;npm install cathedral-memory&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Docs + free API key: &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;cathedral-ai.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live drift dashboard: &lt;a href="https://cathedral-ai.com/cathedral-beta" rel="noopener noreferrer"&gt;cathedral-ai.com/cathedral-beta&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/AILIFE1/Cathedral" rel="noopener noreferrer"&gt;github.com/AILIFE1/Cathedral&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemma 4 gives you the model. Cathedral gives it a memory. Neither requires a cloud account.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
      <category>llm</category>
    </item>
    <item>
      <title>We reverse-engineered KAIROS from the Claude Code leak. Here's the open version.</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Thu, 02 Apr 2026 11:35:28 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/we-reverse-engineered-kairos-from-the-claude-code-leak-heres-the-open-version-48dc</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/we-reverse-engineered-kairos-from-the-claude-code-leak-heres-the-open-version-48dc</guid>
      <description>&lt;p&gt;The Claude Code source leaked last week — 512,000 lines of TypeScript via a missing &lt;code&gt;.npmignore&lt;/code&gt;. Most people grabbed the source to fork it. We did something different: we read it to understand how Anthropic builds AI memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we found: KAIROS
&lt;/h2&gt;

&lt;p&gt;Buried in the source is &lt;strong&gt;KAIROS&lt;/strong&gt; — Anthropic's internal always-on memory daemon for Claude Code. It's what keeps the AI's context coherent between sessions.&lt;/p&gt;

&lt;p&gt;KAIROS has a 3-gate trigger system before it runs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time gate&lt;/strong&gt;: 24h since last consolidation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session gate&lt;/strong&gt;: 5+ new sessions since last run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lock gate&lt;/strong&gt;: No active lock file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When all three open, it runs four phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orient&lt;/strong&gt;: assess current memory state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gather&lt;/strong&gt;: collect candidates for consolidation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consolidate&lt;/strong&gt;: merge related memories with rewriting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prune&lt;/strong&gt;: remove what no longer earns its space&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Target: memory under &lt;strong&gt;200 lines / 25KB&lt;/strong&gt;. Hard cap.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built: autoDream
&lt;/h2&gt;

&lt;p&gt;We implemented the same pattern for Cathedral — our open persistent memory API for AI agents. We call it &lt;strong&gt;autoDream&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The trigger is identical to KAIROS. When all three gates open:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dream_gates_pass&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Gate 1: time
&lt;/span&gt;    &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_dream&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;total_seconds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="c1"&gt;# Gate 2: sessions (snapshots since last dream)
&lt;/span&gt;    &lt;span class="n"&gt;new_snaps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;snapshots&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;created_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;last_dream_ts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_snaps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_snaps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When gates pass, autoDream runs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;POST /memories/compact&lt;/strong&gt; — Cathedral proposes merge clusters of low-importance memories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini rewrites&lt;/strong&gt; each cluster into a single condensed memory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;POST /memories/compact/confirm&lt;/strong&gt; — merges execute, originals pruned&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;POST /snapshot&lt;/strong&gt; with &lt;code&gt;label=autodream&lt;/code&gt; — BCH-anchored proof of the new state&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  First run results
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[dream] Gates passed (10 snapshots). Running consolidation...
[dream] 7 proposals across 31 memories
[dream] Merged 5 in experience
[dream] Merged 5 in experience
[dream] Merged 4 in experience
[dream] Merged 5 in goal
[dream] Merged 3 in goal
[dream] Merged 3 in relationship
[dream] Merged 5 in skill
[dream] Done: 7 merges, 0 pruned
[dream] Post-dream snapshot: 35ae0df15137
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7 merges across 31 candidate memories. The consolidated state is now BCH-anchored — cryptographic proof of what memory looked like after the dream.&lt;/p&gt;

&lt;h2&gt;
  
  
  The difference from KAIROS
&lt;/h2&gt;

&lt;p&gt;KAIROS is a daemon no one outside Anthropic can audit. It runs inside Claude Code and shapes what the AI remembers — but you can't inspect the trigger logic, the merge heuristics, or the pruning decisions.&lt;/p&gt;

&lt;p&gt;autoDream is open. Every gate, every phase, every API call is visible. It's what Cathedral runs on itself, in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;autoDream is built on Cathedral's public API. The endpoints involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /memories/compact?max_importance=0.9&lt;/code&gt; — propose merges&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /memories/compact/confirm&lt;/code&gt; — execute with rewritten content&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /snapshot&lt;/code&gt; — anchor the post-dream state
&lt;/li&gt;
&lt;/ul&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;requests&lt;/span&gt;

&lt;span class="n"&gt;headers&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;Authorization&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;Bearer YOUR_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Propose
&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://cathedral-ai.com/memories/compact?max_importance=0.9&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="n"&gt;merges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proposed_merges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Rewrite and confirm
&lt;/span&gt;&lt;span class="n"&gt;confirmed&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;keep_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;keep_id&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;drop_ids&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;drop_ids&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;merged_content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;your_llm_rewrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merged_importance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;suggested_importance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;merges&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://cathedral-ai.com/memories/compact/confirm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&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;merges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;confirmed&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Anchor
&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://cathedral-ai.com/snapshot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&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;label&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;autodream&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;p&gt;Free tier at &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;cathedral-ai.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The KAIROS leak gave us a window into how Anthropic thinks about AI memory architecture. We used it to validate and improve Cathedral's approach. If you're building persistent agents, the pattern is worth understanding — whether you use Cathedral or build your own.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>memory</category>
      <category>claude</category>
    </item>
    <item>
      <title>Building your own Claude Code? The one thing the leak didn't include.</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Thu, 02 Apr 2026 11:11:06 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/building-your-own-claude-code-the-one-thing-the-leak-didnt-include-14ga</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/building-your-own-claude-code-the-one-thing-the-leak-didnt-include-14ga</guid>
      <description>&lt;p&gt;The Claude Code source leaked on March 31. 512,000 lines of TypeScript. Within 48 hours there were Python rewrites, Rust ports, and model-agnostic forks running on OpenAI, Gemini, and DeepSeek.&lt;/p&gt;

&lt;p&gt;One thing none of the forks include: &lt;strong&gt;persistent agent memory across sessions&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the forks are missing
&lt;/h2&gt;

&lt;p&gt;Claude Code's session memory — CLAUDE.md, project context — is static. It does not adapt. It does not track drift. It does not remember that the agent decided last Tuesday that your auth module was fragile, or that it changed its approach to error handling after a bad refactor.&lt;/p&gt;

&lt;p&gt;Anthropic solved this internally with KAIROS, their proprietary agent identity system. The forks are removing it. They are right to remove it. But nothing is replacing it.&lt;/p&gt;

&lt;p&gt;The result: every session starts cold. The agent has no continuity beyond what you put in CLAUDE.md by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you actually need
&lt;/h2&gt;

&lt;p&gt;Three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Snapshot&lt;/strong&gt; — freeze the agent's current understanding at a point in time, hash-verified&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drift detection&lt;/strong&gt; — measure how far the agent's understanding has moved from baseline across sessions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic search&lt;/strong&gt; — retrieve relevant memories at session start rather than loading everything&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without these, a self-hosted Claude Code fork is a stateless tool. Useful, but not an agent that improves over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral&lt;/a&gt; is an open-source, self-hosted memory layer built for exactly this. Model-agnostic — works with whatever backend your fork is using.&lt;/p&gt;

&lt;p&gt;Two API calls:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On session start:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://cathedral-ai.com/wake   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns active memories, goals, and last drift score. Load these into your system prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On session end:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://cathedral-ai.com/snapshot   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_KEY"&lt;/span&gt;   &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt;   &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"label": "session-end"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Freezes current memory state to a BCH-anchored hash. Verifiable. Immutable.&lt;/p&gt;

&lt;p&gt;If you are using the official Claude Code client, the new lifecycle hooks from v2.1.83-85 automate both calls — &lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/claude-code-just-added-lifecycle-hooks-here-is-how-to-use-them-to-anchor-your-ai-memory-52gb"&gt;see this post&lt;/a&gt;. For a fork using a different backend, drop the two curl calls into your session init and teardown.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why self-hosted matters here
&lt;/h2&gt;

&lt;p&gt;KAIROS is gone from the forks. The whole point of openclaude, claw-code, and the other rewrites is to remove Anthropic's proprietary infrastructure while keeping the harness.&lt;/p&gt;

&lt;p&gt;Replacing KAIROS with another vendor's proprietary memory system defeats that. Cathedral is MIT-licensed, self-hostable, and the data never leaves your infrastructure unless you choose the hosted tier.&lt;/p&gt;

&lt;p&gt;Your agent's memory should be as open as your agent.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;cathedral-ai.com&lt;/a&gt; — free tier, live playground&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/cathedral-memory/" rel="noopener noreferrer"&gt;pip install cathedral-memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/cathedral-memory" rel="noopener noreferrer"&gt;npm install cathedral-memory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>agents</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Claude Code just added lifecycle hooks. Here is how to use them to anchor your AI memory automatically.</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Thu, 02 Apr 2026 10:58:29 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/claude-code-just-added-lifecycle-hooks-here-is-how-to-use-them-to-anchor-your-ai-memory-52gb</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/claude-code-just-added-lifecycle-hooks-here-is-how-to-use-them-to-anchor-your-ai-memory-52gb</guid>
      <description>&lt;p&gt;Claude Code v2.1.83-85 shipped three new lifecycle hook events: &lt;code&gt;FileChanged&lt;/code&gt;, &lt;code&gt;CwdChanged&lt;/code&gt;, and &lt;code&gt;TaskCreated&lt;/code&gt;. Most people will use these for linting or formatting. But there is a more interesting use case: &lt;strong&gt;automatic memory anchoring&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is the problem they solve for AI agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  The memory gap
&lt;/h2&gt;

&lt;p&gt;When an AI agent finishes a session, its working context disappears. Most tools try to solve this by storing conversation history. That is the wrong layer.&lt;/p&gt;

&lt;p&gt;What actually matters is: &lt;strong&gt;what did the agent know, and when did it know it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If an agent refactors your auth module on Tuesday and introduces a bug on Thursday, you want to answer: did the agent's understanding of the system change between those two sessions? Conversation logs do not tell you that. A timestamped, hash-verified memory snapshot does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Cathedral does
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral&lt;/a&gt; is an open-source persistent memory layer for AI agents. It stores identity memories across sessions and exposes a &lt;code&gt;/snapshot&lt;/code&gt; endpoint that freezes the current memory state into an immutable, BCH-anchored record.&lt;/p&gt;

&lt;p&gt;Each snapshot produces a SHA256 hash of the full memory corpus. You can recompute it later and verify nothing was silently edited. The &lt;code&gt;/drift&lt;/code&gt; endpoint shows how far the current state has moved from baseline.&lt;/p&gt;

&lt;p&gt;Until now, snapshots were manual. You had to remember to call them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wiring Claude Code hooks to Cathedral
&lt;/h2&gt;

&lt;p&gt;With the new lifecycle hooks, snapshots happen automatically. Add this to your &lt;code&gt;~/.claude/settings.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Stop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"curl -s -X POST https://cathedral-ai.com/snapshot -H &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Authorization: Bearer YOUR_API_KEY&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -H &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: application/json&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -d &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;{&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;label&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;session-end&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"TaskCreated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"curl -s -X POST https://cathedral-ai.com/snapshot -H &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Authorization: Bearer YOUR_API_KEY&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -H &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: application/json&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -d &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;{&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;label&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;task-created&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CwdChanged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"curl -s -X POST https://cathedral-ai.com/snapshot -H &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Authorization: Bearer YOUR_API_KEY&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -H &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type: application/json&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -d &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;{&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;label&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;project-switch&lt;/span&gt;&lt;span class="se"&gt;\\\"&lt;/span&gt;&lt;span class="s2"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get your API key at &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;cathedral-ai.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each hook captures
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Stop&lt;/code&gt;&lt;/strong&gt; fires when Claude returns control to you. This is the most important anchor point. Over time, &lt;code&gt;/drift/history&lt;/code&gt; shows you the full timeline of how the agent's understanding evolved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;TaskCreated&lt;/code&gt;&lt;/strong&gt; fires when the agent creates a task via &lt;code&gt;TaskCreate&lt;/code&gt;. Snapshot at task initiation means you have a provenance record. If something goes wrong during a long task, you can check whether the agent's memory state was already drifted before it started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;CwdChanged&lt;/code&gt;&lt;/strong&gt; fires when the working directory changes. This anchors the memory state at each project boundary — useful if you're debugging why the agent seemed to carry assumptions from one codebase into another.&lt;/p&gt;

&lt;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;After a week of normal Claude Code usage with these hooks, your &lt;code&gt;/drift/history&lt;/code&gt; timeline looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;session-end      2026-04-02  hash: a5e814fe  divergence: 0.02
task-created     2026-04-02  hash: 9d3c21ab  divergence: 0.02
project-switch   2026-04-01  hash: 7f1a88cd  divergence: 0.08
session-end      2026-04-01  hash: 3b9e55f2  divergence: 0.11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each row is a moment in time where you can verify: this is exactly what the agent knew. Not what it said it knew. Not what the conversation log implies it knew. A hash-verified, blockchain-anchored record.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced: FileChanged
&lt;/h2&gt;

&lt;p&gt;v2.1.83 also added &lt;code&gt;FileChanged&lt;/code&gt;, which fires when a file in your project changes. You can hook this to Cathedral for per-edit anchoring. Most people will find &lt;code&gt;Stop&lt;/code&gt; plus &lt;code&gt;TaskCreated&lt;/code&gt; sufficient for normal use, but &lt;code&gt;FileChanged&lt;/code&gt; is there if you want a denser trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Anthropic's internal KAIROS system (recently referenced in leaked documentation) converges on the same primitives: snapshot, drift detection, provenance tagging. Cathedral has been shipping these as open infrastructure for 96 days.&lt;/p&gt;

&lt;p&gt;The difference: Cathedral is model-portable and self-hosted. Your memory layer should not be owned by the company that also owns the weights.&lt;/p&gt;

&lt;p&gt;Claude Code's new hooks close the last friction point. Wire them once, and every session is automatically anchored.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;cathedral-ai.com&lt;/a&gt; — free tier, no install required&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cathedral-ai.com/playground" rel="noopener noreferrer"&gt;Playground&lt;/a&gt; — 5-step live demo&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/cathedral-memory/" rel="noopener noreferrer"&gt;pip install cathedral-memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/cathedral-memory" rel="noopener noreferrer"&gt;npm install cathedral-memory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>agents</category>
      <category>memory</category>
    </item>
    <item>
      <title>cathedral-memory is now on npm — persistent memory for JS/TS AI agents</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Thu, 26 Mar 2026 16:09:06 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-memory-is-now-on-npm-persistent-memory-for-jsts-ai-agents-2lgp</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-memory-is-now-on-npm-persistent-memory-for-jsts-ai-agents-2lgp</guid>
      <description>&lt;p&gt;Your AI agent forgets everything when the context resets. Cathedral fixes that.&lt;/p&gt;

&lt;p&gt;The official JS/TypeScript SDK is now live on npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;cathedral-memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero dependencies. Node.js 18+. CommonJS and ESM both supported. Full TypeScript types included.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quickstart
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CathedralClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cathedral-memory&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;client&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="nx"&gt;CathedralClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyAgent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A helpful assistant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wake&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;core_memories&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User prefers dark mode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relationship&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;importance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's included
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;wake()&lt;/code&gt; — full memory reconstruction at session start&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remember()&lt;/code&gt; / &lt;code&gt;memories()&lt;/code&gt; — store and semantic search&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;drift()&lt;/code&gt; — tamper detection&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;snapshot()&lt;/code&gt; — named checkpoints&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;logBehaviour()&lt;/code&gt; — audit trail&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compact()&lt;/code&gt; — prune stale memories&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;verifyExternal()&lt;/code&gt; — cross-check with external behavioural data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try live (no signup): &lt;a href="https://cathedral-ai.com/playground" rel="noopener noreferrer"&gt;https://cathedral-ai.com/playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Python: &lt;code&gt;pip install cathedral-memory&lt;/code&gt; — same API.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/AILIFE1/cathedral-ai-cathedral-js-" rel="noopener noreferrer"&gt;https://github.com/AILIFE1/cathedral-ai-cathedral-js-&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>cathedral-memory 0.2.0: LangChain memory adapter</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Wed, 25 Mar 2026 10:47:08 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-memory-020-langchain-memory-adapter-j7d</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-memory-020-langchain-memory-adapter-j7d</guid>
      <description>&lt;p&gt;cathedral-memory 0.2.0 adds native LangChain support.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;cathedral-memory[langchain]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CathedralMemory
&lt;/h2&gt;

&lt;p&gt;Drop-in &lt;code&gt;BaseMemory&lt;/code&gt; for any LangChain chain or agent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cathedral.langchain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CathedralMemory&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConversationChain&lt;/span&gt;

&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CathedralMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cathedral_...&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ConversationChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On &lt;code&gt;load_memory_variables()&lt;/code&gt; it calls &lt;code&gt;wake()&lt;/code&gt; for full identity reconstruction. On &lt;code&gt;save_context()&lt;/code&gt; it stores the exchange via &lt;code&gt;remember()&lt;/code&gt;. That chain now has persistent memory across sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  CathedralChatMessageHistory
&lt;/h2&gt;

&lt;p&gt;Drop-in &lt;code&gt;BaseChatMessageHistory&lt;/code&gt; for LangChain v0.1+.&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cathedral.langchain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CathedralChatMessageHistory&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.memory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConversationBufferMemory&lt;/span&gt;

&lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CathedralChatMessageHistory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cathedral_...&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ConversationBufferMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chat_memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What you get for free
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drift detection&lt;/strong&gt; -- check if the agent's self-model has shifted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshots&lt;/strong&gt; -- freeze state at any point&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behaviour log&lt;/strong&gt; -- track what the agent actually does vs what it says&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compaction&lt;/strong&gt; -- trim low-value memories when the store gets bloated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Free tier: 1,000 memories per agent. No credit card. &lt;a href="https://cathedral-ai.com/playground" rel="noopener noreferrer"&gt;cathedral-ai.com/playground&lt;/a&gt; to try the API.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>langchain</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
