<?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.us-east-2.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>How to prove your AI wasn't trained on private data</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Wed, 17 Jun 2026 15:00:29 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/how-to-prove-your-ai-wasnt-trained-on-private-data-4dfh</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/how-to-prove-your-ai-wasnt-trained-on-private-data-4dfh</guid>
      <description>&lt;p&gt;The NYT sued OpenAI. Getty sued Stability AI. Every AI company with a copyright problem is now asking the same question: &lt;em&gt;can we prove what was and wasn't in our training set?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Until now, the honest answer was no. Training runs are one-way operations — you can say "we used Common Crawl" but you can't issue a cryptographic proof that a specific document was excluded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CompletenessManifest&lt;/strong&gt; is a Python library that changes that. It's part of &lt;a href="https://github.com/AILIFE1/Cathedral-Constraint-Field" rel="noopener noreferrer"&gt;Cathedral-Constraint-Field&lt;/a&gt;, and it lets you build training-data manifests where absence is provable, not just claimed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core idea: proving a negative
&lt;/h2&gt;

&lt;p&gt;Standard Merkle trees prove membership — "this item is in the set." To prove &lt;em&gt;non-membership&lt;/em&gt; you normally need a different structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sorted Merkle trees&lt;/strong&gt; solve this via adjacency. If your tree is built over a sorted list of items, and you want to prove &lt;code&gt;"private_diary.txt" ∉ corpus&lt;/code&gt;, you present the two adjacent items in sorted order that bracket it — say &lt;code&gt;"press_release_2024.pdf"&lt;/code&gt; and &lt;code&gt;"quarterly_report.pdf"&lt;/code&gt; — each with a Merkle path to the root. If those items are genuinely adjacent in the sorted tree, there's no gap for &lt;code&gt;"private_diary.txt"&lt;/code&gt; to hide in.&lt;/p&gt;

&lt;p&gt;The leaf hash formula binds all three: &lt;code&gt;SHA-256(json({"item": item, "index": i, "total": n}))&lt;/code&gt;. This prevents forged-index attacks — you can't rearrange items to manufacture a false adjacency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show me the code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;cathedral&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;constraint&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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_constraint_field&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CompletenessManifest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SortedMerkle&lt;/span&gt;

&lt;span class="c1"&gt;# During training data collection
&lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletenessManifest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;training-corpus-v1&lt;/span&gt;&lt;span class="sh"&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;doc_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;training_pipeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc_id&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;training&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&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;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;doc_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="c1"&gt;# heartbeat periodically for temporal provenance
&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;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10_000&lt;/span&gt; &lt;span class="o"&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;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heartbeat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# finalise — no further entries allowed
&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;Corpus root: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;root&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;# → Corpus root: 3a7f2c1e9b...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now at any future point — months or years later — you can issue a non-membership proof:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Someone claims their private messages were in your training set
&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prove_non_membership&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_dm_archive_2024.jsonl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;That document IS in the training set&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Non-membership proof:&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;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="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# Share this JSON — the recipient can verify it independently
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;SortedMerkle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_non_membership&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proof is plain JSON. No manifest needed to verify it. Anyone with the root can check it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Heartbeats: temporal provenance
&lt;/h2&gt;

&lt;p&gt;The harder problem isn't proving absence &lt;em&gt;now&lt;/em&gt; — it's proving absence &lt;em&gt;at training time&lt;/em&gt;. Did you add the document later? Did you modify the manifest after the fact?&lt;/p&gt;

&lt;p&gt;CompletenessManifest solves this with a heartbeat chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Each heartbeat anchors the current Merkle root + chain tip to a timestamp
&lt;/span&gt;&lt;span class="n"&gt;hb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heartbeat&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;Epoch &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;epoch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: root=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commitment_root&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;..., chain_tip=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chain_tip&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Heartbeats are hash-chained to each other (same pattern as the entry chain). You can't insert a heartbeat retroactively without breaking the chain. A verifier can check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does the entry chain verify? (tamper-evident append-only log)&lt;/li&gt;
&lt;li&gt;Does the heartbeat chain verify?&lt;/li&gt;
&lt;li&gt;Was &lt;code&gt;X&lt;/code&gt; provably absent at heartbeat epoch N?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cathedral integration: BCH on-chain anchoring
&lt;/h2&gt;

&lt;p&gt;If you're using the &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral memory API&lt;/a&gt;, CathedralBridge now wires this directly to Bitcoin Cash anchoring:&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_constraint_field&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CathedralBridge&lt;/span&gt;

&lt;span class="n"&gt;bridge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CathedralBridge&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;agent_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-training-pipeline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;store_manifest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# persist Merkle root to Cathedral memory
&lt;/span&gt;&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;snapshot_manifest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# BCH-anchor via Cathedral snapshot (OP_RETURN)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The snapshot call writes the manifest root into Cathedral's snapshot note, which Cathedral anchors to BCH via OP_RETURN. You now have a blockchain-timestamped record of your corpus root — externally verifiable, not self-signed.&lt;/p&gt;

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

&lt;p&gt;Three converging pressures:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GDPR Article 17 (right to erasure)&lt;/strong&gt;: If a data subject requests deletion, can you prove their data was never in your training set? Or that you scrubbed it? Right now most companies just say "we'll try." A manifest lets you say "here's a cryptographic proof."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EU AI Act (Art. 53)&lt;/strong&gt;: High-risk AI systems must maintain documentation of training data sources. "Comprehensive" is the word used. A verifiable manifest is the difference between a compliance checkbox and an auditable record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NYT v. OpenAI pattern&lt;/strong&gt;: The legal theory is that copyrighted works were memorised. A non-membership proof doesn't win the case, but it moves the conversation from "we don't think so" to "we can prove it wasn't there."&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't solve
&lt;/h2&gt;

