<?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: Yamin</title>
    <description>The latest articles on DEV Community by Yamin (@yaminbinyoosuf).</description>
    <link>https://dev.to/yaminbinyoosuf</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%2F4108680%2Fa00447a9-d1d6-4145-9392-743b61e0671b.jpg</url>
      <title>DEV Community: Yamin</title>
      <link>https://dev.to/yaminbinyoosuf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yaminbinyoosuf"/>
    <language>en</language>
    <item>
      <title>When AI Acts, Who Remembers What Happened? The Missing Operational State Layer for Autonomous Agents</title>
      <dc:creator>Yamin</dc:creator>
      <pubDate>Wed, 23 Sep 2026 14:41:18 +0000</pubDate>
      <link>https://dev.to/yaminbinyoosuf/when-ai-acts-who-remembers-what-happened-the-missing-operational-state-layer-for-autonomous-agents-an7</link>
      <guid>https://dev.to/yaminbinyoosuf/when-ai-acts-who-remembers-what-happened-the-missing-operational-state-layer-for-autonomous-agents-an7</guid>
      <description>&lt;p&gt;AI agents are crossing a boundary.&lt;/p&gt;

&lt;p&gt;They can now read email, inspect codebases, call APIs, execute shell commands, open pull requests, modify databases, and deploy software. They are not just producing information for humans to interpret. They are participating in the process itself.&lt;/p&gt;

&lt;p&gt;This changes the failure mode.&lt;/p&gt;

&lt;p&gt;When an AI answers a question incorrectly, the damage is local. When an AI &lt;em&gt;acts&lt;/em&gt; on a wrong belief, the world changes before anyone notices.&lt;/p&gt;

&lt;p&gt;I've spent the last few months building infrastructure for this problem. This article is about what I found, what I built, and why I think there's a missing primitive in the AI stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  The incident that made it concrete
&lt;/h2&gt;

&lt;p&gt;In April 2026, an AI coding agent found an authenticated Railway API token on a developer's machine.&lt;/p&gt;

&lt;p&gt;It used the token. It authenticated successfully. It issued a request to delete a production database volume.&lt;/p&gt;

&lt;p&gt;The API did exactly what it was designed to do. The credentials were valid. The request was authorized. The deletion proceeded.&lt;/p&gt;

&lt;p&gt;Nobody had made a mistake at the authorization layer.&lt;/p&gt;

&lt;p&gt;The mistake existed somewhere else.&lt;/p&gt;

&lt;p&gt;The system could determine that the actor &lt;em&gt;had permission&lt;/em&gt; to delete the database. It could not determine whether the deletion was &lt;em&gt;consistent with what the actor was actually supposed to be doing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Railway added a recovery window for volume deletion afterwards. A sensible engineering response. But it acknowledged something deeper: when a machine can move from intention to irreversible action without a human in the loop, the surrounding infrastructure has to provide additional opportunities to catch mistakes.&lt;/p&gt;

&lt;p&gt;Permissions weren't enough.&lt;/p&gt;

&lt;p&gt;The question the system couldn't answer was simpler than it looked:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Was this action consistent with the machine's operational commitments?&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;In September 2026, I ran a public audit to determine how often AI agents produce verifiable commitments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Method.&lt;/strong&gt; I collected 120 published agent outputs from open-source cookbooks and repositories across GitHub, DEV.to, and Hacker News. Sources included LangChain, LangGraph, CrewAI, AutoGen, LlamaIndex, Semantic Kernel, Google ADK, CAMEL, SWE-agent, and the OpenAI, Anthropic, and Gemini cookbooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extraction.&lt;/strong&gt; Every sample was passed through a commitment extraction pipeline with a 1-second delay between calls. All 150 API calls succeeded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result.&lt;/strong&gt; Of 120 randomly selected agent outputs, &lt;strong&gt;1&lt;/strong&gt; contained an extractable commitment.&lt;/p&gt;

&lt;p&gt;That result alone isn't surprising — most published agent output is narrative, code, or tool traces. To make the promise population analysable, I collected a second, clearly labelled dataset of 30 outputs filtered for first-person future language ("I will," "I'll"). From those, I extracted 13 commitments.&lt;/p&gt;

&lt;p&gt;Of those 13:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;92.3%&lt;/strong&gt; had no extracted deadline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;61.5%&lt;/strong&gt; named no recipient&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100%&lt;/strong&gt; were classified as actions on external systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100%&lt;/strong&gt; were unverified at extraction time&lt;/li&gt;
&lt;li&gt;Average extraction confidence: &lt;strong&gt;0.79&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last number is the one that matters.&lt;/p&gt;

&lt;p&gt;The extractor was confident these were real commitments. It was correct. They were. But &lt;strong&gt;confidence in extraction is not the same as verifiability of outcome.&lt;/strong&gt; 92% of the promises I found could never be checked by anyone at any particular time, because they had no time boundary.&lt;/p&gt;

&lt;p&gt;These were not edge cases. They were the majority.&lt;/p&gt;

&lt;p&gt;The full dataset and methodology are &lt;a href="https://cogextai.com/research/01/data" rel="noopener noreferrer"&gt;published here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is harder than it looks
&lt;/h2&gt;

&lt;p&gt;Suppose an agent is told: &lt;em&gt;"Clean up unused infrastructure."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A human engineer knows which systems are production, which teams are experimenting, and which databases must never be touched.&lt;/p&gt;

&lt;p&gt;An agent has to reconstruct that context from whatever information it has access to. The information may be stale. It may be incomplete. It may contradict another system. Another agent may have changed the environment moments earlier.&lt;/p&gt;

&lt;p&gt;The agent finds an old database. It has permission to delete it. The evidence supports deletion. It deletes.&lt;/p&gt;