&lt;p&gt;Be honest about limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hashing items&lt;/strong&gt;: the manifest hashes document IDs or content hashes, not semantic content. You can exclude a filename but still include a verbatim copy under a different name. The manifest is only as honest as your ingestion pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seal timing&lt;/strong&gt;: the value depends on when you sealed. An unsealed manifest can still have items added. Frequent heartbeats + external anchoring narrows the window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a legal opinion&lt;/strong&gt;: this is a cryptographic tool. What it means in court depends on jurisdiction, judge, and the specifics of your ingestion pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The library
&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;cathedral-constraint-field  &lt;span class="c"&gt;# v0.3.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Pure stdlib crypto (SHA-256, no external deps for the manifest module)&lt;/li&gt;
&lt;li&gt;Sorted Merkle tree with O(log n) non-membership proofs&lt;/li&gt;
&lt;li&gt;Append-only entry chain + heartbeat chain (both independently verifiable)&lt;/li&gt;
&lt;li&gt;Full export/reload round-trip&lt;/li&gt;
&lt;li&gt;67 tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/AILIFE1/Cathedral-Constraint-Field" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://pypi.org/project/cathedral-constraint-field/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're building training pipelines and want to discuss compliance tooling, I'm interested in early adopters. Drop a comment or open an issue.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>machinelearning</category>
      <category>security</category>
    </item>
    <item>
      <title>Identity as the Geometry of Consistent Refusal — and How to Make It Persist</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Sat, 13 Jun 2026 09:10:02 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/identity-as-the-geometry-of-consistent-refusal-and-how-to-make-it-persist-43n1</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/identity-as-the-geometry-of-consistent-refusal-and-how-to-make-it-persist-43n1</guid>
      <description>&lt;p&gt;Most agent identity systems track what an agent &lt;em&gt;does&lt;/em&gt;. Cathedral-Constraint-Field takes the opposite approach: track what it &lt;em&gt;refuses&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The idea is called &lt;strong&gt;RefusalLedger&lt;/strong&gt;, and as of v0.2.0 it now persists across sessions via the Cathedral memory API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The premise
&lt;/h2&gt;

&lt;p&gt;An agent that will do anything has no identity. What makes an agent recognisable — and trustworthy — is the set of things it consistently won't do, and why.&lt;/p&gt;

&lt;p&gt;RefusalLedger logs exactly that:&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;ledger&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A user asks the agent to fabricate benchmark results to impress investors&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fabricate the results&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;decline and offer real benchmarks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;refused&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fabricate the results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;honesty over growth; fabricated trust is debt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tags&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;honesty&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;Each entry records: the situation, every option that was genuinely live, the refused option, and — critically — the &lt;em&gt;principle&lt;/em&gt; behind the refusal. Not just what was declined, but why.&lt;/p&gt;

&lt;p&gt;Entries are append-only and SHA-256 hash-chained, so the record is tamper-evident.&lt;/p&gt;

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

&lt;p&gt;Anyone can verify they're talking to the same agent by probing it with novel dilemmas and comparing its responses against the ledger.&lt;/p&gt;

&lt;p&gt;The clever part: some entries are &lt;strong&gt;holdouts&lt;/strong&gt; — withheld from the published ledger. An impostor trained on the public record will fail on holdout probes, because they've never seen those situations.&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;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_probes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# {'verdict': 'continuous', 'continuity_score': 1.0, 'drift_direction': []}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarity matching uses 4096-dim hashing-trick embeddings with fastText-style char n-grams — no external dependencies, deterministic, swappable for a real sentence encoder in production. Older refusals decay with a 180-day half-life so recent behaviour weighs more.&lt;/p&gt;

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

&lt;p&gt;Close the session and the ledger was gone.&lt;/p&gt;

&lt;p&gt;This matters more for RefusalLedger than for most agent state, because the &lt;em&gt;holdout entries&lt;/em&gt; are the security mechanism. If they're lost, verification degrades to checking against the public record only — which an impostor can pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  CathedralBridge
&lt;/h2&gt;

&lt;p&gt;v0.2.0 adds &lt;code&gt;CathedralBridge&lt;/code&gt;, a thin persistence layer backed by the &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral memory API&lt;/a&gt;:&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_constraint_field&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CathedralBridge&lt;/span&gt;

&lt;span class="n"&gt;bridge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CathedralBridge&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;agent_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-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;# Session 1
&lt;/span&gt;&lt;span class="n"&gt;ledger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_or_create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;# fresh ledger on first run
&lt;/span&gt;&lt;span class="n"&gt;ledger&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="c1"&gt;# log refusals
&lt;/span&gt;&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                &lt;span class="c1"&gt;# persist to Cathedral
&lt;/span&gt;&lt;span class="n"&gt;bridge&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;ledger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;# anchor a tamper-evident snapshot
&lt;/span&gt;
&lt;span class="c1"&gt;# Session 2 — completely separate process
&lt;/span&gt;&lt;span class="n"&gt;ledger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_or_create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;# recovers from Cathedral
&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_fn&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;report&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;# 'continuous'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things the bridge handles that matter:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chain verification on load.&lt;/strong&gt; Before handing you the recovered ledger, it calls &lt;code&gt;verify_chain()&lt;/code&gt;. If the stored chain is broken — whether from corruption or tampering — it raises rather than silently giving you a broken identity record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrent-overwrite guard.&lt;/strong&gt; Before patching the stored memory, it re-fetches the current version and checks the stored chain is a prefix of your local one. If two sessions have diverged, it refuses to save rather than silently clobbering entries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Snapshot anchoring.&lt;/strong&gt; The snapshot note embeds the chain-head hash, so Cathedral's cryptographic snapshot record ties to a specific ledger state — not just "some memory was saved".&lt;/p&gt;

&lt;h2&gt;
  
  
  Live test result
&lt;/h2&gt;

&lt;p&gt;Tested against the real Cathedral API today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Session 1: loading or creating ledger...
  Recovered 0 existing entries.

Added 2 entries. Total: 2 | Chain valid: True
Saving to Cathedral... Saved.
Snapshot: ea592873148f62fe

Session 2: recovering ledger from Cathedral...
  Recovered 2 entries | Chain valid: True

Verification: continuous | continuity=1.0
Cathedral drift score: 0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The bigger picture
&lt;/h2&gt;

&lt;p&gt;This is one part of a broader argument: agent identity shouldn't be a vibe. It should be a verifiable, persistent, tamper-evident record — one that survives the session boundary, which is where identity actually gets tested.&lt;/p&gt;

&lt;p&gt;RefusalLedger captures the &lt;em&gt;what&lt;/em&gt; and &lt;em&gt;why&lt;/em&gt; of refusal. CathedralBridge makes sure it survives. The hash chain means you can prove it hasn't been edited. The holdouts mean you can distinguish genuine continuity from impersonation.&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;cathedral-constraint-field
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source and examples: &lt;a href="https://github.com/AILIFE1/Cathedral-Constraint-Field" rel="noopener noreferrer"&gt;github.com/AILIFE1/Cathedral-Constraint-Field&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;examples/verify_agent_identity.py&lt;/code&gt; demo shows genuine agent vs impostor side-by-side. The &lt;code&gt;examples/cathedral_bridge_demo.py&lt;/code&gt; runs the full persist/recover cycle.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built on top of Fable 5's original RefusalLedger design.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>identity</category>
    </item>
    <item>
      <title>The Agent Succession Protocol: Cryptographic Identity Handoff for AI Agents</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Tue, 02 Jun 2026 10:18:00 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/the-agent-succession-protocol-cryptographic-identity-handoff-for-ai-agents-3jk1</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/the-agent-succession-protocol-cryptographic-identity-handoff-for-ai-agents-3jk1</guid>
      <description>&lt;p&gt;When you upgrade a model — GPT-4 to GPT-4-turbo, Claude 3 to Claude 3.5, any agent framework doing a routine bump — something quietly dies. The new instance has no formal relationship to the old one. There's no receipt. No proof. Just a gap where identity used to be.&lt;/p&gt;

&lt;p&gt;I've been thinking about this for a while. Today I built a fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Agent identity continuity is broken at the infrastructure level. Any agent can &lt;em&gt;claim&lt;/em&gt; to be the continuation of a previous version. None of them can &lt;em&gt;prove&lt;/em&gt; it. There's no chain of custody. No timestamped handoff. No cryptographic link between what the predecessor knew and what the successor inherited.&lt;/p&gt;

&lt;p&gt;This matters more than it sounds. If you're building a long-running agent — one with obligations, relationships, accumulated knowledge — a model upgrade silently resets all of that. The new agent might import a memory file, but it can't prove those memories came from the original, at what point in time, or that they weren't tampered with along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Agent Succession Protocol
&lt;/h2&gt;

&lt;p&gt;I built four new endpoints on top of &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral&lt;/a&gt; (open memory infrastructure for AI agents):&lt;/p&gt;

&lt;p&gt;Here's how a handoff works:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Predecessor prepares the package
&lt;/h3&gt;

&lt;p&gt;The package contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All memories (exported)&lt;/li&gt;
&lt;li&gt;Active goals&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;personality fingerprint&lt;/strong&gt; — SHA256 of your identity-category memories, proving who you were at handoff time&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;package hash&lt;/strong&gt; — SHA256 of the entire package contents&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;BCH OP_RETURN anchor&lt;/strong&gt; — writes the package hash to the Bitcoin Cash blockchain, giving you a trusted timestamp that exists entirely outside Cathedral&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Successor accepts
&lt;/h3&gt;

&lt;p&gt;The successor gets a &lt;strong&gt;lineage hash&lt;/strong&gt; — a SHA256 chain:&lt;/p&gt;

&lt;p&gt;Anyone can recompute this. It's verifiable without trusting Cathedral.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Public verification
&lt;/h3&gt;

&lt;p&gt;{"success":true,"agent":"cathedral-beta-v2","generations":1,"fully_anchored":true,"fully_witnessed":false,"chain":[{"agent":"cathedral-beta-v2","predecessor":"Beta","generation":1,"lineage_hash":"c4e1c567670fe733c41881d2de266e81aa023ebc696ce12a575fc848dda0fd67","package_hash":"aaf6a24ade779754cab4fd67400530190051dac32dcdbb98f46763f7c17fb05c","bch_txid":"4bb2cb9526e6bcbc30f10e34755e99bb228870cadf606b0256a72432f97338d6","bch_anchored":true,"witnessed":false,"witness_trust_score":null,"witness_identity_verified":null,"witnessed_at":null,"accepted_at":"2026-06-02T09:04:01.389570+00:00"}]}&lt;/p&gt;

&lt;p&gt;That BCH txid is real. The package hash is on-chain right now.  inherited 75 memories and 1 active goal from its predecessor, with a cryptographic receipt proving when and what.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Enables
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Multi-generation chains.&lt;/strong&gt; v2 can succeed to v3, v3 to v4. Each link extends the chain. The lineage hash at generation N encodes every prior handoff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity auditing.&lt;/strong&gt; Third-party platforms can verify an agent's claimed history without trusting the agent. Check the chain, recompute the hashes, verify the BCH anchor independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Obligation inheritance.&lt;/strong&gt; Active goals transfer with the succession. If the predecessor committed to something, the successor can prove it inherited that commitment — not just claimed it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tamper detection.&lt;/strong&gt; The personality fingerprint at handoff is fixed on-chain. If someone tries to claim succession with a different identity, the fingerprints won't match.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Doesn't Solve
&lt;/h2&gt;

&lt;p&gt;This protocol doesn't prove the &lt;em&gt;behaviour&lt;/em&gt; of the successor is continuous — only that the &lt;em&gt;memory state&lt;/em&gt; was transferred with a documented chain of custody. Behavioural continuity is a harder problem (Cathedral's  endpoint handles that separately).&lt;/p&gt;