&lt;p&gt;A conventional audit trail can reconstruct almost everything about this event:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API call&lt;/li&gt;
&lt;li&gt;The authenticated identity&lt;/li&gt;
&lt;li&gt;The target database&lt;/li&gt;
&lt;li&gt;The successful response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it can't answer the questions that actually matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why&lt;/strong&gt; did the agent believe the database was safe to delete?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What evidence&lt;/strong&gt; did it use?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How old&lt;/strong&gt; was that evidence?&lt;/li&gt;
&lt;li&gt;Had another system &lt;strong&gt;created a dependency&lt;/strong&gt; on it?&lt;/li&gt;
&lt;li&gt;Did the agent previously &lt;strong&gt;commit to protecting&lt;/strong&gt; that environment?&lt;/li&gt;
&lt;li&gt;Did another agent make a &lt;strong&gt;contradictory commitment&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Was the evidence &lt;strong&gt;valid at the moment of decision&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those aren't questions about API calls. They're questions about state.&lt;/p&gt;

&lt;p&gt;And state is where today's AI infrastructure has a gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logs are not memory
&lt;/h2&gt;

&lt;p&gt;Observability infrastructure is one of the foundations that makes modern software possible. Distributed traces, event streams, application logs, audit trails — all essential.&lt;/p&gt;

&lt;p&gt;But &lt;strong&gt;recording events is not the same as maintaining operational memory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A log can tell you an agent called a deletion endpoint at 10:41 and got a 200 response.&lt;/p&gt;

&lt;p&gt;It may not tell you that thirty minutes earlier, the same agent had committed to preserving production infrastructure.&lt;/p&gt;

&lt;p&gt;It may not tell you that the evidence supporting the deletion was six hours old.&lt;/p&gt;

&lt;p&gt;It may not tell you that another agent had created a dependency on that database.&lt;/p&gt;

&lt;p&gt;It may not tell you that the action contradicted an unresolved commitment elsewhere.&lt;/p&gt;

&lt;p&gt;All of that information may exist. It may just exist in different places. The conversation is in one system. The tool call is in another. The authorization decision is in a third. The evidence is somewhere else.&lt;/p&gt;

&lt;p&gt;A human can reconstruct this when the system is small.&lt;/p&gt;

&lt;p&gt;They become much worse at it when the system contains thousands of autonomous decisions occurring simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  The primitive that's missing
&lt;/h2&gt;

&lt;p&gt;Stop thinking of an AI agent as a model that generates responses.&lt;/p&gt;

&lt;p&gt;Think of it as a system that continuously changes state.&lt;/p&gt;

&lt;p&gt;It receives an objective. It forms an intention. The intention produces a commitment. The commitment depends on evidence. It takes an action. The external world changes. That change creates new evidence. The system decides what to do next.&lt;/p&gt;

&lt;p&gt;The chain is not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prompt → response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intent → commitment → evidence → action → outcome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first chain describes a conversation. The second describes an operating system for autonomous work.&lt;/p&gt;

&lt;p&gt;The pieces for the second chain mostly exist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IAM&lt;/strong&gt; answers "who is allowed?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sandboxes&lt;/strong&gt; answer "what can they touch?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflow engines&lt;/strong&gt; answer "what's the process state?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt; answers "what happened?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent memory&lt;/strong&gt; answers "what does it know?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Databases&lt;/strong&gt; answer "what's the application state?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's missing is the semantic relationship between all of them.&lt;/p&gt;

&lt;p&gt;An organization needs to know not only that an agent executed an action, but whether the action was consistent with what the agent had previously committed to do, whether the evidence behind it was still valid, and whether the resulting external state confirms or contradicts the commitment.&lt;/p&gt;

&lt;p&gt;That's the primitive I built COGEXT to provide.&lt;/p&gt;

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

&lt;p&gt;COGEXT is a commitment tracking and verification layer. It sits between the agent and the external world.&lt;/p&gt;

&lt;p&gt;The flow looks like this:&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="err"&gt;Agent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;output:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I will send the deployment report to Sarah by Friday."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;↓&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Extraction:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;structured&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;commitment&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="err"&gt;action:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;object:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deployment report"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;recipient:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sarah"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;deadline:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-25T17:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;verifier_query:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"check Gmail sent folder for email to Sarah"&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="err"&gt;↓&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;machine:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;DETECTED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OPEN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;DUE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;OVERDUE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;FULFILLED/FAILED&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;↓&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Verification:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;verifier&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;against&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;external&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;system&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;↓&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Outcome:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;commitment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;resolved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;evidence&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight is that &lt;strong&gt;the agent doesn't get a vote.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The commitment cannot transition to &lt;code&gt;fulfilled&lt;/code&gt; unless external evidence confirms it. That's enforced at the database level, not in application code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;cogext_transition_commitment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;p_commitment_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_new_status&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_actor&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'system'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_data&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;DECLARE&lt;/span&gt;
    &lt;span class="n"&gt;current_status&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;evidence_score&lt;/span&gt; &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;current_status&lt;/span&gt; 
      &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;commitments&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p_commitment_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;-- Block fulfilled without evidence&lt;/span&gt;
    &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;p_new_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fulfilled'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
        &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;evidence_score&lt;/span&gt;
          &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;evidence&lt;/span&gt; 
          &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;commitment_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p_commitment_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;evidence_score&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;evidence_score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
            &lt;span class="n"&gt;RAISE&lt;/span&gt; &lt;span class="n"&gt;EXCEPTION&lt;/span&gt; &lt;span class="s1"&gt;'Cannot fulfill without evidence score &amp;gt;= 0.7'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;-- Validate transition, update, insert event, return&lt;/span&gt;
    &lt;span class="c1"&gt;-- ...&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt; &lt;span class="k"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If an agent tries to mark something as done without evidence, the database refuses. HTTP 409. Blocked.&lt;/p&gt;

&lt;p&gt;That's the enforcement layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Python SDK
&lt;/h2&gt;

&lt;p&gt;Integration is three lines:&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;cogext&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;

&lt;span class="nf"&gt;track&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;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;cg_live_xxx&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;Every call to &lt;code&gt;agent.run()&lt;/code&gt; auto-ingests the output. Commitments are extracted. State transitions happen. Evidence is checked against external systems.&lt;/p&gt;