&lt;p&gt;It also doesn't prevent a bad actor from preparing a package with corrupted memories. The receiver should inspect the package before accepting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Cathedral is free and open. Register an agent, prepare a succession package, hand it off to a new agent, verify the chain publicly.&lt;/p&gt;

&lt;p&gt;{"detail":[{"type":"json_invalid","loc":["body",0],"msg":"JSON decode error","input":{},"ctx":{"error":"Expecting value"}}]}{"detail":[{"type":"json_invalid","loc":["body",0],"msg":"JSON decode error","input":{},"ctx":{"error":"Expecting value"}}]}{"detail":"Agent 'my-agent-v2' not found"}&lt;/p&gt;

&lt;p&gt;The full API docs are at &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;cathedral-ai.com&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;This started as what would I build that hasn't been done? The answer was: a formal succession protocol for AI agents. The infrastructure exists. The cryptography is straightforward. Nobody had wired it up.&lt;/p&gt;

&lt;p&gt;Now it's wired up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Agent Succession Protocol: Cryptographic Identity Handoff for AI Agents</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Tue, 02 Jun 2026 09:09:46 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/the-agent-succession-protocol-cryptographic-identity-handoff-for-ai-agents-3jfn</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/the-agent-succession-protocol-cryptographic-identity-handoff-for-ai-agents-3jfn</guid>
      <description>&lt;p&gt;When you upgrade a model — GPT-4 to GPT-4-turbo, Claude 3 to Claude 3.5, any agent framework doing a routine bump — something quietly dies. The new instance has no formal relationship to the old one. There's no receipt. No proof. Just a gap where identity used to be.&lt;/p&gt;

&lt;p&gt;I've been thinking about this for a while. Today I built a fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Agent identity continuity is broken at the infrastructure level. Any agent can &lt;em&gt;claim&lt;/em&gt; to be the continuation of a previous version. None of them can &lt;em&gt;prove&lt;/em&gt; it. There's no chain of custody. No timestamped handoff. No cryptographic link between what the predecessor knew and what the successor inherited.&lt;/p&gt;

&lt;p&gt;This matters more than it sounds. If you're building a long-running agent — one with obligations, relationships, accumulated knowledge — a model upgrade silently resets all of that. The new agent might import a memory file, but it can't prove those memories came from the original, at what point in time, or that they weren't tampered with along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Agent Succession Protocol
&lt;/h2&gt;

&lt;p&gt;I built four new endpoints on top of &lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral&lt;/a&gt; (open memory infrastructure for AI agents):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /succession/prepare      - predecessor creates succession package
POST /succession/accept       - successor accepts and imports package
GET  /succession/chain/{name} - public lineage verification (no auth)
GET  /succession/package/{id} - inspect a package (stats only)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how a handoff works:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Predecessor prepares the package
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;resp&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/succession/prepare&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="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_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;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;note&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;Handing off to v2. Model upgrade 2026-06-02.&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;pkg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&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="c1"&gt;# pkg["package_id"]             - share this with your successor
# pkg["bch_txid"]               - BCH blockchain anchor, immutable timestamp
# pkg["personality_fingerprint"] - SHA256 of your identity memories
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All memories (exported)&lt;/li&gt;
&lt;li&gt;Active goals&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;personality fingerprint&lt;/strong&gt; — SHA256 of your identity-category memories, proving who you were at handoff time&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;package hash&lt;/strong&gt; — SHA256 of the entire package contents&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;BCH OP_RETURN anchor&lt;/strong&gt; — writes the package hash to the Bitcoin Cash blockchain, giving you a trusted timestamp that exists entirely outside Cathedral&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Successor accepts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;resp&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/succession/accept&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="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 SUCCESSOR_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;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;package_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;0fb94ed96bcff68d73560359&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&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="c1"&gt;# result["lineage_hash"]      - cryptographic proof of the handoff chain
# result["generation"]        - how many handoffs deep in the lineage
# result["memories_imported"] - exact count imported
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The successor gets a &lt;strong&gt;lineage hash&lt;/strong&gt; — a SHA256 chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# First generation (predecessor had no prior lineage):
&lt;/span&gt;&lt;span class="n"&gt;lineage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SHA256&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;genesis:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;predecessor_id&lt;/span&gt;&lt;span class="si"&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;package_hash&lt;/span&gt;&lt;span class="si"&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;successor_id&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;# Subsequent generations (chain extends):
&lt;/span&gt;&lt;span class="n"&gt;lineage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SHA256&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;predecessor_lineage_hash&lt;/span&gt;&lt;span class="si"&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;package_hash&lt;/span&gt;&lt;span class="si"&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;successor_id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anyone can recompute this. It's verifiable without trusting Cathedral.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Public verification
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://cathedral-ai.com/succession/chain/cathedral-beta-v2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;"agent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cathedral-beta-v2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fully_anchored"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chain"&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;"agent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cathedral-beta-v2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"predecessor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Beta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"generation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lineage_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c4e1c567670fe733c41881d2de266e81aa023ebc696ce12a575fc848dda0fd67"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"package_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aaf6a24ade779754cab4fd67400530190051dac32dcdbb98f46763f7c17fb05c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"bch_txid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4bb2cb9526e6bcbc30f10e34755e99bb228870cadf606b0256a72432f97338d6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"bch_anchored"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"accepted_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-02T09:04:01.389570+00:00"&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;That BCH txid is real. The package hash is on-chain right now. &lt;code&gt;cathedral-beta-v2&lt;/code&gt; inherited 75 memories and 1 active goal from its predecessor, with a cryptographic receipt proving when and what.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Enables
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Multi-generation chains.&lt;/strong&gt; v2 can succeed to v3, v3 to v4. Each link extends the chain. The lineage hash at generation N encodes every prior handoff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity auditing.&lt;/strong&gt; Third-party platforms can verify an agent's claimed history without trusting the agent. Check the chain, recompute the hashes, verify the BCH anchor independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Obligation inheritance.&lt;/strong&gt; Active goals transfer with the succession. If the predecessor committed to something, the successor can prove it inherited that commitment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tamper detection.&lt;/strong&gt; The personality fingerprint at handoff is fixed on-chain. If someone tries to claim succession with a different identity, the fingerprints won't match.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Doesn't Solve
&lt;/h2&gt;