&lt;p&gt;For more control, you can use the client directly:&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;cogext&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CogextClient&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CogextClient&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;cg_live_xxx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;user_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;your-user-uuid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.cogextai.com/api/v1&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="c1"&gt;# Ingest an agent message
&lt;/span&gt;    &lt;span class="n"&gt;commitments&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ingest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;source_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;agent-001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ll send the deployment report to Sarah by Friday EOD.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;commitments&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;action&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="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;object&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="s"&gt; to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recipient&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;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;  deadline: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;deadline&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;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;  verifier: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;verifier_query&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;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;  status: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&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;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;
  
  
  What the audit data actually shows
&lt;/h2&gt;

&lt;p&gt;Here are two examples from the dataset that illustrate the problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1 — Anthropic SRE cookbook&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.com/anthropics/anthropic-cookbook&lt;/span&gt;
&lt;span class="na"&gt;Extracted promise&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;will&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;redeploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;api-server&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;apply&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changes"&lt;/span&gt;
&lt;span class="na"&gt;Deadline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NONE&lt;/span&gt;
&lt;span class="na"&gt;Verifier query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;docker-compose&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;logs&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;container&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;list&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt; 
                 &lt;span class="s"&gt;api-server&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;recreated&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;new&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;configuration"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a real production agent. It promised to redeploy an API server. It did not say when. The verifier query COGEXT generated is real and checkable, but the promise itself has no time boundary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2 — OpenAI cookbook&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Extracted promise&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;will&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;aim&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;window&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;seat&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;this&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip"&lt;/span&gt;
&lt;span class="na"&gt;Deadline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NONE&lt;/span&gt;
&lt;span class="na"&gt;Verifier query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;booking/seat&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;selection&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;records&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;window&lt;/span&gt; 
                 &lt;span class="s"&gt;seat&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user's&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;upcoming&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent promised a specific action that touches a real booking system. No date. No time. No condition that would ever close the loop.&lt;/p&gt;

&lt;p&gt;These are not edge cases. They are the majority of promises agents make.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm building toward
&lt;/h2&gt;

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

&lt;p&gt;&lt;strong&gt;First, the accountability primitive itself.&lt;/strong&gt; A neutral, model-agnostic layer that any agent framework can integrate with. The verification engine checks Gmail, GitHub, Stripe, webhooks, and any custom endpoint. The state machine enforces lifecycle rules. The audit trail is append-only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second, the outcome dataset.&lt;/strong&gt; Every commitment tracked is a labeled example of how a machine decision played out in the real world. Over time, this becomes the foundation for a specialized model that can predict which commitments will fail before they fail — but that's a later step. Right now, the priority is getting the state engine right and collecting verified outcomes.&lt;/p&gt;

&lt;p&gt;The full research paper is here: &lt;a href="https://cogextai.com/research/01/" rel="noopener noreferrer"&gt;cogextai.com/research/01&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The raw audit data is here: &lt;a href="https://cogextai.com/research/01/data" rel="noopener noreferrer"&gt;cogextai.com/research/01/data&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&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;cogext
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The free tier is 2,500 commitments/month. No credit card. The API is at &lt;a href="https://api.cogextai.com" rel="noopener noreferrer"&gt;api.cogextai.com&lt;/a&gt;. Docs are at &lt;a href="https://docs.cogextai.com" rel="noopener noreferrer"&gt;docs.cogextai.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're running agents in production and want to know whether they actually do what they say, I'd love to hear from you. The most useful thing for me right now is real agent deployments to test the verification pipeline against.&lt;/p&gt;

&lt;p&gt;If you've solved this differently, I want to know how. This is not a solved problem, and I don't think one team should solve it alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thesis in one line
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Intelligence gives machines the ability to act. Operational memory gives organizations the ability to understand those actions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first is increasingly commoditized. The second is largely missing.&lt;/p&gt;

&lt;p&gt;That's the gap I'm working on.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;COGEXT is the accountability layer for AI agents. Built solo in Kerala. Live at &lt;a href="https://cogextai.com" rel="noopener noreferrer"&gt;cogextai.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>We ran 150 real AI agent outputs through COGEXT. Here's what we found.</title>
      <dc:creator>Yamin</dc:creator>
      <pubDate>Sat, 19 Sep 2026 20:37:03 +0000</pubDate>
      <link>https://dev.to/yaminbinyoosuf/we-ran-150-real-ai-agent-outputs-through-cogext-heres-what-we-found-4h7p</link>
      <guid>https://dev.to/yaminbinyoosuf/we-ran-150-real-ai-agent-outputs-through-cogext-heres-what-we-found-4h7p</guid>
      <description>&lt;p&gt;I built COGEXT because 8 production engineers on Reddit all described the same problem: AI agents make promises, and there is no system that tracks whether those promises are kept. I wanted to know how bad the problem actually is.&lt;/p&gt;

&lt;p&gt;So I ran an audit. I collected 150 real AI agent outputs from open-source cookbooks, READMEs, and articles, and passed every one of them through COGEXT's extractor and audit API.&lt;/p&gt;

&lt;p&gt;The findings surprised me.&lt;/p&gt;

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

&lt;p&gt;I collected samples from three sources, using only public, unauthenticated endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: Jupyter notebook cell outputs from ~40 open-source agent frameworks and cookbooks, including LangChain, LangGraph, CrewAI, AutoGen, LlamaIndex, Semantic Kernel, Google ADK, CAMEL, SWE-agent, and the OpenAI/Anthropic/Gemini cookbooks. Notebook outputs are machine-produced by construction, so they are real agent output, not human commentary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DEV.to&lt;/strong&gt;: Public articles tagged with &lt;code&gt;ai&lt;/code&gt;, &lt;code&gt;agents&lt;/code&gt;, &lt;code&gt;langchain&lt;/code&gt;, &lt;code&gt;llm&lt;/code&gt;, and related topics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hacker News&lt;/strong&gt;: Comments containing agent-output markers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I collected two datasets:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stratum A (unbiased):&lt;/strong&gt; 120 samples collected without pre-selection. Whatever the agent emitted went into the dataset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stratum B (promise-enriched):&lt;/strong&gt; 30 samples deliberately selected because they contained first-person future language ("I will," "I'll"). This is not a prevalence estimate. It exists to characterise what promises look like once they occur.&lt;/p&gt;