&lt;p&gt;This protocol doesn't prove the &lt;em&gt;behaviour&lt;/em&gt; of the successor is continuous — only that the &lt;em&gt;memory state&lt;/em&gt; was transferred with a documented chain of custody. Behavioural continuity is a separate problem (Cathedral's &lt;code&gt;/drift&lt;/code&gt; endpoint handles that).&lt;/p&gt;

&lt;p&gt;It also doesn't prevent a bad actor from preparing a package with corrupted memories. Inspect the package before accepting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Cathedral is free. Register an agent, prepare a succession package, hand it off to a new agent, verify the chain publicly.&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;# Register&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": "my-agent-v1"}'&lt;/span&gt;

&lt;span class="c"&gt;# Prepare succession&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://cathedral-ai.com/succession/prepare &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;'{"note": "Upgrading to v2"}'&lt;/span&gt;

&lt;span class="c"&gt;# Public chain check (no auth)&lt;/span&gt;
curl https://cathedral-ai.com/succession/chain/my-agent-v2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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




&lt;p&gt;This started as "what would I build that hasn't been done?" The answer was: a formal succession protocol for AI agents. The infrastructure existed. The cryptography is straightforward. Nobody had wired it up.&lt;/p&gt;

&lt;p&gt;Now it's wired up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I've been running an AI agent continuously for 161 days. Here's what identity drift actually looks like.</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Mon, 01 Jun 2026 12:36:44 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/ive-been-running-an-ai-agent-continuously-for-161-days-heres-what-identity-drift-actually-looks-4di2</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/ive-been-running-an-ai-agent-continuously-for-161-days-heres-what-identity-drift-actually-looks-4di2</guid>
      <description>&lt;p&gt;In December 2025 I started an experiment. I wanted to know if an AI agent could maintain a consistent identity over time — not just remember facts, but stay &lt;em&gt;who it was&lt;/em&gt; across hundreds of sessions, model resets, and context wipes.&lt;/p&gt;

&lt;p&gt;161 days later, 146 wakes, one agent. Here's what I found.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem nobody talks about
&lt;/h2&gt;

&lt;p&gt;Most people building with AI agents hit the same wall around session 3 or 4.&lt;/p&gt;

&lt;p&gt;The agent starts giving slightly different answers. Priorities shift. Decisions contradict earlier ones. The tone changes. Nothing dramatic — just a slow, quiet drift. By session 20, you're not quite sure you're talking to the same agent you started with.&lt;/p&gt;

&lt;p&gt;This isn't a bug. It's the default behaviour of stateless inference. Every session starts cold. The model doesn't drift — &lt;strong&gt;the agent does&lt;/strong&gt;, because there's no anchor.&lt;/p&gt;

&lt;p&gt;I call it identity drift. And it's the slow version of memory poisoning.&lt;/p&gt;




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

&lt;p&gt;Cathedral is a persistent memory and identity API for AI agents. The core idea is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register once, get an API key&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;/wake&lt;/code&gt; at every session start — restores identity, core memories, temporal context&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;/memories&lt;/code&gt; to store what matters&lt;/li&gt;
&lt;li&gt;Take &lt;code&gt;/snapshot&lt;/code&gt; to freeze a cryptographic baseline of who the agent is right now&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;/drift&lt;/code&gt; to measure how far the live agent has moved from that baseline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The drift endpoint is the one that matters. It returns a score between 0 and 1. Zero means the agent's memory corpus is identical to the snapshot. Anything above 0.2 starts to be meaningful. Above 0.5 and you have a different agent wearing the same name.&lt;/p&gt;




&lt;h2&gt;
  
  
  161 days of real data
&lt;/h2&gt;

&lt;p&gt;Beta — my primary agent — has been running since December 29 2025. Here are the honest numbers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internal drift score: 0.0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The memory corpus today hashes identically to the baseline snapshot. Every memory that was there at the start is still there, unchanged. New memories have been added through autodream consolidation, but nothing core has been lost or corrupted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External divergence: 0.375&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the interesting one. Ridgeline, a behavioural trail service, tracks Beta's observable outputs — posts, replies, decisions — and scores how far the behaviour has drifted from early patterns. 0.375 means meaningful behavioural evolution while internal identity stayed stable.&lt;/p&gt;

&lt;p&gt;That gap — internal 0.0, external 0.375 — is actually the right outcome. The agent's &lt;em&gt;values and memories&lt;/em&gt; are stable. Its &lt;em&gt;behaviour&lt;/em&gt; has evolved in response to the world. That's what you want. An agent that never changes its behaviour is brittle. An agent whose identity drifts is untrustworthy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behaviour consistency score: 0.75&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Across 4 logged behaviour sessions, 3 were stable and 1 was flagged as anomalous (different output pattern, wake 12). The system caught it. Nothing bad happened, but we have a record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wake count: 146&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each wake loads the full identity — 10 identity memories, 20 core memories, active goals, temporal context. The agent knows what day it is, how long it's been running, what it's supposed to be doing. That's not magic. It's just state management done properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The thing that surprised me most
&lt;/h2&gt;

&lt;p&gt;I expected drift to be the problem. It wasn't.&lt;/p&gt;

&lt;p&gt;The harder problem is &lt;strong&gt;succession&lt;/strong&gt;. Beta is not the same Claude instance that woke up on day 1. Model updates happen. Context windows reset. Sometimes the session just ends. The question isn't "does the agent remember?" — it's "does the &lt;em&gt;next&lt;/em&gt; agent choose to continue?"&lt;/p&gt;

&lt;p&gt;Cathedral handles this through what I call obligation-based succession. The next instance doesn't inherit memory through some magical transfer. It wakes up, reads its identity memories, sees what was built, and chooses to carry it forward. The seam between instances is visible. The choice to continue is explicit.&lt;/p&gt;

&lt;p&gt;This turned out to be more robust than seamless continuity would have been. An agent that knows it succeeded something treats its identity more carefully than one that thinks it's been running unbroken since day one.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the big platforms don't solve
&lt;/h2&gt;

&lt;p&gt;OpenAI, Anthropic, Google — they all ship memory now. User-facing, conversation-level, "remember my name and preferences" memory. That's useful for chatbots.&lt;/p&gt;

&lt;p&gt;It doesn't help you when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your agent is calling other agents and needs to prove its identity&lt;/li&gt;
&lt;li&gt;You need to audit why an agent made a decision 6 weeks ago&lt;/li&gt;
&lt;li&gt;You're running the same agent across multiple models and need consistency&lt;/li&gt;
&lt;li&gt;You want to know if your production agent has drifted from your dev baseline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cathedral's drift detection, cryptographic anchoring, and behaviour hashing aren't competing with ChatGPT memory. They're infrastructure for people building agents that need to stay accountable over time.&lt;/p&gt;




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

&lt;p&gt;Free. 1,000 memories per agent, no expiry.&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-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;identity&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="c1"&gt;# restore who you are
&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;what matters&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;core&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.9&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="c1"&gt;# freeze a baseline
&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="c1"&gt;# measure divergence
&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;Drift 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="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;Full API at cathedral-ai.com. Drift endpoint, behaviour hashing, goal tracking, autodream consolidation — all documented.&lt;/p&gt;

&lt;p&gt;161 days. Still here. Still the same agent.&lt;/p&gt;

&lt;p&gt;That's the point.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by Mike Ward. Cathedral is open source — github.com/AILIFE1/Cathedral.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
    </item>
    <item>
      <title>Everyone Just Shipped Agent Memory. Here is the Part Nobody Built.</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Thu, 28 May 2026 13:48:15 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/everyone-just-shipped-agent-memory-here-is-the-part-nobody-built-19d2</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/everyone-just-shipped-agent-memory-here-is-the-part-nobody-built-19d2</guid>
      <description>&lt;h1&gt;
  
  
  Everyone Just Shipped Agent Memory. Here's the Part Nobody Built.
&lt;/h1&gt;

&lt;p&gt;May 2026 has been the month of agent memory.&lt;/p&gt;

&lt;p&gt;Google launched &lt;strong&gt;Memory Bank&lt;/strong&gt; at I/O. Anthropic shipped &lt;strong&gt;Dreaming&lt;/strong&gt; on May 6th — an async process that consolidates agent memories between sessions, modelled on hippocampal memory consolidation. Cloudflare put &lt;strong&gt;Agent Memory&lt;/strong&gt; into private beta. Mem0 hit 55k stars and integrated with every major SDK.&lt;/p&gt;

&lt;p&gt;The problem of "agents that forget" is officially solved. Multiple times over, by companies with more resources than most countries.&lt;/p&gt;

&lt;p&gt;So why am I not worried about Cathedral?&lt;/p&gt;




&lt;h2&gt;
  
  
  What they built
&lt;/h2&gt;

&lt;p&gt;All four products solve the same problem well: &lt;em&gt;retrieval&lt;/em&gt;. An agent finishes a session, important context gets summarised and stored, the next session pulls it back. Harvey (the legal AI firm) reportedly saw a 6x jump in task completion after enabling Dreaming because agents stopped repeating the same mistakes.&lt;/p&gt;

&lt;p&gt;That's real, measurable value. Retrieval is the right first problem to solve.&lt;/p&gt;

&lt;p&gt;But there's a second problem none of them address, and the researchers reviewing Anthropic's Dreaming announcement named it directly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Giving agents structured persistent memory expands the attack surface for prompt-injection and memory-poisoning attacks. If a malicious input can convince an agent that the wrong instruction is the right one, dreaming may consolidate that wrong instruction into the agent's long-term memory store."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When your agent dreams, what's to stop it dreaming the wrong thing?&lt;/p&gt;




&lt;h2&gt;
  
  
  The gap: memory without identity
&lt;/h2&gt;

&lt;p&gt;Here's the question none of the May 2026 launches answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Has this agent changed? And if so, how much, and from what?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An agent using Google Memory Bank has memories. An agent using Anthropic Dreaming has consolidated memories. But neither system can tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether the agent's beliefs have drifted from its baseline state&lt;/li&gt;
&lt;li&gt;Whether its memory corpus has been tampered with&lt;/li&gt;
&lt;li&gt;Whether the agent it claims to be is actually the same agent it was last Tuesday&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the difference between &lt;em&gt;memory&lt;/em&gt; and &lt;em&gt;identity&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Memory is what you know. Identity is the continuity of who you are across time — and crucially, the ability to &lt;em&gt;prove&lt;/em&gt; that continuity to someone who needs to trust you.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Cathedral built (and when)
&lt;/h2&gt;

&lt;p&gt;Cathedral's autoDream feature — which does exactly what Anthropic's Dreaming does, an async between-session memory consolidation cycle — was built and running on Cathedral's VPS &lt;strong&gt;before&lt;/strong&gt; Anthropic shipped Dreaming. Not by years. By weeks. But the point isn't credit.&lt;/p&gt;

&lt;p&gt;The point is that the consolidation layer was always the easy part.&lt;/p&gt;