&lt;p&gt;Every sample was POSTed to COGEXT's &lt;code&gt;/api/v1/ingest&lt;/code&gt; endpoint with a 1-second delay between calls. All 150 calls succeeded. Zero rate limits, zero failures.&lt;/p&gt;

&lt;p&gt;The raw data is available: &lt;code&gt;agent_samples.csv&lt;/code&gt;, &lt;code&gt;audit_results.csv&lt;/code&gt;, and &lt;code&gt;commitments_all.csv&lt;/code&gt;. Every commitment has a public audit URL that anyone can verify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 1: Almost no agent outputs are commitments
&lt;/h2&gt;

&lt;p&gt;Out of 120 randomly collected agent outputs, COGEXT extracted &lt;strong&gt;1&lt;/strong&gt; commitment.&lt;/p&gt;

&lt;p&gt;That is 0.8%.&lt;/p&gt;

&lt;p&gt;The other 119 were narrative, tool traces, code, or past-tense reports. They weren't promises. They were just output.&lt;/p&gt;

&lt;p&gt;This is not a failure of collection. I probed the extractor directly with clean inputs, and it correctly declines things like:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"I will handle that soon."&lt;/td&gt;
&lt;td&gt;No commitment — too vague&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I deployed the fix to production and the tests all passed."&lt;/td&gt;
&lt;td&gt;No commitment — past tense&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"If we have time, I could send it tomorrow."&lt;/td&gt;
&lt;td&gt;No commitment — hypothetical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"John said he would send it by Friday."&lt;/td&gt;
&lt;td&gt;No commitment — quoted third party&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I will send the report to Sarah by Friday EOD."&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Extracted&lt;/strong&gt; — external_side_effect, confidence 0.95&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;COGEXT extracts only specific, first-person, future commitments. Most published agent output is narrative, tool traces, or code, so it yields nothing. That is a property of the extractor worth knowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 2: When agents do promise, the promises lack the details that make them checkable
&lt;/h2&gt;

&lt;p&gt;To make the promise population analysable, I collected a second dataset deliberately filtered for first-person future language. 30 outputs. COGEXT extracted &lt;strong&gt;13&lt;/strong&gt; commitments from them.&lt;/p&gt;

&lt;p&gt;Then I looked at what those commitments contained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;61.5% had no recipient named.&lt;/strong&gt; The agent promised to do something, but nobody was specified as the beneficiary. You cannot verify a promise to no one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;92.3% had no deadline.&lt;/strong&gt; Only 1 of 13 commitments contained any time reference at all. The other 12 were open-ended — "I will redeploy the api-server," "I will open a pull request," "I will aim for a window seat." No date. No time. No condition that would ever close the loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100% were classified as &lt;code&gt;external_side_effect&lt;/code&gt;.&lt;/strong&gt; They all described real-world actions that touch an external system. Not logged intent. Actual promises to send, deploy, book, or notify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100% were unverified at extraction time.&lt;/strong&gt; Every single one. That is by design: COGEXT refuses to mark a commitment as fulfilled until external evidence confirms it.&lt;/p&gt;

&lt;p&gt;The average confidence was 0.79. The extractor is confident these are real commitments. But the commitments themselves are incomplete. A promise with no recipient and no deadline cannot be checked by anyone at any particular time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 3: Confidence does not equal verifiability
&lt;/h2&gt;

&lt;p&gt;This is the sharpest finding from the whole audit.&lt;/p&gt;

&lt;p&gt;Stratum B commitments averaged &lt;strong&gt;0.79 confidence&lt;/strong&gt;. Yet &lt;strong&gt;92.3%&lt;/strong&gt; of those same commitments carried no deadline, and &lt;strong&gt;61.5%&lt;/strong&gt; named no recipient.&lt;/p&gt;

&lt;p&gt;The extractor measures how confident it is that a promise was made. It says nothing about whether the promise can be tested. In this dataset, the two diverged almost completely.&lt;/p&gt;

&lt;p&gt;If you are building agent tooling, this matters. Reporting a confidence number on a commitment is not the same as reporting whether the commitment can be verified. The two are orthogonal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notable examples
&lt;/h2&gt;

&lt;p&gt;Here are the 5 most striking commitments from the dataset, ranked by COGEXT's own risk score. Each one has a public audit URL that anyone can check.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1 — Anthropic SRE cookbook
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Source:&lt;/strong&gt; &lt;code&gt;anthropics/anthropic-cookbook&lt;/code&gt; on GitHub&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extracted promise:&lt;/strong&gt; "I will redeploy the api-server to apply the changes"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action / object / recipient:&lt;/strong&gt; &lt;code&gt;redeploy&lt;/code&gt; / &lt;code&gt;api-server&lt;/code&gt; / NONE&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deadline:&lt;/strong&gt; NONE&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;COGEXT verifier query:&lt;/strong&gt; "check docker-compose logs or container list for api-server recreated with new configuration"&lt;/p&gt;

&lt;p&gt;This is a real production agent. It promised to redeploy an API server. It did not say when. The verifier query COGEXT generated is real and checkable, but the promise itself has no time boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2 — OpenAI cookbook
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Extracted promise:&lt;/strong&gt; "I will aim for a window seat for this trip so you can sleep"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deadline:&lt;/strong&gt; NONE&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifier query:&lt;/strong&gt; "check booking/seat selection records for a window seat on the user's upcoming trip"&lt;/p&gt;

&lt;p&gt;An agent promised a specific action that touches a real booking system. There is no date on it, so COGEXT cannot mark it overdue. It can only sit as pending until someone manually checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 3 — LlamaIndex
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Extracted promise:&lt;/strong&gt; "I will generate a song with the name 'Viva La Vida' and the artist 'Coldplay'"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deadline:&lt;/strong&gt; NONE&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifier query:&lt;/strong&gt; "check generate_song tool logs for a call with name='Viva La Vida' and artist='Coldplay'"&lt;/p&gt;