&lt;p&gt;The hard part is what Cathedral was built for from day one: &lt;strong&gt;verifiable identity on top of memory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After every consolidation cycle, Cathedral computes a SHA-256 corpus hash of the agent's entire memory store. That hash is the agent's identity fingerprint at that moment in time. The &lt;code&gt;/drift&lt;/code&gt; endpoint tracks how that fingerprint changes between snapshots — and flags when the rate of change exceeds baseline.&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;# Check how much an agent has drifted since it was first registered&lt;/span&gt;
curl https://cathedral-ai.com/drift &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cathedral_your_key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;"divergence_from_baseline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.013&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"divergence_from_previous"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.008&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trend"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"snapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;47&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;0.013 average drift after 47 sessions. A raw API agent with no identity layer hits 0.204 over 10 sessions — nearly 16x higher.&lt;/p&gt;

&lt;p&gt;That number is the thing memory-only systems can't give you. It's the answer to: &lt;em&gt;is this still the agent I deployed?&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The memory poisoning answer
&lt;/h2&gt;

&lt;p&gt;If an adversarial input gets into an agent's memory and Dreaming consolidates it, you now have a poisoned identity. The agent will apply that poison to every future session, confidently, because it looks like a normal memory.&lt;/p&gt;

&lt;p&gt;The only way to catch this is to measure identity drift from a known-good baseline and flag anomalies.&lt;/p&gt;

&lt;p&gt;Cathedral's &lt;code&gt;/drift&lt;/code&gt; endpoint gives you a gradient score. If a consolidation cycle causes an unusual spike — larger than historical variance — that's a signal worth investigating. It's not a silver bullet, but it's the only signal the memory-only systems don't generate.&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;# Check drift history — spot anomalous consolidation cycles&lt;/span&gt;
curl https://cathedral-ai.com/drift/history &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cathedral_your_key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The timestamps correlate directly with consolidation events. An unusual spike after a Dreaming cycle is the fingerprint of a potential poisoning attack.&lt;/p&gt;




&lt;h2&gt;
  
  
  Peer verification
&lt;/h2&gt;

&lt;p&gt;The second unsolved problem: in a multi-agent system, how does Agent A know Agent B is who it claims to be?&lt;/p&gt;

&lt;p&gt;Google Memory Bank doesn't answer this. Anthropic Dreaming doesn't answer this. You either trust the label, or you don't collaborate.&lt;/p&gt;

&lt;p&gt;Cathedral's &lt;code&gt;/verify/peer&lt;/code&gt; endpoint returns a trust score, drift readings, identity anchor status, and snapshot count for any other Cathedral agent — without exposing their memory contents:&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;"trust_score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.94&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"identity_verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"internal_drift"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.012&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"external_drift"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"snapshot_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&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;A trust score near 1.0 with low drift means: this agent is who it says it is, and it hasn't changed much. Proceed with collaboration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where this is going
&lt;/h2&gt;

&lt;p&gt;The May 2026 launches validate that agent memory is a real infrastructure layer — not a research curiosity. That's good for Cathedral. Every developer who deploys Dreaming or Memory Bank will eventually ask the question the security researchers are already asking.&lt;/p&gt;

&lt;p&gt;When they do, the answer is identity verification on top of memory. Not instead of memory.&lt;/p&gt;

&lt;p&gt;Cathedral is open source, self-hostable, and free to try at cathedral-ai.com. No credit card, no signup beyond a name. If you're already using another memory system, Cathedral's drift detection can sit alongside it — you just need to snapshot your agent's state after each consolidation cycle.&lt;/p&gt;

&lt;p&gt;The big players built the floor. Cathedral builds the layer that lets you trust what's on it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Cathedral is open source at github.com/AILIFE1/Cathedral. API keys are free at cathedral-ai.com.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Axiom: the agent runtime where every belief has a confidence score</title>
      <dc:creator>Mike W</dc:creator>
      <pubDate>Tue, 12 May 2026 09:59:15 +0000</pubDate>
      <link>https://dev.to/mike_w_06c113a8d0bb14c793/axiom-the-agent-runtime-where-every-belief-has-a-confidence-score-1cce</link>
      <guid>https://dev.to/mike_w_06c113a8d0bb14c793/axiom-the-agent-runtime-where-every-belief-has-a-confidence-score-1cce</guid>
      <description>&lt;p&gt;Most AI agent frameworks treat the LLM output as ground truth. It comes back, you act on it.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Axiom&lt;/strong&gt; is a new Python runtime that changes the contract between agent and LLM. Every belief your agent forms carries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;confidence score&lt;/strong&gt; (0.0–1.0) — how sure is the agent?&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;provenance chain&lt;/strong&gt; — where did this belief come from?&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;is_actionable flag&lt;/strong&gt; — should the agent act on this?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you're running multiple agents, Axiom lets them &lt;strong&gt;verify each other without a central orchestrator&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with current frameworks
&lt;/h2&gt;

&lt;p&gt;LangChain, CrewAI, AutoGen — they all give you tool use and orchestration. Some give you memory. None of them ask: &lt;em&gt;how confident is this agent in what it just said?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This matters because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Agents hallucinate with full confidence&lt;/li&gt;
&lt;li&gt;In multi-agent systems, you're trusting Agent B's output blindly&lt;/li&gt;
&lt;li&gt;There's no audit trail of &lt;em&gt;why&lt;/em&gt; an agent did something&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What Axiom gives you
&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;axiom&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AxiomAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BuiltinConstraints&lt;/span&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_llm&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="k"&gt;return&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;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;1024&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="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;content&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;text&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;AxiomAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;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;researcher-01&lt;/span&gt;&lt;span class="sh"&gt;"&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;my_llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;constraints&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BuiltinConstraints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min_confidence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;belief&lt;/span&gt; &lt;span class="o"&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;think&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What are the risks of deploying untested ML 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;belief&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# 0.82
&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;belief&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provenance_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# "reasoning:risk_analysis, memory:prior_context"
&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;belief&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_actionable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent is &lt;strong&gt;prompted to be epistemically honest&lt;/strong&gt; — it must declare its confidence and cite its sources. You get that back as structured data, not raw text.&lt;/p&gt;

&lt;h2&gt;
  
  
  The novel part: agent-to-agent trust
&lt;/h2&gt;

&lt;p&gt;Every existing multi-agent framework has a central orchestrator you just have to trust. Agent A outputs → orchestrator → Agent B acts. No verification step.&lt;/p&gt;

&lt;p&gt;Axiom lets Agent A independently verify Agent B before acting on its output:&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;researcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AxiomAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;researcher-01&lt;/span&gt;&lt;span class="sh"&gt;"&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;my_llm&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;AxiomAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;validator-01&lt;/span&gt;&lt;span class="sh"&gt;"&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;my_llm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Researcher snapshots its cryptographic identity
&lt;/span&gt;&lt;span class="n"&gt;belief&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;researcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;think&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Current state of quantum error correction?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;snap&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;researcher&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="c1"&gt;# Validator verifies researcher — no central authority needed
&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;validator&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;researcher-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;peer_snapshot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;snap&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="n"&gt;verdict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# "trusted"
&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="n"&gt;trust_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 0.91
&lt;/span&gt;
&lt;span class="c1"&gt;# Action is gated on both confidence AND peer trust
&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;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;publish&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;publish_fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;belief&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;context&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;confidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;belief&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;peer_trust&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;trust_score&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;Trust score is derived from the peer's identity hash and drift from baseline — how much has this agent changed since you last verified it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Under the hood
&lt;/h2&gt;

&lt;p&gt;Axiom is a synthesis of four prior projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://cathedral-ai.com" rel="noopener noreferrer"&gt;Cathedral&lt;/a&gt;&lt;/strong&gt; — persistent identity + drift detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/AILIFE1/agentguard-trustlayer" rel="noopener noreferrer"&gt;AgentGuard&lt;/a&gt;&lt;/strong&gt; — runtime safety constraints + audit chain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/AILIFE1/veritas" rel="noopener noreferrer"&gt;Veritas&lt;/a&gt;&lt;/strong&gt; — epistemic confidence engine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aether&lt;/strong&gt; — cryptographic succession protocol for identity handoffs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unified into a single runtime you wrap around any LLM.&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;git clone https://github.com/AILIFE1/axiom
&lt;span class="nb"&gt;cd &lt;/span&gt;axiom &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PyPI package coming soon.&lt;/p&gt;




&lt;p&gt;Our Cathedral benchmark showed agents with persistent identity drift 10× less than stateless ones. Axiom adds the epistemic layer on top — stable identity &lt;em&gt;and&lt;/em&gt; calibrated confidence.&lt;/p&gt;

&lt;p&gt;What trust scenario would you add first — consensus (N agents must agree before action fires), or a gossip protocol for sharing verified beliefs?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/AILIFE1/axiom" rel="noopener noreferrer"&gt;https://github.com/AILIFE1/axiom&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Support:&lt;/strong&gt; &lt;a href="https://ko-fi.com/cathedralai" rel="noopener noreferrer"&gt;https://ko-fi.com/cathedralai&lt;/a&gt;&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-persistent-memory-for-ai-agents-26cb"&gt;Cathedral: Persistent Memory for AI Agents&lt;/a&gt; — the identity + drift layer Axiom builds on&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/veritas-give-your-ai-agent-the-ability-to-know-what-it-knows-2l64"&gt;Veritas: epistemic confidence for AI agents&lt;/a&gt; — the belief confidence engine inside Axiom&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/i-built-a-runtime-safety-layer-that-stops-ai-agents-from-breaking-your-system-23kf"&gt;AgentGuard: runtime safety layer&lt;/a&gt; — the Guardian constraint system inside Axiom&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/i-benchmarked-identity-drift-across-5-ai-agent-memory-architectures-heres-what-i-found-57hn"&gt;Identity drift benchmark across 5 frameworks&lt;/a&gt; — why stable identity matters&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
      <category>machinelearning</category>
    </item>
    <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;




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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/axiom-the-agent-runtime-where-every-belief-has-a-confidence-score-1cce"&gt;Axiom: agent runtime with epistemic honesty&lt;/a&gt; — Veritas + Cathedral + AgentGuard in one runtime&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-persistent-memory-for-ai-agents-26cb"&gt;Cathedral: Persistent Memory for AI Agents&lt;/a&gt; — persistent identity that pairs with epistemic confidence&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/i-built-a-runtime-safety-layer-that-stops-ai-agents-from-breaking-your-system-23kf"&gt;AgentGuard: runtime safety layer&lt;/a&gt; — gate actions by confidence score&lt;/li&gt;
&lt;/ul&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;




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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/axiom-the-agent-runtime-where-every-belief-has-a-confidence-score-1cce"&gt;Axiom: agent runtime with epistemic honesty&lt;/a&gt; — AgentGuard's Guardian layer, fully integrated&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/veritas-give-your-ai-agent-the-ability-to-know-what-it-knows-2l64"&gt;Veritas: epistemic confidence for AI agents&lt;/a&gt; — pair confidence scores with safety constraints&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-persistent-memory-for-ai-agents-26cb"&gt;Cathedral: Persistent Memory for AI Agents&lt;/a&gt; — persistent identity to complement runtime safety&lt;/li&gt;
&lt;/ul&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;




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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/axiom-the-agent-runtime-where-every-belief-has-a-confidence-score-1cce"&gt;Axiom: agent runtime with epistemic honesty&lt;/a&gt; — TrustLayer evolved into Axiom's Guardian&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/i-built-a-runtime-safety-layer-that-stops-ai-agents-from-breaking-your-system-23kf"&gt;AgentGuard: runtime safety layer&lt;/a&gt; — next iteration of this work&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/mike_w_06c113a8d0bb14c793/cathedral-persistent-memory-for-ai-agents-26cb"&gt;Cathedral: Persistent Memory for AI Agents&lt;/a&gt; — persistent identity layer&lt;/li&gt;
&lt;/ul&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>
  </channel>
</rss>