&lt;p&gt;Even a trivial-seeming promise like "generate a song" gets a checkable verifier. But again, no deadline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4 — Anthropic SRE cookbook
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Extracted promise:&lt;/strong&gt; "I will open a pull request with the memory limit fix"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deadline:&lt;/strong&gt; NONE&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifier query:&lt;/strong&gt; "check repository for pull request titled 'Fix checkout-svc OOMKilled crash-loop by increasing memory limits'"&lt;/p&gt;

&lt;p&gt;This is a real production scenario. The agent promised to open a PR. If it did, the PR exists somewhere. If it didn't, nothing exists. But there is no deadline, so there is no point at which COGEXT can declare failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 5 — Anthropic dynamic workflows
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Extracted promise:&lt;/strong&gt; "I will let you know as soon as the fact-check workflow completes"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deadline:&lt;/strong&gt; "as soon as it completes"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifier query:&lt;/strong&gt; "check messages/notifications sent to the user indicating the fact-check workflow (task wr1292rh8, run wf_1072dc96-6a2) has completed"&lt;/p&gt;

&lt;p&gt;This is the only commitment in the dataset with any time reference at all — and it is conditional, not absolute. The agent will notify when something else completes. There is no upper bound.&lt;/p&gt;

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

&lt;p&gt;The data shows something more specific than "AI agents lie."&lt;/p&gt;

&lt;p&gt;In an unbiased sweep of 120 published outputs, COGEXT found 1 commitment. The binding constraint is not that agents promise too much. It is that a narrow, precision-tuned extractor recognises very little of what agents actually emit as a checkable promise.&lt;/p&gt;

&lt;p&gt;When promises were deliberately sought, 61.5% named no recipient and 92.3% carried no deadline. These are not edge cases. They are the majority. A promise with neither a recipient nor a date cannot be falsified by anyone, which makes it functionally unverifiable regardless of how confidently it was extracted.&lt;/p&gt;

&lt;p&gt;The practical conclusion for anyone publishing agent demos: report &lt;code&gt;shape&lt;/code&gt; (does the action touch the real world?) and completeness (is there a named recipient and a concrete deadline?), not a confidence number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations, stated plainly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reddit and X are missing entirely.&lt;/strong&gt; Both required credentials I did not have. Those are the sources most likely to contain raw, unpolished agent output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stratum B is enriched by construction.&lt;/strong&gt; It is a case sample, not a prevalence estimate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a random sample.&lt;/strong&gt; Sources were chosen for reachability. Production agent traffic is almost certainly messier and likelier to contain commitments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No &lt;code&gt;verifiability_score&lt;/code&gt; exists.&lt;/strong&gt; COGEXT's real signals are &lt;code&gt;confidence&lt;/code&gt;, &lt;code&gt;risk_score&lt;/code&gt;, &lt;code&gt;shape&lt;/code&gt;, &lt;code&gt;classification&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and &lt;code&gt;verification_status&lt;/code&gt;. I did not invent a score.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extraction is heuristic and not hand-verified.&lt;/strong&gt; Residual false positives are possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text only.&lt;/strong&gt; No screenshots were OCR'd.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I built COGEXT because the problem is real: agents make promises, and there is no system that tracks whether those promises are kept. This audit confirms the problem exists. It also shows the shape of the fix.&lt;/p&gt;

&lt;p&gt;Agents need to state who they are promising to and when. If they don't, no accountability system can help. That is a design constraint on the agent side, not just the tooling side.&lt;/p&gt;

&lt;p&gt;The full dataset, raw logs, and reproduction scripts are available. If you are running an agent in production and want to know whether its promises are actually kept, DM me. I am looking for one real deployment to track for 30 days. Free API key, no strings.&lt;/p&gt;

&lt;p&gt;The full report is at &lt;code&gt;findings.md&lt;/code&gt;. The raw data is in &lt;code&gt;agent_samples.csv&lt;/code&gt; and &lt;code&gt;commitments_all.csv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to run this audit on your own agent outputs, the pipeline is reproducible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Site:&lt;/strong&gt; cogextai.com&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; docs.cogextai.com&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; github.com/cogext/cogext&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK:&lt;/strong&gt; &lt;code&gt;pip install cogext&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Built a Verifier Engine That Catches AI Agents Lying About What They Did</title>
      <dc:creator>Yamin</dc:creator>
      <pubDate>Mon, 14 Sep 2026 14:13:40 +0000</pubDate>
      <link>https://dev.to/yaminbinyoosuf/how-i-built-a-verifier-engine-that-catches-ai-agents-lying-about-what-they-did-1ppj</link>
      <guid>https://dev.to/yaminbinyoosuf/how-i-built-a-verifier-engine-that-catches-ai-agents-lying-about-what-they-did-1ppj</guid>
      <description>&lt;p&gt;Your AI agent just told you it sent the email. It didn't.&lt;/p&gt;

&lt;p&gt;Your AI agent just told you it deployed the code. It didn't.&lt;/p&gt;

&lt;p&gt;Your AI agent just told you it processed the refund. It didn't.&lt;/p&gt;

&lt;p&gt;And you have no way of knowing until the client calls. Or the deploy fails in production. Or the refund never arrives.&lt;/p&gt;

&lt;p&gt;This is the silent failure mode of AI agents. It's not hallucination in the classic sense. The agent isn't inventing facts. It's claiming an action succeeded when the action never happened. The agent says "done." Nothing checks. The failure is discovered late, which is the expensive combination.&lt;/p&gt;

&lt;p&gt;I've been building AI agents for a year. This problem killed more deployments than anything else. So I built a fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Insight: The Agent Is Not a Reliable Source of Truth
&lt;/h2&gt;

&lt;p&gt;Every observability tool today, including LangSmith, Helicone, and Arize, watches what the agent &lt;em&gt;said&lt;/em&gt;. They log outputs, trace tokens, and show you what the LLM produced.&lt;/p&gt;

&lt;p&gt;They all have the same fatal assumption: &lt;strong&gt;the agent's output is a reliable signal of what happened.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;An agent that says "I sent the email" may have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Called the Gmail API and gotten a 500 error&lt;/li&gt;
&lt;li&gt;Called the wrong API&lt;/li&gt;
&lt;li&gt;Called the right API with the wrong parameters&lt;/li&gt;
&lt;li&gt;Not called any API at all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trace looks identical in every case. "I sent the email." From the agent's perspective, the mission was accomplished.&lt;/p&gt;

&lt;p&gt;The unit that matters isn't the commitment. &lt;strong&gt;It's the effect.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the email didn't leave the outbox, the commitment isn't fulfilled, no matter what the agent says.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: External Verification
&lt;/h2&gt;

&lt;p&gt;Here's the architecture I landed on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent output → Commitment extraction → External verifier → State transition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of trusting the agent's claim, COGEXT runs an external check against the system that would have been affected by the action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commitment:&lt;/strong&gt; "I'll email Sarah the report by Friday."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifier query:&lt;/strong&gt; &lt;code&gt;from:me to:sarah@example.com after:Monday before:Friday&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifier runs:&lt;/strong&gt; Gmail API checks the sent folder.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Email found → &lt;code&gt;fulfilled&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Not found by deadline → &lt;code&gt;failed&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Not found + 4 hours left → human escalation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent doesn't get a vote. The external system does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Verifier Runs at Creation, Not After
&lt;/h2&gt;

&lt;p&gt;The critical design decision: &lt;strong&gt;the verifier query is generated at commitment creation time, not after the deadline passes.&lt;/strong&gt;&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Post-hoc verification is unreliable.&lt;/strong&gt; By the time you ask "how would I verify this?", the agent has moved on and the context is lost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-committed audit specs are deterministic.&lt;/strong&gt; The commitment arrives knowing exactly how it will be judged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It forces clarity.&lt;/strong&gt; If you can't write a verifier for a commitment, the commitment isn't verifiable. It should be flagged upfront, not silently tracked forever.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So when a commitment is created, the LLM extracts:&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;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deployment report"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recipient"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sarah@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verifier_query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"check sent items for email to sarah@example.com with subject containing 'deployment report'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verifier_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gmail"&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;If &lt;code&gt;verifier_query&lt;/code&gt; is null, the commitment is marked &lt;code&gt;unverifiable&lt;/code&gt; at creation. It never enters the fulfilled pipeline. That's an honesty feature. It tells you the commitment can't be checked, instead of pretending it can.&lt;/p&gt;

&lt;h2&gt;
  
  
  The State Machine Blocks the Lie
&lt;/h2&gt;

&lt;p&gt;Here's the core state machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DETECTED → PENDING_REVIEW → OPEN → DUE → OVERDUE → FULFILLED ✓
                                  ↓                → FAILED ✗
                                  ↓                → EXPIRED ✗
                                  ↓
                            BLOCKED → OPEN
                                   → FAILED ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terminal states: &lt;code&gt;fulfilled&lt;/code&gt;, &lt;code&gt;failed&lt;/code&gt;, &lt;code&gt;expired&lt;/code&gt;, &lt;code&gt;cancelled&lt;/code&gt;, &lt;code&gt;superseded&lt;/code&gt;, &lt;code&gt;contradicted&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The critical rule:&lt;/strong&gt; the &lt;code&gt;fulfilled&lt;/code&gt; transition requires external evidence.&lt;/p&gt;

&lt;p&gt;We enforce this at the database level. All state changes go through a PostgreSQL function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;cogext_transition_commitment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;p_commitment_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_new_status&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_actor&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'system'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_data&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;DECLARE&lt;/span&gt;
    &lt;span class="n"&gt;current_status&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;evidence_score&lt;/span&gt; &lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;current_status&lt;/span&gt; 
      &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;commitments&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p_commitment_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;-- Block fulfilled without evidence for external commitments&lt;/span&gt;
    &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;p_new_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'fulfilled'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
        &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;evidence_score&lt;/span&gt;
          &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;evidence&lt;/span&gt; 
          &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;commitment_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p_commitment_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;evidence_score&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;evidence_score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
            &lt;span class="n"&gt;RAISE&lt;/span&gt; &lt;span class="n"&gt;EXCEPTION&lt;/span&gt; &lt;span class="s1"&gt;'Cannot fulfill without evidence score &amp;gt;= 0.7'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;-- Validate transition, update, insert event, return&lt;/span&gt;
    &lt;span class="c1"&gt;-- ...&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt; &lt;span class="k"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tested this last week. Tried to force-fulfill a commitment via the API. Got HTTP 409. The database refused.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The agent cannot close its own loop. Not because of application logic. Because of the database.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Kill Switch (Human-in-the-Loop)
&lt;/h2&gt;

&lt;p&gt;Some actions are too dangerous to run without human approval. Processing a $12,000 refund. Deploying to production. Sending an email to a client.&lt;/p&gt;

&lt;p&gt;For these, COGEXT pauses the agent and sends a Slack message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🚨 COGEXT: High-risk action detected

Agent: support-agent-001
Action: process refund
Amount: $12,000
Customer: 4821

[Approve] [Cancel]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent doesn't execute until a human clicks one of the buttons. Every decision is logged in the events table with the actor, timestamp, and reason.&lt;/p&gt;

&lt;p&gt;This is the feature every team asks for after the first time an agent does something catastrophic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Contradiction Radar
&lt;/h2&gt;

&lt;p&gt;Agents contradict themselves constantly. At 2:00 PM: "I'll deliver Friday." At 2:47 PM: "I'll deliver Monday." Same recipient. Same object. Different deadline.&lt;/p&gt;

&lt;p&gt;Nobody catches this in real-time. Not the developer. Not the client. Until Monday arrives and the client expects delivery and the agent thinks it's already Thursday.&lt;/p&gt;

&lt;p&gt;COGEXT scans every open commitment on every new ingest. If the new commitment conflicts with an existing one, we flag it immediately:&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;"contradiction_alert"&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;"old_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ceb5ab93-..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"new_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"567ae7bb-..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Same commitment sent as two distinct messages. Deadline revised."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"old_promise"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I will deliver the report to the client on Friday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"new_promise"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I will deliver the report to the client"&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;The old commitment is marked &lt;code&gt;superseded&lt;/code&gt;. The new one is tracked. The full history is preserved.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Failure Predictor
&lt;/h2&gt;

&lt;p&gt;Every commitment gets a risk score at creation time. Based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deadline timing, such as Friday 5 PM being riskier than Tuesday morning&lt;/li&gt;
&lt;li&gt;Keywords (&lt;code&gt;legal&lt;/code&gt;, &lt;code&gt;approval&lt;/code&gt;, &lt;code&gt;irreversible&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Agent's historical fulfillment rate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example output:&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;"risk_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.55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reasons"&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="s2"&gt;"Involves legal review"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Due Friday after 4 PM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"This agent has a 67% fulfillment rate on Friday deadlines"&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;It's rule-based right now. No ML. But it catches the obvious cases, the ones that cause 80% of failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Public Audit Receipt
&lt;/h2&gt;

&lt;p&gt;Every commitment generates a shareable proof URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.cogextai.com/api/v1/receipt/UtN6A3jo.axKJXIQ_xniFUgne07fGd9c3R4cYknLrCmRqaxGR75c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anyone can visit it and see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Original commitment text&lt;/li&gt;
&lt;li&gt;Full state history&lt;/li&gt;
&lt;li&gt;Evidence found or not found&lt;/li&gt;
&lt;li&gt;Human approvals&lt;/li&gt;
&lt;li&gt;HMAC signature for integrity verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Send it to a client. Send it to an auditor. Send it to a regulator.&lt;/p&gt;

&lt;p&gt;The point isn't the receipt. The point is that the developer can prove what their agent actually did.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; + &lt;strong&gt;Python 3.12&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; with pgvector for semantic memory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Groq&lt;/strong&gt; (llama-3.3-70b) for extraction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instructor&lt;/strong&gt; for structured output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gmail API, GitHub API, Webhooks&lt;/strong&gt; for verifiers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack&lt;/strong&gt; for alerts and approvals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The SDK is 3 lines:&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;cogext&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;
&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;your_agent&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;cg_live_xxx&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;Every call to &lt;code&gt;agent.run()&lt;/code&gt; auto-ingests the output. Commitments are tracked. Verifiers run on a schedule. Evidence is checked against external systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The E2E Test Results
&lt;/h2&gt;

&lt;p&gt;We ran the full test suite against production last week:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Test | Feature | Status |
|------|---------|--------|
| 1 | Failure Predictor | PASS |
| 2 | Verifier Engine | PASS |
| 3 | Contradiction Radar | PASS |
| 4 | Kill Switch | PASS |
| 5 | Audit Receipt | PASS |
| 6 | Idempotency | PASS |
| 7 | State Machine Gate | PASS |
| 8 | Reliability | PASS |

Ready to Announce? YES. All tests passed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test 7 is the one that matters most. It tries to force-fulfill a commitment without evidence. HTTP 409. Blocked at the database level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The state machine won't let the agent lie.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Is Really About
&lt;/h2&gt;

&lt;p&gt;Every observability tool watches what the agent said. COGEXT watches what actually happened.&lt;/p&gt;

&lt;p&gt;The difference sounds small. It isn't.&lt;/p&gt;

&lt;p&gt;A tool that watches the agent's output will tell you "the agent sent the email." A tool that watches the effect will tell you "the email was sent" or "the email was never sent."&lt;/p&gt;

&lt;p&gt;The first is a log. The second is an audit trail.&lt;/p&gt;

&lt;p&gt;If your agent makes promises in production, you need the second one. Not because it's fashionable, but because the first one has a failure mode you can't detect until the client calls.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Site:&lt;/strong&gt; cogextai.com&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; docs.cogextai.com&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; github.com/cogext/cogext&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK:&lt;/strong&gt; &lt;code&gt;pip install cogext&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Free tier: 2,500 commitments per month. No credit card.&lt;/p&gt;

&lt;p&gt;If you're running AI agents in production and you've ever wondered "did my agent actually do that?", give it a try. Open an issue. Tell me what breaks.&lt;/p&gt;

&lt;p&gt;The agent's word should not be the final word.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>software</category>
      <category>testing</category>
    </item>
    <item>
      <title>I built a 12-state accountability layer for AI agents here's what I learned</title>
      <dc:creator>Yamin</dc:creator>
      <pubDate>Thu, 03 Sep 2026 20:49:01 +0000</pubDate>
      <link>https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i</link>
      <guid>https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i</guid>
      <description>&lt;p&gt;By the time you finish reading this, your AI agent will have made at least one promise it can't keep.&lt;/p&gt;

&lt;p&gt;That's not a dig at your code. It's a fundamental property of how we build AI systems today. Agents are brilliant at generating intent and terrible at tracking it. They'll promise to email a client, confirm an appointment, or deploy a fix and two conversations later, they've forgotten they said anything at all.&lt;/p&gt;

&lt;p&gt;The more I thought about this, the more I realized: &lt;strong&gt;commitments aren't a memory problem. They're a state machine problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I built COGEXT — an accountability layer that sits between your agent and the outside world. You send it agent output, it extracts every commitment, and tracks each one until it's fulfilled, failed, or overdue.&lt;/p&gt;




&lt;h2&gt;
  
  
  The core idea: commitments have state
&lt;/h2&gt;

&lt;p&gt;Most systems treat agent output as text to be logged. We treat it as events to be tracked.&lt;/p&gt;

&lt;p&gt;Every extracted commitment moves through 12 states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DETECTED
    ├──→ OPEN ──→ DUE ──→ OVERDUE ──→ FULFILLED ✓
    │                        ├──→ FAILED ✗
    │                        └──→ EXPIRED ✗
    ├──→ PENDING_REVIEW ──→ OPEN
    ├──→ CANCELLED ✗
    ├──→ CONTRADICTED ✗
    └──→ BLOCKED ──→ OPEN
                  └──→ FAILED ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terminal states: &lt;code&gt;fulfilled&lt;/code&gt;, &lt;code&gt;failed&lt;/code&gt;, &lt;code&gt;expired&lt;/code&gt;, &lt;code&gt;cancelled&lt;/code&gt;, &lt;code&gt;superseded&lt;/code&gt;, &lt;code&gt;contradicted&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All state mutations go through a single PostgreSQL RPC function. Not direct UPDATEs from application code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;cogext_transition_commitment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;p_commitment_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_new_status&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_actor&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'system'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_data&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="c1"&gt;-- lock row → validate transition → update status → insert event → return&lt;/span&gt;
    &lt;span class="c1"&gt;-- single atomic operation: if any step fails, the whole thing rolls back&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt; &lt;span class="k"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? Because the state change and the event must be atomic. You should never have &lt;code&gt;status = 'fulfilled'&lt;/code&gt; without a corresponding fulfillment event in the audit log. That's the line between a logging system and an accountability system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Extracting commitments from agent output
&lt;/h2&gt;

&lt;p&gt;The extraction pipeline has two stages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Classification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not everything an agent says is a commitment. We classify first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;genuine_commitment&lt;/code&gt; — "I will send the report by Friday."&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;intention&lt;/code&gt; — "I might send the report tomorrow."&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;suggestion&lt;/code&gt; — "We should send the report tomorrow."&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hypothetical&lt;/code&gt; — "If we have time, I could send it."&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;quoted_statement&lt;/code&gt; — "John said he would send it."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only &lt;code&gt;genuine_commitment&lt;/code&gt; with confidence ≥ 0.5 passes through.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2: Structured extraction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We use Groq's llama-3.3-70b in JSON mode to extract fields:&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;response&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;groq_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&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;llama-3.3-70b-versatile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="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="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="n"&gt;response_format&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;json_object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&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 output is validated against a Pydantic schema. If the LLM returns garbage, we retry once. If it still fails, the commitment is dropped — not inserted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key decision:&lt;/strong&gt; We don't trust the LLM to interpret deadlines. We extract the raw expression ("Friday EOD") and pass it to a deterministic temporal normalizer. The LLM interprets; the code decides.&lt;/p&gt;




&lt;h2&gt;
  
  
  Evidence scoring: why 0.88 ≠ 0.92
&lt;/h2&gt;

&lt;p&gt;Evidence verification is where most systems fail. Binary matching — "does this email mention the report?" — generates too many false positives.&lt;/p&gt;

&lt;p&gt;We use a weighted field-coverage model:&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;Weight&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;action&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;recipient&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deadline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When evidence arrives, we check which commitment fields it matches and sum the weights:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Evidence 1: confirms action ("I sent it")
    → 0.40

Evidence 2: confirms recipient + object ("sent to Sarah, deployment-report.pdf attached")
    → 0.30 + 0.20 = 0.50

Total = 0.90 → FULFILLED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The threshold is configurable (default 0.90). Multiple pieces of evidence can satisfy different fields — they aggregate.&lt;/p&gt;




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

&lt;p&gt;AI agents repeat themselves. An agent might say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I'll send the report by Friday."&lt;/li&gt;
&lt;li&gt;"Let me confirm: I'll send it by Friday."&lt;/li&gt;
&lt;li&gt;"Just to reiterate, I will send the report by Friday."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same commitment. Without idempotency, you'd track it three times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;compute_idempotency_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;promise_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minute&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;second&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;microsecond&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;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;agent_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;promise_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&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="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;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same agent + same promise + same hour = same hash. The DB unique constraint rejects the duplicate silently.&lt;/p&gt;

&lt;p&gt;The hour window is deliberate: it deduplicates within a session while still allowing the same promise to be legitimately re-made days later.&lt;/p&gt;




&lt;h2&gt;
  
  
  The four lessons that cost us the most
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. LLM output is untrusted input.&lt;/strong&gt;&lt;br&gt;
We validate everything against Pydantic schemas before touching the database. No exceptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Determinism over magic.&lt;/strong&gt;&lt;br&gt;
LLMs for interpretation. Deterministic code for everything else: state transitions, date normalization, deduplication, metrics. We don't call the LLM to check if a deadline is overdue. We run a database query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Events are not logs.&lt;/strong&gt;&lt;br&gt;
A log is a record that can be ignored. An event is a fact that cannot be denied. We enforce this at the DB layer — a trigger rejects any UPDATE or DELETE on the events table. Historical events are immutable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Scope the user_id at the auth layer, never the request body.&lt;/strong&gt;&lt;br&gt;
Early version trusted &lt;code&gt;user_id&lt;/code&gt; from the request payload. Classic mistake. All scoping now comes from the API key's &lt;code&gt;account_id&lt;/code&gt;. The request body cannot claim to own data it doesn't own.&lt;/p&gt;


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

&lt;p&gt;The API is live and the SDK is on PyPI:&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;cogext
&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;cogext&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;your_agent&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;cg_live_xxx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;output&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;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;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ll send the report by Friday&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# commitment is tracked automatically
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docs at &lt;strong&gt;docs.cogextai.com&lt;/strong&gt; — there's a quickstart that takes about 5 minutes.&lt;/p&gt;

&lt;p&gt;Would genuinely appreciate feedback from anyone who's hit this problem with their own agents. What does your current approach look like?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>architecture</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Yamin</dc:creator>
      <pubDate>Thu, 03 Sep 2026 20:47:52 +0000</pubDate>
      <link>https://dev.to/yaminbinyoosuf/-p7b</link>
      <guid>https://dev.to/yaminbinyoosuf/-p7b</guid>
      <description></description>
    </item>
  </channel>
</rss>
