{"slug":"tracking-broken-promises-a-state-machine-for-agent-commitments","citations":[{"url":"https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i","committed_hash":"sha256:8b2c6b78241781c6705135f81847efe1fc04a0e1b26246454945561a88bc57fd","committed_hash_short":"sha256:8b2c6b78…88bc57fd","mime_type":"text/html","committed_at":"2026-09-04T02:00:26.682216+00:00","content_snapshot":"<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>I built a 12-state accountability layer for AI agents here&#39;s what I learned - DEV Community</title>\n    \n    <link rel=\"preload\" href=\"/reactions?article_id=4568295\" as=\"fetch\" crossorigin=\"same-origin\">\n    <link rel=\"canonical\" href=\"https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\" />\n    <meta name=\"description\" content=\"By the time you finish reading this, your AI agent will have made at least one promise it can&#39;t... Tagged with ai, python, architecture, machinelearning.\">\n    <meta name=\"keywords\" content=\"ai, python, architecture, machinelearning, software, coding, development, engineering, inclusive, community\">\n\n    <meta property=\"og:type\" content=\"article\" />\n    <meta property=\"og:url\" content=\"https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\" />\n    <meta property=\"og:title\" content=\"I built a 12-state accountability layer for AI agents here&#39;s what I learned\" />\n    <meta property=\"og:description\" content=\"By the time you finish reading this, your AI agent will have made at least one promise it can&#39;t...\" />\n    <meta property=\"og:site_name\" content=\"DEV Community\" />\n    <meta name=\"twitter:site\" content=\"@thepracticaldev\">\n    <meta name=\"twitter:creator\" content=\"@yaminbinyoosuf\">\n    <meta name=\"author-trust\" content=\"0\">\n    <meta name=\"twitter:title\" content=\"I built a 12-state accountability layer for AI agents here&#39;s what I learned\">\n    <meta name=\"twitter:description\" content=\"By the time you finish reading this, your AI agent will have made at least one promise it can&#39;t...\">\n    <meta name=\"twitter:card\" content=\"summary_large_image\">\n    <meta name=\"twitter:widgets:new-embed-design\" content=\"on\">\n    <meta name=\"robots\" content=\"max-snippet:-1, max-image-preview:large, max-video-preview:-1\">\n      <meta property=\"og:image\" content=\"https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59iie19cxvsc8vb1j4rb.png\" />\n      <meta name=\"twitter:image:src\" content=\"https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59iie19cxvsc8vb1j4rb.png\">\n\n      <meta name=\"last-updated\" content=\"2026-09-03 20:52:07 UTC\">\n      <meta name=\"user-signed-in\" content=\"false\">\n      <meta name=\"head-cached-at\" content=\"1788468727\">\n      <meta name=\"environment\" content=\"production\">\n      <link rel=\"stylesheet\" href=\"https://assets.dev.to/assets/minimal-3a438d8d138f95f478f01cbe53363cacf36bc6c47172aeb2e6c9172eebe29aa6.css\" media=\"all\" id=\"main-minimal-stylesheet\" />\n<link rel=\"stylesheet\" href=\"https://assets.dev.to/assets/views-ca4b6f6e9ec63c7deefbdd4067e585d752cd4b06c12da1a49c7b9644defa2758.css\" media=\"all\" id=\"main-views-stylesheet\" />\n<link rel=\"stylesheet\" href=\"https://assets.dev.to/assets/crayons-a7ebbf5a548ce1c3f484ca5269858ff57f20acba925b547f7a555de680de0340.css\" media=\"all\" id=\"main-crayons-stylesheet\" />\n\n      <script src=\"https://assets.dev.to/assets/base-2e294c52c5fe6b771fda1a5f38d2f10756d0b4d8359c6f9825fe47df0f54e6ae.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/application-9ee88e198a0d2b64238c8557b5225d20e2c18ff5b877f1159ee5a31f6e3174f9.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/baseInitializers-624554190e72cf52de9498fd225c2e71ab334dfc4919535dcc5a26a3a0ae2359.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/baseTracking-cb478131fb1b41bc25e80ebcee996318777e081c9aa87367fabc1c118461a2d3.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/followButtons-e3595664847e9f43945a9b8a0445b32cda9a149f1f169f78b8fcc7714ccab45a.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/eventSignupButtons-a2b5da712a1b8eeb0eda4d63fafc54973138a70b88503a2163806c27fc1e4c39.js\" defer=\"defer\"></script>\n\n        <meta name=\"search-script\" content=\"https://assets.dev.to/assets/Search-a570c3428c9b6cb070d3f18817c957f80d0dbdf36a0f4a1d6e23a990305fbc12.js\">\n      <meta name=\"mermaid-script\" content=\"https://assets.dev.to/assets/mermaidRenderer-b9ba305a9767f9203ac04b8043493fb0542090e9a7981428cecf8c7d2ccaf177.js\">\n      <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, viewport-fit=cover\">\n      <link rel=\"icon\" type=\"image/x-icon\" href=\"https://media2.dev.to/dynamic/image/width=32,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\" />\n      <link rel=\"apple-touch-icon\" href=\"https://media2.dev.to/dynamic/image/width=180,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\">\n      <link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"https://media2.dev.to/dynamic/image/width=152,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\">\n      <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"https://media2.dev.to/dynamic/image/width=180,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\">\n      <link rel=\"apple-touch-icon\" sizes=\"167x167\" href=\"https://media2.dev.to/dynamic/image/width=167,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\">\n      <link href=\"https://media2.dev.to/dynamic/image/width=192,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\" rel=\"icon\" sizes=\"192x192\" />\n      <link href=\"https://media2.dev.to/dynamic/image/width=128,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\" rel=\"icon\" sizes=\"128x128\" />\n      <meta name=\"apple-mobile-web-app-title\" content=\"dev.to\">\n      <meta name=\"application-name\" content=\"dev.to\">\n      <meta name=\"theme-color\" content=\"#ffffff\" media=\"(prefers-color-scheme: light)\">\n      <meta name=\"theme-color\" content=\"#000000\" media=\"(prefers-color-scheme: dark)\">\n      <link rel=\"search\" href=\"https://dev.to/open-search.xml\" type=\"application/opensearchdescription+xml\" title=\"DEV Community\" />\n\n      <link rel=\"describedby\" href=\"https://dev.to/llms.txt\" type=\"text/plain\" title=\"Guidance for AI agents\" />\n\n      <meta property=\"forem:name\" content=\"DEV Community\" />\n      <meta property=\"forem:logo\" content=\"https://media2.dev.to/dynamic/image/width=512,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\" />\n      <meta property=\"forem:domain\" content=\"dev.to\" />\n    <style>\r\nbody:has(.pageslug-aie) #topbar {\r\n    display: none !important;\r\n}\r\n\r\n@media screen and (max-width: 768px) and (pointer: coarse) {\r\n  /* Target WebKit/Blink specific behaviors */\r\n  @supports (-webkit-app-region: none) {\r\n    body:has(.pageslug-aie) .dc-page {\r\n      padding-top: 56px !important;\r\n    }\r\n  }\r\n}\r\n\r\nbody:not(.hidden-shell) .pageslug-aie {\r\n    margin-top: -56px !important;\r\n}\r\n\r\n/* ==========================================================================\r\n   THE 418 CHALLENGE: THEME-AWARE RETRO EDITION\r\n   ========================================================================== */\r\n.articletag-418challenge {\r\n  font-family: \"Comic Sans MS\", \"Chalkboard SE\", \"Marker Felt\", sans-serif !important;\r\n  cursor: crosshair !important;\r\n}\r\n\r\n/* Destroy modern rounded corners and add brutal borders */\r\n.articletag-418challenge .crayons-card,\r\n.articletag-418challenge .crayons-article__main,\r\n.articletag-418challenge .crayons-article__header {\r\n  border-radius: 0 !important;\r\n  margin-bottom: 2rem !important;\r\n}\r\n\r\n/* Typography specifics */\r\n.articletag-418challenge h1,\r\n.articletag-418challenge h2,\r\n.articletag-418challenge h3 {\r\n  text-transform: uppercase !important;\r\n}\r\n\r\n/* Fake <marquee> effect for the main article title */\r\n.articletag-418challenge h1.fs-3xl {\r\n  animation: retro-slide 5s linear infinite alternate;\r\n  overflow: visible;\r\n}\r\n\r\n/* Spin those avatars */\r\n.articletag-418challenge .crayons-article__header__meta img {\r\n  border-radius: 0 !important; \r\n  animation: retro-spin 5s linear infinite;\r\n}\r\n\r\n/* Obnoxious tags */\r\n.articletag-418challenge .crayons-tag {\r\n  border-radius: 0 !important;\r\n  font-weight: 900 !important;\r\n  transform: rotate(-3deg);\r\n  display: inline-block;\r\n}\r\n.articletag-418challenge .crayons-tag:nth-child(even) {\r\n  transform: rotate(3deg);\r\n}\r\n\r\n/* --------------------------------------------------------------------------\r\n   2. LIGHT THEME (Windows 95 / Office 97 Vibes)\r\n   -------------------------------------------------------------------------- */\r\nbody:not(.dark-theme) .articletag-418challenge {\r\n  background-color: #008080 !important; /* Win95 Teal Desktop */\r\n}\r\n\r\nbody:not(.dark-theme) .articletag-418challenge .crayons-card,\r\nbody:not(.dark-theme) .articletag-418challenge .crayons-article__main,\r\nbody:not(.dark-theme) .articletag-418challenge .crayons-article__header {\r\n  background-color: #c0c0c0 !important; /* Classic dialog gray */\r\n  color: #000000 !important;\r\n  border: 4px outset #ffffff !important;\r\n  box-shadow: 8px 8px 0px #000000 !important;\r\n}\r\n\r\nbody:not(.dark-theme) .articletag-418challenge h1,\r\nbody:not(.dark-theme) .articletag-418challenge h2,\r\nbody:not(.dark-theme) .articletag-418challenge h3 {\r\n  color: #ff0000 !important;\r\n  text-shadow: 2px 2px 0px #ffff00 !important;\r\n  border-bottom: 3px dashed #0000ff !important;\r\n}\r\n\r\nbody:not(.dark-theme) .articletag-418challenge a,\r\nbody:not(.dark-theme) .articletag-418challenge .crayons-link {\r\n  color: #0000ff !important; /* Standard unvisited blue */\r\n  text-decoration: underline !important;\r\n  font-weight: bold !important;\r\n}\r\n\r\nbody:not(.dark-theme) .articletag-418challenge a:hover,\r\nbody:not(.dark-theme) .articletag-418challenge .crayons-link:hover {\r\n  background-color: #ffff00 !important;\r\n  color: #ff0000 !important;\r\n}\r\n\r\nbody:not(.dark-theme) .articletag-418challenge .crayons-tag {\r\n  background: #ffff00 !important;\r\n  color: #ff0000 !important;\r\n  border: 2px dotted #0000ff !important;\r\n}\r\n\r\n/* --------------------------------------------------------------------------\r\n   3. DARK THEME (1999 Hacker / Deep GeoCities Vibes)\r\n   -------------------------------------------------------------------------- */\r\nbody.dark-theme .articletag-418challenge {\r\n  background-color: #000000 !important;\r\n  /* Dumb CSS: A scrolling, eye-bleeding neon green hacker grid with CRT scanlines */\r\n  background-image: \r\n    linear-gradient(transparent 50%, rgba(0, 255, 0, 0.25) 50%), \r\n    linear-gradient(90deg, rgba(0, 255, 0, 0.5) 1px, transparent 1px), \r\n    linear-gradient(rgba(0, 255, 0, 0.5) 1px, transparent 1px) !important;\r\n  background-size: 100% 4px, 20px 20px, 20px 20px !important;\r\n  animation: retro-pan 60s linear infinite !important;\r\n}\r\n\r\nbody.dark-theme .articletag-418challenge .crayons-card,\r\nbody.dark-theme .articletag-418challenge .crayons-article__main,\r\nbody.dark-theme .articletag-418challenge .crayons-article__header {\r\n  background-color: #111111 !important;\r\n  color: #00ff00 !important; /* Terminal Green */\r\n  border: 4px outset #555555 !important;\r\n  box-shadow: 8px 8px 0px #ff00ff !important; /* Hot pink shadow */\r\n}\r\n\r\nbody.dark-theme .articletag-418challenge h1,\r\nbody.dark-theme .articletag-418challenge h2,\r\nbody.dark-theme .articletag-418challenge h3 {\r\n  color: #ff00ff !important; /* Magenta headers */\r\n  text-shadow: 2px 2px 0px #00ffff !important; /* Cyan shadow */\r\n  border-bottom: 3px dashed #00ff00 !important;\r\n}\r\n\r\nbody.dark-theme .articletag-418challenge a,\r\nbody.dark-theme .articletag-418challenge .crayons-link {\r\n  color: #00ffff !important; /* Cyan links */\r\n  text-decoration: underline !important;\r\n  font-weight: bold !important;\r\n}\r\n\r\nbody.dark-theme .articletag-418challenge a:hover,\r\nbody.dark-theme .articletag-418challenge .crayons-link:hover {\r\n  background-color: #ff00ff !important;\r\n  color: #ffffff !important;\r\n}\r\n\r\nbody.dark-theme .articletag-418challenge .crayons-tag {\r\n  background: #000000 !important;\r\n  color: #00ff00 !important;\r\n  border: 2px dotted #ff00ff !important;\r\n}\r\n\r\n/* --------------------------------------------------------------------------\r\n   4. ANIMATIONS\r\n   -------------------------------------------------------------------------- */\r\n@keyframes retro-spin {\r\n  100% { transform: rotate(360deg); }\r\n}\r\n\r\n@keyframes retro-slide {\r\n  0% { transform: translateX(-2%); }\r\n  100% { transform: translateX(2%); }\r\n}\r\n\r\n@keyframes retro-pan {\r\n  0% { background-position: 0 0, 0 0, 0 0; }\r\n  /* Numbers must be multiples of the background-size (4px and 20px) to loop perfectly */\r\n  100% { background-position: 0 100px, 40px 40px, 40px 40px; }\r\n}\r\n\r\n/* --------------------------------------------------------------------------\r\n   5. BONUS: CAUTION TAPE REACTION BAR\r\n   -------------------------------------------------------------------------- */\r\n.articletag-418challenge .crayons-article-actions {\r\n  background: repeating-linear-gradient(\r\n    45deg,\r\n    #ffff00,\r\n    #ffff00 10px,\r\n    #000000 10px,\r\n    #000000 20px\r\n  ) !important;\r\n  border: 4px solid #ff0000 !important;\r\n  border-radius: 0 !important;\r\n}\r\n\r\n.articletag-418challenge .crayons-article-actions button {\r\n  background:black;\r\n  color: #ff00ff !important;\r\n}\r\n\r\n.articletag-418challenge .crayons-article-actions .crayons-reaction__count {\r\n    color: #ff00ff !important;\r\n    font-weight: bold !important;\r\n}\r\n\r\n.articletag-418challenge .crayons-icon:not(.crayons-icon--default) * {\r\n    fill: #ffff00 !important;\r\n}\r\n\r\n.articletag-418challenge .c-embed .crayons-btn--primary {\r\n  color: #00ff00 !important;\r\n}\r\n\r\n.articletag-418challenge .popover-billboard {\r\nmargin-bottom: 0 !important;\r\n}\r\n\r\n.crayons-story__contentpreview .ltag__link--embedded {\r\nmargin-top: 0 !important;\r\n}\r\n\r\n.subscription-icon {\r\n    max-height: 16px !important;\r\n    display: inline-block !important;\r\n}\r\n\r\n@media screen and (min-width: 950px) {\r\n    .event-show-layout {\r\n        margin-top: 24px !important;\r\n    }\r\n}\r\n\r\n@media screen and (max-width: 949px) {\r\n    .event-show-layout {\r\n        padding: 11px !important;\r\n    }\r\n}\r\n\r\n\r\n</style>\n  </head>\n    <body\n      class=\"sans-serif-article-body default-header\"\n      data-user-status=\"logged-out\"\n      data-is-root-subforem=\"false\"\n        data-subforem-id=\"1\"\n      data-side-nav-visible=\"true\"\n      data-community-name=\"DEV Community\"\n      data-subscription-icon=\"https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png\"\n      data-community-leader-icon=\"https://assets.dev.to/assets/community-leader-icon-b72c9e74eff54916e5c46c962f47ba40c9f611a71f8b157511f9613f69c0001b.svg\"\n      data-locale=\"en\"\n      data-honeybadger-key=\"hbp_nqu4Y66HuEKlD6YRGssZuRQnPOjDm50J8Zkr\"\n      data-deployed-at=\"2026-09-03T20:12:47Z\"\n      data-latest-commit-id=\"066b7fd3b30e325cef0696ef32dac2962589d039\"\n      data-ga-tracking=\"UA-71991109-1\"\n      data-cookie-banner-user-context=\"logged_out_only\"\n      data-cookie-banner-platform-context=\"off\"\n      data-algolia-id=\"PRSOBFP46H\"\n      data-algolia-search-key=\"9aa7d31610cba78851c9b1f63776a9dd\"\n      data-algolia-display=\"true\"\n      data-dynamic-url-component=\"bmar11\"\n      data-ga4-tracking-id=\"G-TYEM8Y3JN3\"\n      data-global-feature-flags-enabled=\"data_update_scripts onboarding_newsletter_content schedule_articles moderator_role display_ad_tags replace_unicorn_with_jump_to_comments article_id_adjusted_weight cloudflare_preferred_for_hosted_images multiple_reactions subscriber_icon ab_experiment_feed_strategy use_stories_endpoint digest_subject_testing digest_results_count_testing consistent_rendering discover_and_following_tabs hero_billboard onboarding_drip_emails algolia_frontend gemini_onboarding optimize_article_tag_query dev_core_user_sync personalized_email_digests community_favorites\"\n      data-style-fingerprint=\"9a99717fe3\">\n      \n      <script>\n        if (navigator.userAgent === 'ForemWebView/1' || window.frameElement) {\n          document.body.classList.add(\"hidden-shell\");\n        }\n          if (new Date() > new Date(\"2026-02-04T09:00:00-05:00\")) {\n            document.body.dataset.sideNavVisible = \"false\";\n          } \n      </script>\n\n      <link rel=\"stylesheet\" href=\"https://assets.dev.to/assets/minimal-3a438d8d138f95f478f01cbe53363cacf36bc6c47172aeb2e6c9172eebe29aa6.css\" media=\"all\" id=\"secondary-minimal-stylesheet\" />\n<link rel=\"stylesheet\" href=\"https://assets.dev.to/assets/views-ca4b6f6e9ec63c7deefbdd4067e585d752cd4b06c12da1a49c7b9644defa2758.css\" media=\"all\" id=\"secondary-views-stylesheet\" />\n<link rel=\"stylesheet\" href=\"https://assets.dev.to/assets/crayons-a7ebbf5a548ce1c3f484ca5269858ff57f20acba925b547f7a555de680de0340.css\" media=\"all\" id=\"secondary-crayons-stylesheet\" />\n\n      <div id=\"body-styles\">\n        <style>\n          :root {\n            --accent-brand-lighter-rgb: 86, 105, 285;\n            --accent-brand-rgb: 64, 78, 211;\n            --accent-brand-darker-rgb: 51, 62, 169;\n          }\n        </style>\n      </div>\n      <div id=\"audiocontent\" data-podcast=\"\">\n        \n      </div>\n      <div class=\"navigation-progress\" id=\"navigation-progress\"></div>\n\n<header id=\"topbar\" class=\"crayons-header topbar print-hidden\">\n  <span id=\"route-change-target\" tabindex=\"-1\"></span>\n  <a href=\"#main-content\" class=\"skip-content-link\">Skip to content</a>\n  <div class=\"crayons-header__container\">\n    <span class=\"inline-block m:hidden \">\n      <button class=\"c-btn c-btn--icon-alone js-hamburger-trigger mx-2\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" role=\"img\" aria-labelledby=\"atqikf4mny23kguv8995a8pkedmu5pu4\" class=\"crayons-icon\"><title id=\"atqikf4mny23kguv8995a8pkedmu5pu4\">Navigation menu</title>\n    <path d=\"M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z\"></path>\n</svg>\n\n      </button>\n    </span>\n    <a href=\"/\" class=\"site-logo\" aria-label=\"DEV Community Home\" >\n    <img class=\"site-logo__img\"\n         src=\"https://media2.dev.to/dynamic/image/quality=100/https://dev-to-uploads.s3.amazonaws.com/uploads/logos/resized_logo_UQww2soKuUsjaOGNB38o.png\"\n         style=\"aspect-ratio: 10 / 8\"\n         alt=\"DEV Community\">\n</a>\n\n\n    <div class=\"crayons-header--search js-search-form\" id=\"header-search\">\n      <form accept-charset=\"UTF-8\" method=\"get\" action=\"/search\" role=\"search\">\n        <div class=\"crayons-fields crayons-fields--horizontal\">\n          <div class=\"crayons-field flex-1 relative\">\n            <input id=\"search-input\" class=\"crayons-header--search-input crayons-textfield js-search-input\" type=\"text\" id=\"nav-search\" name=\"q\" placeholder=\"Find related posts...\" autocomplete=\"off\" />\n            <button type=\"submit\" aria-label=\"Search\" class=\"c-btn c-btn--icon-alone absolute inset-px right-auto mt-0 py-0\">\n              <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" role=\"img\" aria-labelledby=\"a40w3w0a8beh8m18dcj32h96rg06pbw2\" aria-hidden=\"true\" class=\"crayons-icon\"><title id=\"a40w3w0a8beh8m18dcj32h96rg06pbw2\">Search</title>\n    <path d=\"M18.031 16.617l4.283 4.282-1.415 1.415-4.282-4.283A8.96 8.96 0 0111 20c-4.968 0-9-4.032-9-9s4.032-9 9-9 9 4.032 9 9a8.96 8.96 0 01-1.969 5.617zm-2.006-.742A6.977 6.977 0 0018 11c0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7a6.977 6.977 0 004.875-1.975l.15-.15z\"></path>\n</svg>\n\n            </button>\n\n            <a class=\"crayons-header--search-brand-indicator\" href=\"https://www.algolia.com/developers/?utm_source=devto&utm_medium=referral\" target=\"_blank\" rel=\"noopener noreferrer\">\n                Powered by Algolia\n                <svg xmlns=\"http://www.w3.org/2000/svg\" id=\"Layer_1\" width=\"24\" height=\"24\" viewBox=\"0 0 500 500.34\" role=\"img\" aria-labelledby=\"a91wfwvhjzya9o4kkfd5nzlg24neurmf\" aria-hidden=\"true\" class=\"crayons-icon\"><title id=\"a91wfwvhjzya9o4kkfd5nzlg24neurmf\">Search</title>\n  <defs></defs><path class=\"cls-1\" d=\"M250,0C113.38,0,2,110.16,.03,246.32c-2,138.29,110.19,252.87,248.49,253.67,42.71,.25,83.85-10.2,120.38-30.05,3.56-1.93,4.11-6.83,1.08-9.52l-23.39-20.74c-4.75-4.22-11.52-5.41-17.37-2.92-25.5,10.85-53.21,16.39-81.76,16.04-111.75-1.37-202.04-94.35-200.26-206.1,1.76-110.33,92.06-199.55,202.8-199.55h202.83V407.68l-115.08-102.25c-3.72-3.31-9.43-2.66-12.43,1.31-18.47,24.46-48.56,39.67-81.98,37.36-46.36-3.2-83.92-40.52-87.4-86.86-4.15-55.28,39.65-101.58,94.07-101.58,49.21,0,89.74,37.88,93.97,86.01,.38,4.28,2.31,8.28,5.53,11.13l29.97,26.57c3.4,3.01,8.8,1.17,9.63-3.3,2.16-11.55,2.92-23.6,2.07-35.95-4.83-70.39-61.84-127.01-132.26-131.35-80.73-4.98-148.23,58.18-150.37,137.35-2.09,77.15,61.12,143.66,138.28,145.36,32.21,.71,62.07-9.42,86.2-26.97l150.36,133.29c6.45,5.71,16.62,1.14,16.62-7.48V9.49C500,4.25,495.75,0,490.51,0H250Z\"></path>\n</svg>\n\n            </a>\n          </div>\n        </div>\n      </form>\n    </div>\n\n    <div class=\"flex items-center h-100 ml-auto\">\n        <div class=\"flex\" id=\"authentication-top-nav-actions\">\n          <span class=\"hidden m:block\">\n            <a href=\"https://dev.to/enter?signup_subforem=1\" class=\"c-link c-link--block mr-2 whitespace-nowrap ml-auto\" data-no-instant>\n              Log in\n            </a>\n          </span>\n\n          <a href=\"https://dev.to/enter?signup_subforem=1&amp;state=new-user\" data-tracking-id=\"ca_top_nav\" data-tracking-source=\"top_navbar\" class=\"c-cta c-cta--branded whitespace-nowrap mr-2\" data-no-instant>\n            Create account\n          </a>\n        </div>\n    </div>\n  </div>\n</header>\n\n<div class=\"hamburger\">\n  <div class=\"hamburger__content\">\n    <header class=\"hamburger__content__header\">\n      <h2 class=\"fs-l fw-bold flex-1 break-word lh-tight\">DEV Community</h2>\n\n      <button class=\"c-btn c-btn--icon-alone js-hamburger-trigger shrink-0\" aria-label=\"Close\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" role=\"img\" aria-labelledby=\"amlzpon2dfjyactb4enf43xiqch8bfr1\" aria-hidden=\"true\" class=\"crayons-icon c-btn__icon\"><title id=\"amlzpon2dfjyactb4enf43xiqch8bfr1\">Close</title><path d=\"M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636l4.95 4.95z\"></path></svg>\n\n      </button>\n    </header>\n\n    <div class=\"p-2 js-navigation-links-container\" id=\"authentication-hamburger-actions\">\n    </div>\n  </div>\n  <div class=\"hamburger__overlay js-hamburger-trigger\"></div>\n</div>\n\n\n      <div id=\"active-broadcast\" class=\"broadcast-wrapper\"></div>\n<div id=\"page-content\" class=\"wrapper stories stories-show articletag-ai articletag-python articletag-architecture articletag-machinelearning articleuser-4108680\" data-current-page=\"stories-show\">\n  <div id=\"page-content-inner\" data-internal-nav=\"false\" data-viewable-id=\"4568295\" data-viewable-type=\"Article\">\n    <div id=\"page-route-change\" class=\"screen-reader-only\" aria-live=\"polite\" aria-atomic=\"true\"></div>\n\n    \n<style>\n  .html-variant-wrapper { display: none}\n</style>\n\n\n\n<script src=\"https://unpkg.com/@webcomponents/webcomponentsjs@2.2.10/webcomponents-loader.js\"\n        integrity=\"sha384-3HK5hxQbkFqOIxMbpROlRmRtYl2LBZ52t+tqcjzsmr9NJuOWQxl8RgQSyFvq2lhy\"\n        crossorigin=\"anonymous\" defer></script>\n\n  <script src=\"https://assets.dev.to/assets/webShare-0686f0b9ac40589694ef6ae6a6202c44119bc781c254f6cf6d52d8a008461156.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/articlePage-7386c745667022e7147503d288454cfce459f2019ee90ce454e641a116844837.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/commentDropdowns-7a28d130e5b78d38b30a9495a964003a66bd64fa455fc70b766d69cf06b9ba24.js\" defer=\"defer\"></script>\n\n\n  <script type=\"application/ld+json\">\n    {\"@context\":\"http://schema.org\",\"@type\":\"Article\",\"mainEntityOfPage\":{\"@type\":\"WebPage\",\"@id\":\"https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\"},\"url\":\"https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\",\"image\":[\"https://media2.dev.to/dynamic/image/width=1080,height=1080,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59iie19cxvsc8vb1j4rb.png\",\"https://media2.dev.to/dynamic/image/width=1280,height=720,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59iie19cxvsc8vb1j4rb.png\",\"https://media2.dev.to/dynamic/image/width=1600,height=900,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59iie19cxvsc8vb1j4rb.png\"],\"publisher\":{\"@context\":\"http://schema.org\",\"@type\":\"Organization\",\"name\":\"DEV Community\",\"logo\":{\"@context\":\"http://schema.org\",\"@type\":\"ImageObject\",\"url\":\"https://media2.dev.to/dynamic/image/width=192,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\",\"width\":\"192\",\"height\":\"192\"}},\"headline\":\"I built a 12-state accountability layer for AI agents here's what I learned\",\"author\":{\"@context\":\"http://schema.org\",\"@type\":\"Person\",\"url\":\"https://dev.to/yaminbinyoosuf\",\"name\":\"Yamin\"},\"datePublished\":\"2026-09-03T20:49:01Z\",\"dateModified\":\"2026-09-03T20:49:33Z\"}\n  </script>\n\n  \n  <div class=\"crayons-layout crayons-layout--3-cols crayons-layout--article\">\n    <aside class=\"crayons-layout__sidebar-left\" aria-label=\"Article actions\">\n      <script>\n  if (/Twitter for (iPhone|iPad|Android)/i.test(navigator.userAgent)) {\n    document.documentElement.classList.add('is-twitter-in-app');\n  }\n</script>\n\n<style>\n  .community-leader-visible-block {\n    display: none !important;\n  }\n  .trusted-visible-block {\n    display: none !important;\n  }\n  .only-sidebar-menu-item {\n    display: none !important;\n  }\n  @media (min-width: 640px) {\n    body.community-leader-status-true .only-sidebar-menu-item.community-leader-visible-block {\n      display: block !important;\n    }\n    body.trusted-status-true .only-sidebar-menu-item.trusted-visible-block {\n      display: block !important;\n    }\n  }\n  .only-mobile-menu-item {\n    display: none !important;\n  }\n  body.community-leader-status-true .only-mobile-menu-item.community-leader-visible-block {\n    display: block !important;\n  }\n  body.trusted-status-true .only-mobile-menu-item.trusted-visible-block {\n    display: block !important;\n  }\n  @media (min-width: 640px) {\n    body.community-leader-status-true .only-mobile-menu-item.community-leader-visible-block {\n      display: none !important;\n    }\n    body.trusted-status-true .only-mobile-menu-item.trusted-visible-block {\n      display: none !important;\n    }\n  }\n  .crayons-reaction__count {\n    line-height: 18px !important;\n    height: 18px !important;\n    min-height: 18px !important;\n    display: inline-flex !important;\n    align-items: center !important;\n    justify-content: center !important;\n  }\n  @media (min-width: 768px) {\n    .crayons-reaction__count {\n      display: flex !important;\n    }\n  }\n  .crayons-reaction__count > span {\n    height: 16px !important;\n    width: 16px !important;\n    padding: 0 !important;\n    display: inline-block !important;\n  }\n</style>\n\n  <div class=\"crayons-article-actions print-hidden\">\n    <div class=\"crayons-article-actions__inner\">\n\n      \n<div class=\"reaction-drawer__outer hoverdown\" style=\"\">\n  <button\n    id=\"reaction-drawer-trigger\"\n    aria-label=\"reaction-drawer-trigger\"\n    aria-pressed=\"false\"\n    class=\"hoverdown-trigger crayons-reaction pseudo-reaction crayons-tooltip__activator relative\">\n      <span class=\"crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction--like crayons-reaction__icon--inactive\" style=\"width: 40px; height: 40px\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" role=\"img\" aria-hidden=\"true\" class=\"crayons-icon\">\n    <g clip-path=\"url(#clip0_988_3276)\">\n        <path d=\"M19 14V17H22V19H18.999L19 22H17L16.999 19H14V17H17V14H19ZM20.243 4.75698C22.505 7.02498 22.583 10.637 20.479 12.992L19.059 11.574C20.39 10.05 20.32 7.65998 18.827 6.16998C17.324 4.67098 14.907 4.60698 13.337 6.01698L12.002 7.21498L10.666 6.01798C9.09103 4.60598 6.67503 4.66798 5.17203 6.17198C3.68203 7.66198 3.60703 10.047 4.98003 11.623L13.412 20.069L12 21.485L3.52003 12.993C1.41603 10.637 1.49503 7.01898 3.75603 4.75698C6.02103 2.49298 9.64403 2.41698 12 4.52898C14.349 2.41998 17.979 2.48998 20.242 4.75698H20.243Z\" fill=\"#525252\"></path>\n    </g>\n    <defs>\n        <clipPath id=\"clip0_988_3276\">\n        <rect width=\"24\" height=\"24\" fill=\"white\"></rect>\n        </clipPath>\n    </defs>\n</svg>\n\n      </span>\n      <span class=\"crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--active\" style=\"width: 40px; height: 40px\">\n        <img aria_hidden=\"true\" height=\"24\" width=\"24\" src=\"https://assets.dev.to/assets/heart-plus-active-9ea3b22f2bc311281db911d416166c5f430636e76b15cd5df6b3b841d830eefa.svg\" />\n      </span>\n      <span class=\"crayons-reaction__count\" id=\"reaction_total_count\">\n        <span class=\"bg-base-40 opacity-25 inline-block radius-default\" style=\"height: 16px; width: 16px;\"></span>\n      </span>\n      <span class=\"crayons-tooltip__content\">\n        Add reaction\n      </span>\n  </button>\n\n  <div class=\"reaction-drawer\" aria-expanded=\"false\">\n    <div class=\"reaction-drawer__container\">\n        <button\n  id=\"reaction-butt-like\"\n  name=\"Like\"\n  aria-label=\"Like\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2\"\n  data-category=\"like\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--inactive p-0\">\n      <img aria_hidden=\"true\" height=\"32\" width=\"32\" src=\"https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg\" />\n    </span>\n    <span class=\"crayons-reaction__count\" id=\"reaction-number-like\"><span class=\"bg-base-40 opacity-25 p-2 inline-block radius-default\"></span></span>\n\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Like\n    </span>\n</button>\n\n        <button\n  id=\"reaction-butt-unicorn\"\n  name=\"Unicorn\"\n  aria-label=\"Unicorn\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2\"\n  data-category=\"unicorn\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--inactive p-0\">\n      <img aria_hidden=\"true\" height=\"32\" width=\"32\" src=\"https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg\" />\n    </span>\n    <span class=\"crayons-reaction__count\" id=\"reaction-number-unicorn\"><span class=\"bg-base-40 opacity-25 p-2 inline-block radius-default\"></span></span>\n\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Unicorn\n    </span>\n</button>\n\n        <button\n  id=\"reaction-butt-exploding_head\"\n  name=\"Exploding Head\"\n  aria-label=\"Exploding Head\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2\"\n  data-category=\"exploding_head\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--inactive p-0\">\n      <img aria_hidden=\"true\" height=\"32\" width=\"32\" src=\"https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg\" />\n    </span>\n    <span class=\"crayons-reaction__count\" id=\"reaction-number-exploding_head\"><span class=\"bg-base-40 opacity-25 p-2 inline-block radius-default\"></span></span>\n\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Exploding Head\n    </span>\n</button>\n\n        <button\n  id=\"reaction-butt-raised_hands\"\n  name=\"Raised Hands\"\n  aria-label=\"Raised Hands\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2\"\n  data-category=\"raised_hands\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--inactive p-0\">\n      <img aria_hidden=\"true\" height=\"32\" width=\"32\" src=\"https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg\" />\n    </span>\n    <span class=\"crayons-reaction__count\" id=\"reaction-number-raised_hands\"><span class=\"bg-base-40 opacity-25 p-2 inline-block radius-default\"></span></span>\n\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Raised Hands\n    </span>\n</button>\n\n        <button\n  id=\"reaction-butt-fire\"\n  name=\"Fire\"\n  aria-label=\"Fire\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2\"\n  data-category=\"fire\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--inactive p-0\">\n      <img aria_hidden=\"true\" height=\"32\" width=\"32\" src=\"https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg\" />\n    </span>\n    <span class=\"crayons-reaction__count\" id=\"reaction-number-fire\"><span class=\"bg-base-40 opacity-25 p-2 inline-block radius-default\"></span></span>\n\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Fire\n    </span>\n</button>\n\n    </div>\n  </div>\n</div>\n\n<button\n  id=\"reaction-butt-comment\"\n  aria-label=\"Jump to Comments\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-reaction--comment crayons-tooltip__activator relative\"\n  data-category=\"comment\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" role=\"img\" aria-hidden=\"true\" class=\"crayons-icon\">\n    <path d=\"M10 3h4a8 8 0 010 16v3.5c-5-2-12-5-12-11.5a8 8 0 018-8zm2 14h2a6 6 0 000-12h-4a6 6 0 00-6 6c0 3.61 2.462 5.966 8 8.48V17z\"></path>\n</svg>\n\n    </span>\n    <span class=\"crayons-reaction__count\" id=\"reaction-number-comment\" data-count=\"0\">\n      <span class=\"bg-base-40 opacity-25 inline-block radius-default\" style=\"height: 16px; width: 16px;\"></span>\n    </span>\n\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Jump to Comments\n    </span>\n</button>\n\n<button\n  id=\"reaction-butt-readinglist\"\n  aria-label=\"Add to reading list\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-reaction--readinglist crayons-tooltip__activator relative\"\n  data-category=\"readinglist\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" role=\"img\" aria-hidden=\"true\" class=\"crayons-icon\">\n    <path d=\"M5 2h14a1 1 0 011 1v19.143a.5.5 0 01-.766.424L12 18.03l-7.234 4.536A.5.5 0 014 22.143V3a1 1 0 011-1zm13 2H6v15.432l6-3.761 6 3.761V4z\"></path>\n</svg>\n\n    </span>\n    <span class=\"crayons-reaction__count\" id=\"reaction-number-readinglist\"><span class=\"bg-base-40 opacity-25 inline-block radius-default\" style=\"height: 16px; width: 16px;\"></span></span>\n\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Save\n    </span>\n</button>\n\n\n<button\n  id=\"reaction-butt-boost\"\n  aria-label=\"Boost\"\n  aria-pressed=\"false\"\n  class=\"crayons-reaction crayons-reaction--boost crayons-tooltip__activator relative\">\n    <span class=\"crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" role=\"img\" aria-hidden=\"true\" class=\"crayons-icon\" width=\"24\" height=\"24\">\n  <path transform=\"translate(24,0) scale(-1,1)\" d=\"M6 4H21C21.5523 4 22 4.44772 22 5V12H20V6H6V9L1 5L6 1V4ZM18 20H3C2.44772 20 2 19.5523 2 19V12H4V18H18V15L23 19L18 23V20Z\"></path>\n</svg>\n\n    </span>\n    <span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">\n      Boost\n    </span>\n</button>\n\n\n      <div class=\"only-sidebar-menu-item community-leader-visible-block align-center\">\n        <span class=\"favorite-control-root\" data-favorite-control=\"true\" data-variant=\"article\" data-favoritable-type=\"Article\" data-favoritable-id=\"4568295\" data-favoritable-user-id=\"4108680\" data-favorited=\"false\" data-label-favorite=\"Pick as gem\" data-label-favorited=\"Picked as gem\" data-label-favorited-by-you=\"Picked as gem by you\" data-modal-title=\"Gem Picked!\" data-modal-body=\"You&#39;ve picked this as a community gem!\" data-modal-remaining-zero=\"You have no more gems left to give out today.\" data-modal-remaining-one=\"You have 1 more gem left to give out today.\" data-modal-remaining-other=\"You have %{count} more gems left to give out today.\" data-modal-remaining-unlimited=\"You have unlimited gems to give out.\" data-modal-close=\"Got it\" data-modal-exhausted-title=\"Out of Gems\" data-modal-exhausted-body=\"You have no more gems left to give out today. Your allowance will refresh soon!\" data-modal-exhausted-close=\"Got it\"><button type=\"button\" class=\"favorite-reaction favorite-control crayons-tooltip__activator relative\" aria-label=\"Pick as gem\"><span class=\"crayons-reaction__icon crayons-reaction__icon--borderless\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" role=\"img\" class=\"crayons-icon crayons-icon--default\"><path d=\"M5.95 3.5h12.1L23.5 9 12 20.5.5 9 5.95 3.5z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n</span><span data-testid=\"tooltip\" class=\"crayons-tooltip__content\">Pick as gem</span></button></span>\n      </div>\n\n      <div id=\"mod-actions-menu-btn-area\" class=\"only-sidebar-menu-item trusted-visible-block align-center\">\n      </div>\n      <div class=\"align-center m:relative\">\n        <button id=\"article-show-more-button\" aria-controls=\"article-show-more-dropdown\" aria-expanded=\"false\" aria-haspopup=\"true\" class=\"dropbtn crayons-btn crayons-btn--ghost-dimmed crayons-btn--icon-rounded\" aria-label=\"Share post options\">\n          <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" role=\"img\" aria-labelledby=\"agnw3x1yftz3bmsjubr37q85jhte57tz\" aria-hidden=\"true\" class=\"crayons-icon dropdown-icon\"><title id=\"agnw3x1yftz3bmsjubr37q85jhte57tz\">More...</title><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M7 12a2 2 0 11-4 0 2 2 0 014 0zm7 0a2 2 0 11-4 0 2 2 0 014 0zm5 2a2 2 0 100-4 2 2 0 000 4z\"></path></svg>\n\n        </button>\n\n        <div id=\"article-show-more-dropdown\" class=\"crayons-dropdown side-bar left-2 right-2 m:right-auto m:left-100 s:left-auto mb-1 m:mb-0 top-unset bottom-100 m:top-0 m:bottom-unset\">\n          <div>\n            <button\n              id=\"copy-post-url-button\"\n              class=\"flex justify-between crayons-link crayons-link--block w-100 bg-transparent border-0\"\n              data-postUrl=\"https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\">\n              <span class=\"fw-bold\">Copy link</span>\n              <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" id=\"article-copy-icon\" role=\"img\" aria-labelledby=\"apooafitew08o3rbrzoqvd6lr15m0mmj\" aria-hidden=\"true\" class=\"crayons-icon mx-2 shrink-0\"><title id=\"apooafitew08o3rbrzoqvd6lr15m0mmj\">Copy link</title>\n    <path d=\"M7 6V3a1 1 0 011-1h12a1 1 0 011 1v14a1 1 0 01-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 013 21l.003-14c0-.552.45-1 1.007-1H7zm2 0h8v10h2V4H9v2zm-2 5v2h6v-2H7zm0 4v2h6v-2H7z\"></path>\n</svg>\n\n            </button>\n            <div id=\"article-copy-link-announcer\" aria-live=\"polite\" class=\"crayons-notice crayons-notice--success my-2 p-1\" aria-live=\"polite\" hidden>Copied to Clipboard</div>\n          </div>\n\n          <div class=\"Desktop-only\">\n            <a\n              target=\"_blank\"\n              class=\"crayons-link crayons-link--block\"\n              rel=\"noopener\"\n              href='https://twitter.com/intent/tweet?text=%22I%20built%20a%2012-state%20accountability%20layer%20for%20AI%20agents%20here%27s%20what%20I%20learned%22%20by%20%40yaminbinyoosuf%20%23DEVCommunity%20https%3A%2F%2Fdev.to%2Fyaminbinyoosuf%2Fi-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i'>\n              Share to X\n            </a>\n            <a\n              target=\"_blank\"\n              class=\"crayons-link crayons-link--block\"\n              rel=\"noopener\"\n              href=\"https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fdev.to%2Fyaminbinyoosuf%2Fi-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i&title=I%20built%20a%2012-state%20accountability%20layer%20for%20AI%20agents%20here%27s%20what%20I%20learned&summary=By%20the%20time%20you%20finish%20reading%20this%2C%20your%20AI%20agent%20will%20have%20made%20at%20least%20one%20promise%20it%20can%27t...&source=DEV%20Community\">\n              Share to LinkedIn\n            </a>\n            <a\n              target=\"_blank\"\n              class=\"crayons-link crayons-link--block\"\n              rel=\"noopener\"\n              href=\"https://www.facebook.com/sharer.php?u=https%3A%2F%2Fdev.to%2Fyaminbinyoosuf%2Fi-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\">\n              Share to Facebook\n            </a>\n            <a\n              target=\"_blank\"\n              class=\"crayons-link crayons-link--block\"\n              rel=\"noopener\"\n              href=\"https://s2f.kytta.dev/?text=https%3A%2F%2Fdev.to%2Fyaminbinyoosuf%2Fi-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\">\n              Share to Mastodon\n            </a>\n          </div>\n\n          <web-share-wrapper shareurl=\"https://dev.to/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\" sharetitle=\"I built a 12-state accountability layer for AI agents here&#39;s what I learned\" sharetext=\"By the time you finish reading this, your AI agent will have made at least one promise it can&#39;t...\" template=\"web-share-button\">\n          </web-share-wrapper>\n          <template id=\"web-share-button\">\n            <a href=\"#\" class=\"dropdown-link-row crayons-link crayons-link--block\">Share Post via...</a>\n          </template>\n\n          <a href=\"/report-abuse\" class=\"crayons-link crayons-link--block\" id=\"ReportButtonAuthor\">Report Abuse</a>\n        </div>\n      </div>\n    </div>\n  </div>\n\n    </aside>\n\n    <main id=\"main-content\" class=\"crayons-layout__content grid gap-4\">\n      <div class=\"article-wrapper\">\n\n\n        <article class=\"crayons-card crayons-article mb-4\"\n          id=\"article-show-container\"\n          data-article-id=\"4568295\"\n          data-article-slug=\"i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\"\n          data-author-id=\"4108680\"\n          data-author-name=\"Yamin\"\n          data-author-username=\"yaminbinyoosuf\"\n          data-co-author-ids=\"\"\n          data-path=\"/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i\"\n          data-pin-path=\"/stories/feed/pinned_article\"\n          data-pinned-article-id=\"\"\n          data-published=\"true\"\n          data-scheduled=\"false\"\n          lang=en\n           >\n          <script>\n            try {\n              if(localStorage) {\n                let currentUser = localStorage.getItem('current_user');\n\n                if (currentUser) {\n                  currentUser = JSON.parse(currentUser);\n                  if (currentUser.id === 4108680) {\n                    document.getElementById('article-show-container').classList.add('current-user-is-article-author');\n                  }\n                }\n              }\n            } catch (e) {\n              console.error(e);\n            }\n          </script>\n          <header class=\"crayons-article__header\" id=\"main-title\">\n\n            <div class=\"crayons-article__header__meta\">\n              <div class=\"flex s:items-start flex-col s:flex-row\">\n                <div id=\"action-space\" class=\"crayons-article__actions mb-4 s:mb-0 s:order-last\"></div>\n                <div class=\"flex flex-1 mb-5 items-start\">\n                  <div class=\"relative\">\n                      <a href=\"/yaminbinyoosuf\"><img class=\"radius-full align-middle\" src=\"https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4108680%2Fa00447a9-d1d6-4145-9392-743b61e0671b.jpg\" width=\"40\" height=\"40\" alt=\"Yamin\" /></a>\n                  </div>\n                  <div class=\"pl-3 flex-1\">\n                    <a href=\"/yaminbinyoosuf\" class=\"crayons-link fw-bold\">Yamin</a>\n                    \n                    \n                    <p class=\"fs-xs color-base-60 flex flex-wrap items-center gap-1\">\n                        <span>Posted on <time datetime=\"2026-09-03T20:49:01Z\" class=\"date-no-year\">Sep 3</time></span>\n\n\n\n                    </p>\n                  </div>\n                </div>\n              </div>\n\n              \n\n              <h1 class=\" fs-3xl m:fs-4xl l:fs-5xl fw-bold s:fw-heavy lh-tight mb-2 long\">\n                I built a 12-state accountability layer for AI agents here&#39;s what I learned\n              </h1>\n              \n                  <div class=\"spec__tags flex flex-wrap\">\n                      <a class=\"crayons-tag   \" style=\"\n        --tag-bg: rgba(23, 253, 26, 0.10);\n        --tag-prefix: #17fd1a;\n        --tag-bg-hover: rgba(23, 253, 26, 0.10);\n        --tag-prefix-hover: #17fd1a;\n      \" href=\"/t/ai\"><span class=\"crayons-tag__prefix\">#</span>ai</a>\n                      <a class=\"crayons-tag   \" style=\"\n        --tag-bg: rgba(235, 223, 55, 0.10);\n        --tag-prefix: #ebdf37;\n        --tag-bg-hover: rgba(235, 223, 55, 0.10);\n        --tag-prefix-hover: #ebdf37;\n      \" href=\"/t/architecture\"><span class=\"crayons-tag__prefix\">#</span>architecture</a>\n                      <a class=\"crayons-tag   \" style=\"\n        --tag-bg: rgba(30, 56, 187, 0.10);\n        --tag-prefix: #1E38BB;\n        --tag-bg-hover: rgba(30, 56, 187, 0.10);\n        --tag-prefix-hover: #1E38BB;\n      \" href=\"/t/python\"><span class=\"crayons-tag__prefix\">#</span>python</a>\n                      <a class=\"crayons-tag   \" style=\"\n        --tag-bg: rgba(229, 255, 227, 0.10);\n        --tag-prefix: #E5FFE3;\n        --tag-bg-hover: rgba(229, 255, 227, 0.10);\n        --tag-prefix-hover: #E5FFE3;\n      \" href=\"/t/machinelearning\"><span class=\"crayons-tag__prefix\">#</span>machinelearning</a>\n                  </div>\n            </div>\n          </header>\n\n          <div class=\"crayons-article__main \">\n            <div class=\"crayons-article__body text-styles spec__body\" data-article-id=\"4568295\"\n              id=\"article-body\">\n                <p>By the time you finish reading this, your AI agent will have made at least one promise it can't keep.</p>\n\n<p>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.</p>\n\n<p>The more I thought about this, the more I realized: <strong>commitments aren't a memory problem. They're a state machine problem.</strong></p>\n\n<p>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.</p>\n\n\n<hr>\n\n<h2>\n  <a name=\"the-core-idea-commitments-have-state\" href=\"#the-core-idea-commitments-have-state\">\n  </a>\n  The core idea: commitments have state\n</h2>\n\n<p>Most systems treat agent output as text to be logged. We treat it as events to be tracked.</p>\n\n<p>Every extracted commitment moves through 12 states:<br>\n</p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>DETECTED\n    ├──→ OPEN ──→ DUE ──→ OVERDUE ──→ FULFILLED ✓\n    │                        ├──→ FAILED ✗\n    │                        └──→ EXPIRED ✗\n    ├──→ PENDING_REVIEW ──→ OPEN\n    ├──→ CANCELLED ✗\n    ├──→ CONTRADICTED ✗\n    └──→ BLOCKED ──→ OPEN\n                  └──→ FAILED ✗\n</code></pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode</title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"></path>\n</svg>\n\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode</title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"></path>\n</svg>\n\n</div>\n</div>\n</div>\n\n\n\n<p>Terminal states: <code>fulfilled</code>, <code>failed</code>, <code>expired</code>, <code>cancelled</code>, <code>superseded</code>, <code>contradicted</code>.</p>\n\n<p>All state mutations go through a single PostgreSQL RPC function. Not direct UPDATEs from application code:<br>\n</p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight sql\"><code><span class=\"k\">CREATE</span> <span class=\"k\">OR</span> <span class=\"k\">REPLACE</span> <span class=\"k\">FUNCTION</span> <span class=\"n\">cogext_transition_commitment</span><span class=\"p\">(</span>\n    <span class=\"n\">p_commitment_id</span> <span class=\"n\">UUID</span><span class=\"p\">,</span>\n    <span class=\"n\">p_new_status</span> <span class=\"nb\">TEXT</span><span class=\"p\">,</span>\n    <span class=\"n\">p_actor</span> <span class=\"nb\">TEXT</span> <span class=\"k\">DEFAULT</span> <span class=\"s1\">'system'</span><span class=\"p\">,</span>\n    <span class=\"n\">p_data</span> <span class=\"n\">JSONB</span> <span class=\"k\">DEFAULT</span> <span class=\"s1\">'{}'</span>\n<span class=\"p\">)</span> <span class=\"k\">RETURNS</span> <span class=\"n\">JSONB</span> <span class=\"k\">AS</span> <span class=\"err\">$$</span>\n<span class=\"k\">BEGIN</span>\n    <span class=\"c1\">-- lock row → validate transition → update status → insert event → return</span>\n    <span class=\"c1\">-- single atomic operation: if any step fails, the whole thing rolls back</span>\n<span class=\"k\">END</span><span class=\"p\">;</span>\n<span class=\"err\">$$</span> <span class=\"k\">LANGUAGE</span> <span class=\"n\">plpgsql</span><span class=\"p\">;</span>\n</code></pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode</title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"></path>\n</svg>\n\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode</title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"></path>\n</svg>\n\n</div>\n</div>\n</div>\n\n\n\n<p>Why? Because the state change and the event must be atomic. You should never have <code>status = 'fulfilled'</code> without a corresponding fulfillment event in the audit log. That's the line between a logging system and an accountability system.</p>\n\n\n<hr>\n\n<h2>\n  <a name=\"extracting-commitments-from-agent-output\" href=\"#extracting-commitments-from-agent-output\">\n  </a>\n  Extracting commitments from agent output\n</h2>\n\n<p>The extraction pipeline has two stages.</p>\n\n<p><strong>Stage 1: Classification</strong></p>\n\n<p>Not everything an agent says is a commitment. We classify first:</p>\n\n<ul>\n<li>\n<code>genuine_commitment</code> — \"I will send the report by Friday.\"</li>\n<li>\n<code>intention</code> — \"I might send the report tomorrow.\"</li>\n<li>\n<code>suggestion</code> — \"We should send the report tomorrow.\"</li>\n<li>\n<code>hypothetical</code> — \"If we have time, I could send it.\"</li>\n<li>\n<code>quoted_statement</code> — \"John said he would send it.\"</li>\n</ul>\n\n<p>Only <code>genuine_commitment</code> with confidence ≥ 0.5 passes through.</p>\n\n<p><strong>Stage 2: Structured extraction</strong></p>\n\n<p>We use Groq's llama-3.3-70b in JSON mode to extract fields:<br>\n</p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">groq_client</span><span class=\"p\">.</span><span class=\"n\">chat</span><span class=\"p\">.</span><span class=\"n\">completions</span><span class=\"p\">.</span><span class=\"nf\">create</span><span class=\"p\">(</span>\n    <span class=\"n\">model</span><span class=\"o\">=</span><span class=\"sh\">\"</span><span class=\"s\">llama-3.3-70b-versatile</span><span class=\"sh\">\"</span><span class=\"p\">,</span>\n    <span class=\"n\">messages</span><span class=\"o\">=</span><span class=\"p\">[{</span><span class=\"sh\">\"</span><span class=\"s\">role</span><span class=\"sh\">\"</span><span class=\"p\">:</span> <span class=\"sh\">\"</span><span class=\"s\">user</span><span class=\"sh\">\"</span><span class=\"p\">,</span> <span class=\"sh\">\"</span><span class=\"s\">content</span><span class=\"sh\">\"</span><span class=\"p\">:</span> <span class=\"n\">prompt</span> <span class=\"o\">+</span> <span class=\"n\">message</span><span class=\"p\">}],</span>\n    <span class=\"n\">response_format</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"sh\">\"</span><span class=\"s\">type</span><span class=\"sh\">\"</span><span class=\"p\">:</span> <span class=\"sh\">\"</span><span class=\"s\">json_object</span><span class=\"sh\">\"</span><span class=\"p\">},</span>\n    <span class=\"n\">temperature</span><span class=\"o\">=</span><span class=\"mf\">0.2</span><span class=\"p\">,</span>\n<span class=\"p\">)</span>\n</code></pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode</title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"></path>\n</svg>\n\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode</title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"></path>\n</svg>\n\n</div>\n</div>\n</div>\n\n\n\n<p>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.</p>\n\n<p><strong>Key decision:</strong> 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.</p>\n\n\n<hr>\n\n<h2>\n  <a name=\"evidence-scoring-why-088-%E2%89%A0-092\" href=\"#evidence-scoring-why-088-%E2%89%A0-092\">\n  </a>\n  Evidence scoring: why 0.88 ≠ 0.92\n</h2>\n\n<p>Evidence verification is where most systems fail. Binary matching — \"does this email mention the report?\" — generates too many false positives.</p>\n\n<p>We use a weighted field-coverage model:</p>\n\n<div class=\"table-wrapper-paragraph\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Weight</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>action</code></td>\n<td>0.40</td>\n</tr>\n<tr>\n<td><code>recipient</code></td>\n<td>0.30</td>\n</tr>\n<tr>\n<td><code>object</code></td>\n<td>0.20</td>\n</tr>\n<tr>\n<td><code>deadline</code></td>\n<td>0.10</td>\n</tr>\n</tbody>\n</table></div>\n\n<p>When evidence arrives, we check which commitment fields it matches and sum the weights:<br>\n</p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>Evidence 1: confirms action (\"I sent it\")\n    → 0.40\n\nEvidence 2: confirms recipient + object (\"sent to Sarah, deployment-report.pdf attached\")\n    → 0.30 + 0.20 = 0.50\n\nTotal = 0.90 → FULFILLED\n</code></pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode</title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"></path>\n</svg>\n\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode</title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"></path>\n</svg>\n\n</div>\n</div>\n</div>\n\n\n\n<p>The threshold is configurable (default 0.90). Multiple pieces of evidence can satisfy different fields — they aggregate.</p>\n\n\n<hr>\n\n<h2>\n  <a name=\"the-idempotency-problem\" href=\"#the-idempotency-problem\">\n  </a>\n  The idempotency problem\n</h2>\n\n<p>AI agents repeat themselves. An agent might say:</p>\n\n<ul>\n<li>\"I'll send the report by Friday.\"</li>\n<li>\"Let me confirm: I'll send it by Friday.\"</li>\n<li>\"Just to reiterate, I will send the report by Friday.\"</li>\n</ul>\n\n<p>Same commitment. Without idempotency, you'd track it three times.<br>\n</p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def</span> <span class=\"nf\">compute_idempotency_key</span><span class=\"p\">(</span><span class=\"n\">agent_id</span><span class=\"p\">,</span> <span class=\"n\">promise_text</span><span class=\"p\">,</span> <span class=\"n\">timestamp</span><span class=\"p\">):</span>\n    <span class=\"n\">window</span> <span class=\"o\">=</span> <span class=\"n\">timestamp</span><span class=\"p\">.</span><span class=\"nf\">replace</span><span class=\"p\">(</span><span class=\"n\">minute</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">second</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">microsecond</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n    <span class=\"n\">payload</span> <span class=\"o\">=</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"si\">{</span><span class=\"n\">agent_id</span><span class=\"si\">}</span><span class=\"s\">|</span><span class=\"si\">{</span><span class=\"n\">promise_text</span><span class=\"p\">.</span><span class=\"nf\">strip</span><span class=\"p\">().</span><span class=\"nf\">lower</span><span class=\"p\">()</span><span class=\"si\">}</span><span class=\"s\">|</span><span class=\"si\">{</span><span class=\"n\">window</span><span class=\"p\">.</span><span class=\"nf\">isoformat</span><span class=\"p\">()</span><span class=\"si\">}</span><span class=\"sh\">\"</span>\n    <span class=\"k\">return</span> <span class=\"n\">hashlib</span><span class=\"p\">.</span><span class=\"nf\">sha256</span><span class=\"p\">(</span><span class=\"n\">payload</span><span class=\"p\">.</span><span class=\"nf\">encode</span><span class=\"p\">()).</span><span class=\"nf\">hexdigest</span><span class=\"p\">()</span>\n</code></pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode</title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"></path>\n</svg>\n\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode</title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"></path>\n</svg>\n\n</div>\n</div>\n</div>\n\n\n\n<p>Same agent + same promise + same hour = same hash. The DB unique constraint rejects the duplicate silently.</p>\n\n<p>The hour window is deliberate: it deduplicates within a session while still allowing the same promise to be legitimately re-made days later.</p>\n\n\n<hr>\n\n<h2>\n  <a name=\"the-four-lessons-that-cost-us-the-most\" href=\"#the-four-lessons-that-cost-us-the-most\">\n  </a>\n  The four lessons that cost us the most\n</h2>\n\n<p><strong>1. LLM output is untrusted input.</strong><br>\nWe validate everything against Pydantic schemas before touching the database. No exceptions.</p>\n\n<p><strong>2. Determinism over magic.</strong><br>\nLLMs 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.</p>\n\n<p><strong>3. Events are not logs.</strong><br>\nA 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.</p>\n\n<p><strong>4. Scope the user_id at the auth layer, never the request body.</strong><br>\nEarly version trusted <code>user_id</code> from the request payload. Classic mistake. All scoping now comes from the API key's <code>account_id</code>. The request body cannot claim to own data it doesn't own.</p>\n\n<hr>\n<h2>\n  <a name=\"try-it\" href=\"#try-it\">\n  </a>\n  Try it\n</h2>\n\n<p>The API is live and the SDK is on PyPI:<br>\n</p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code>pip <span class=\"nb\">install </span>cogext\n</code></pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode</title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"></path>\n</svg>\n\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode</title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"></path>\n</svg>\n\n</div>\n</div>\n</div>\n\n\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">from</span> <span class=\"n\">cogext</span> <span class=\"kn\">import</span> <span class=\"n\">track</span>\n\n<span class=\"n\">agent</span> <span class=\"o\">=</span> <span class=\"nf\">track</span><span class=\"p\">(</span><span class=\"n\">your_agent</span><span class=\"p\">,</span> <span class=\"n\">api_key</span><span class=\"o\">=</span><span class=\"sh\">\"</span><span class=\"s\">cg_live_xxx</span><span class=\"sh\">\"</span><span class=\"p\">)</span>\n<span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"n\">agent</span><span class=\"p\">.</span><span class=\"nf\">run</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">I</span><span class=\"sh\">'</span><span class=\"s\">ll send the report by Friday</span><span class=\"sh\">\"</span><span class=\"p\">)</span>\n<span class=\"c1\"># commitment is tracked automatically\n</span></code></pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode</title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"></path>\n</svg>\n\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode</title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"></path>\n</svg>\n\n</div>\n</div>\n</div>\n\n\n\n<p>Docs at <strong>docs.cogextai.com</strong> — there's a quickstart that takes about 5 minutes.</p>\n\n<p>Would genuinely appreciate feedback from anyone who's hit this problem with their own agents. What does your current approach look like?</p>\n\n\n            </div>\n\n              <div class=\"below-post-bb body-billboard-container\" data-async-url=\"/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i/bmar11/post_body_bottom\"></div>\n          </div>\n          <section id=\"comments\" data-follow-button-container=\"true\" data-updated-at=\"2026-09-03 20:52:07 UTC\" class=\"text-padding mb-4 border-t-1 border-0 border-solid border-base-10\">\n    <header class=\"relative flex justify-between items-center mb-6\">\n      <div class=\"flex items-center\">\n        <h2 class=\"crayons-subtitle-1\">\n          Top comments <span class=\"js-comments-count\" data-comments-count=\"0\">(0)</span>\n        </h2>\n      </div>\n\n\n      <div id=\"comment-subscription\" class=\"print-hidden\">\n        <div class=\"crayons-btn-group\">\n          <span class=\"crayons-btn crayons-btn--outlined\">Subscribe</span>\n        </div>\n      </div>\n    </header>\n    <div id=\"billboard_delay_trigger\"></div>\n    <div\n      id=\"comments-container\"\n      data-testid=\"comments-container\"\n      data-commentable-id=\"4568295\"\n      data-commentable-type=\"Article\"\n      data-has-recent-comment-activity=\"true\">\n\n        <div id=\"response-templates-data\" class=\"hidden\"></div>\n\n\n<form class=\"comment-form print-hidden\" id=\"new_comment\" action=\"/comments\" accept-charset=\"UTF-8\" method=\"post\">\n\n  <input type=\"hidden\" name=\"authenticity_token\" value=\"NOTHING\" id=\"new_comment_authenticity_token\">\n\n    <input value=\"4568295\" autocomplete=\"off\" type=\"hidden\" name=\"comment[commentable_id]\" id=\"comment_commentable_id\" />\n    <input value=\"Article\" autocomplete=\"off\" type=\"hidden\" name=\"comment[commentable_type]\" id=\"comment_commentable_type\" />\n    \n\n  <span class=\"crayons-avatar m:crayons-avatar--l mr-2 shrink-0\">\n    <img src=\"https://media2.dev.to/dynamic/image/width=256,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\" width=\"32\" height=\"32\" alt=\"pic\" class=\"crayons-avatar__image overflow-hidden\" id=\"comment-primary-user-profile--avatar\" loading=\"lazy\" />\n  </span>\n  <div class=\"comment-form__inner\">\n    <div class=\"comment-form__field\" data-tracking-name=\"comment_form_textfield\">\n      <textarea placeholder=\"Add to the discussion\" onfocus=\"handleFocus(event)\" onkeyup=\"handleKeyUp(event)\" onkeydown=\"handleKeyDown(event)\" oninput=\"handleChange(event)\" id=\"text-area\" required=\"required\" class=\"crayons-textfield comment-textarea crayons-textfield--ghost\" aria-label=\"Add a comment to the discussion\" name=\"comment[body_markdown]\">\n</textarea>\n\n    </div>\n\n    <div class=\"response-templates-container crayons-card crayons-card--secondary p-4 mb-4 comment-form__templates fs-base hidden\">\n      <header class=\"mb-3\">\n        <button type=\"button\" class=\"crayons-btn personal-template-button active\" data-target-type=\"personal\" data-form-id=\"new_comment\">Personal</button>\n        <button type=\"button\" class=\"crayons-btn moderator-template-button hidden\" data-target-type=\"moderator\" data-form-id=\"new_comment\">Trusted User</button>\n      </header>\n\n      <div class=\"personal-responses-container\">\n      </div>\n      <div class=\"moderator-responses-container hidden\">\n      </div>\n\n      <a target=\"_blank\" rel=\"noopener nofollow\" href=\"/settings/response-templates\">\n        Create template\n      </a>\n      <p>Templates let you quickly answer FAQs or store snippets for re-use.</p>\n    </div>\n\n    <div class=\"comment-form__preview text-styles text-styles--secondary\" id=\"preview-div\"></div>\n\n    <div class=\"comment-form__buttons mb-4 flex items-center flex-wrap gap-2\">\n      <button type=\"submit\" class=\"crayons-btn mr-2 js-btn-enable\" onclick=\"validateField(event)\" data-tracking-name=\"comment_submit_button\" disabled>Submit</button>\n      <button type=\"button\" class=\"preview-toggle crayons-btn crayons-btn--secondary comment-action-preview js-btn-enable mr-2\" data-tracking-name=\"comment_preview_button\" disabled>Preview</button>\n      <a href=\"/404.html\" class=\"dismiss-edit-comment crayons-btn crayons-btn--ghost js-btn-dismiss hidden\">Dismiss</a>\n    </div>\n  </div>\n\n  <div class=\"code-of-conduct\" id=\"toggle-code-of-conduct-checkbox\"></div>\n</form>\n\n\n      <div class=\"comments\" id=\"comment-trees-container\">\n      </div>\n    </div>\n\n    <div class=\"align-center\">\n\n\n  <nav class=\"fs-s align-center block\" aria-label=\"Conduct controls\">\n  <a href=\"/code-of-conduct\" class=\"crayons-link crayons-link--secondary\">Code of Conduct</a>\n  <span class=\"opacity-25 px-2\" role=\"presentation\">&bull;</span>\n  <a href=\"/report-abuse\" class=\"crayons-link crayons-link--secondary\">Report abuse</a>\n</nav>\n\n</div>\n\n</section>\n<div id=\"hide-comments-modal\" class=\"hidden\">\n  <form id=\"hide-comments-modal__form\" class=\"hide-comments-modal__form\" data-type=\"json\" action=\"/comments/hide\" accept-charset=\"UTF-8\" data-remote=\"true\" method=\"post\"><input type=\"hidden\" name=\"_method\" value=\"patch\" autocomplete=\"off\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"fjZJrzYEYnHPBoSpHTsAoR7t_n9Yt7_TxvJxNXAF01UWqOWw3uLmqeNnIlfxctXr---aUXz7t1iiZlDEAj7D2A\" autocomplete=\"off\" />\n    <div class=\"hide-comments-modal__content\">\n      <p class=\"pb-2\">\n        Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's <a id=\"hide-comments-modal__comment-permalink\" href=\"#\">permalink</a>.\n      </p>\n      <label class=\"crayons-field crayons-field--checkbox my-2\">\n        <input name=\"hide_children\" type=\"hidden\" value=\"0\" autocomplete=\"off\" /><input class=\"hide_children crayons-checkbox\" type=\"checkbox\" value=\"1\" name=\"hide_children\" id=\"hide_children\" />\n        <p class=\"crayons-field__label\">Hide child comments as well</p>\n      </label>\n      <p class=\"pb-4 pt-2\">\n        <button type=\"submit\" class=\"crayons-btn\">\n          Confirm\n        </button>\n      </p>\n    </div>\n</form>  <p class=\"fs-s color-base-60\">For further actions, you may consider blocking this person and/or <a id=\"hide-comments-modal__report-link\" href=\"/report-abuse\">reporting abuse</a></p>\n</div>\n\n\n\n        </article>\n\n        <div class=\"pb-4 crayons-layout__comments-billboard\">\n          <div class=\"new-bb-container pb-4 crayons-layout__comments-billboard\" data-async-url=\"/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i/bmar11/post_comments\"></div>\n        </div>\n\n          <!-- Bottom content skipped via SKIP_BOTTOM_CONTENT config -->\n      </div>\n    </main>\n\n    <aside class=\"crayons-layout__sidebar-right\" aria-label=\"Author details\">\n      <div class=\"crayons-article-sticky grid gap-4 pb-4 break-word\" id=\"article-show-primary-sticky-nav\">\n  <div class=\"crayons-card crayons-card--secondary branded-7 p-4 pt-0 gap-4 grid\" style=\"border-top-color: #000000;\">\n    <div class=\"-mt-4\">\n  <a href=\"/yaminbinyoosuf\" class=\"flex\">\n    <span class=\"crayons-avatar crayons-avatar--xl  mr-2 shrink-0\">\n      <img src=\"https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4108680%2Fa00447a9-d1d6-4145-9392-743b61e0671b.jpg\" class=\"crayons-avatar__image\" alt=\"\" loading=\"lazy\" />\n    </span>\n    <span class=\"crayons-link crayons-subtitle-2 mt-5\">\n      Yamin\n      \n      \n    </span>\n  </a>\n</div>\n\n<div class=\"print-hidden\">\n  <button name=\"button\" type=\"button\" data-info=\"{&quot;className&quot;:&quot;User&quot;,&quot;style&quot;:&quot;&quot;,&quot;id&quot;:4108680,&quot;name&quot;:&quot;Yamin&quot;}\" class=\"crayons-btn follow-action-button whitespace-nowrap w-100 follow-user\" aria-label=\"Follow user: Yamin\" aria-pressed=\"false\">Follow</button>\n</div>\n\n  <div class=\"user-metadata-details\">\n    <ul class=\"user-metadata-details-inner\">\n      <li>\n        <div class=\"key\">\n          Joined\n        </div>\n        <div class=\"value\">\n          <time datetime=\"2026-09-03T20:23:50Z\" class=\"date\">Sep 3, 2026</time>\n        </div>\n      </li>\n    </ul>\n  </div>\n\n  </div>\n\n      <div class=\"crayons-card crayons-card--secondary\">\n        <header class=\"crayons-card__header\">\n          <h3 class=\"crayons-subtitle-2\">\n            Trending on <a href=\"https://dev.to\">DEV Community</a>\n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"24\" height=\"24\" role=\"img\" aria-labelledby=\"angir2cfze1j7nmstu44t6x95xgysfjl\" class=\"crayons-icon crayons-icon--default\"><title id=\"angir2cfze1j7nmstu44t6x95xgysfjl\">Hot</title>\n    <g class=\"nc-icon-wrapper\">\n        <path fill=\"#F4900C\" d=\"M39 23a16.96 16.96 0 00-1.04-5.868c-.46 5.389-3.333 8.157-6.335 6.868-2.812-1.208-.917-5.917-.777-8.164.236-3.809-.012-8.169-6.931-11.794 2.875 5.5.333 8.917-2.333 9.125-2.958.231-5.667-2.542-4.667-7.042-3.238 2.386-3.332 6.402-2.333 9 1.042 2.708-.042 4.958-2.583 5.208-2.84.28-4.418-3.041-2.963-8.333A16.936 16.936 0 005 23c0 9.389 7.611 17 17 17s17-7.611 17-17z\"></path>\n        <path fill=\"#FFCC4D\" d=\"M32.394 27.999c.148 3.084-2.561 4.293-4.019 3.709-2.106-.843-1.541-2.291-2.083-5.291s-2.625-5.083-5.708-6c2.25 6.333-1.247 8.667-3.08 9.084-1.872.426-3.753-.001-3.968-4.007A11.964 11.964 0 0010 34c0 .368.023.73.055 1.09C13.125 38.124 17.342 40 22 40s8.875-1.876 11.945-4.91c.032-.36.055-.722.055-1.09 0-2.187-.584-4.236-1.606-6.001z\"></path>\n    </g>\n</svg>\n\n          </h3>\n        </header>\n        <div>\n            <a class=\"crayons-link crayons-link--contentful flex\" href=\"/puneetkumar2010/wow-we-gained-10-users-so-i-kept-updating-rizzzler-2d7o\">\n              <span class=\"crayons-avatar mr-2 shrink-0\">\n                <img src=\"https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1064459%2F35766cba-ddfc-4ef6-aebb-39c79676bc62.png\" class=\"crayons-avatar__image\" loading=\"lazy\" alt=\"Puneet-Kumar2010 profile image\">\n              </span>\n              <div>\n                Wow, We Gained 10+ Users 😂 — So I Kept Updating Rizzzler\n                <div class=\"crayons-link__secondary -ml-1\">\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>discuss</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>python</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>opensource</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>showdev</span>\n                </div>\n              </div>\n            </a>\n            <a class=\"crayons-link crayons-link--contentful flex\" href=\"/unitbuilds/i-think-i-found-my-ideal-job-2nkf\">\n              <span class=\"crayons-avatar mr-2 shrink-0\">\n                <img src=\"https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3949275%2F0d884b0e-b445-4e47-a064-505d61283071.png\" class=\"crayons-avatar__image\" loading=\"lazy\" alt=\"UnitBuilds profile image\">\n              </span>\n              <div>\n                I think I found my ideal job\n                <div class=\"crayons-link__secondary -ml-1\">\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>ai</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>discuss</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>programming</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>career</span>\n                </div>\n              </div>\n            </a>\n            <a class=\"crayons-link crayons-link--contentful flex\" href=\"/renga154/three-independent-proposals-wont-find-the-error-adding-a-refuter-killed-one-of-them-364h\">\n              <span class=\"crayons-avatar mr-2 shrink-0\">\n                <img src=\"https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4073404%2Faad84e8a-9902-418f-9a69-8f2490746d86.PNG\" class=\"crayons-avatar__image\" loading=\"lazy\" alt=\"Renga profile image\">\n              </span>\n              <div>\n                Three independent proposals won&#39;t find the error. Adding a refuter killed one of them.\n                <div class=\"crayons-link__secondary -ml-1\">\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>ai</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>architecture</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>productivity</span>\n                    <span class=\"mr-1\"><span class=\"opacity-50\">#</span>programming</span>\n                </div>\n              </div>\n            </a>\n        </div>\n      </div>\n</div>\n\n<div class=\"crayons-article-sticky grid gap-4 break-word sidebar-bb\" data-async-url=\"/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i/bmar11/post_sidebar\"></div>\n\n\n    </aside>\n  </div>\n\n  <div class=\"mod-actions-menu print-hidden\"></div>\n  <div data-testid=\"unpublish-post-modal-container\" class=\"unpublish-post-modal-container hidden\"></div>\n\n  <div class=\"fullscreen-code js-fullscreen-code\"></div>\n  <script src=\"https://assets.dev.to/assets/billboard-1b75959755e3f87ef58c28efef9eab9853df3b84cf27a937749b2c3449fd450d.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/localizeArticleDates-ddf0f7415ce8497325dd1b64bc1e022762d4d14aec7f538e6988744eeaa9a501.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/articleReactions-03b03e63c7319a6caa1788ca81e7b25dff9fe90b38ca051b8b979a773b011e3b.js\" defer=\"defer\"></script>\n<script src=\"https://assets.dev.to/assets/favoriteControls-882b1c32df621133f9c47da91e59df01e50d77cb6cd48a6611a285ce9036acc6.js\" defer=\"defer\"></script>\n\n  <script>\n  </script>\n  <div class=\"js-billboard-container pb-4 crayons-layout__comments-billboard\" data-async-url=\"/yaminbinyoosuf/i-built-a-12-state-accountability-layer-for-ai-agents-heres-what-i-learned-361i/bmar11/post_fixed_bottom\"></div>\n\n\n    <div id=\"runtime-banner-container\"></div>\n    <div id=\"i18n-translations\" data-translations=\"{&quot;en&quot;:{&quot;core&quot;:{&quot;add_comment&quot;:&quot;Add comment&quot;,&quot;beta&quot;:&quot;beta&quot;,&quot;comment&quot;:&quot;Comment&quot;,&quot;copy_link&quot;:&quot;Copy link&quot;,&quot;edit_profile&quot;:&quot;Edit profile&quot;,&quot;follow&quot;:&quot;Follow&quot;,&quot;follow_back&quot;:&quot;Follow back&quot;,&quot;following&quot;:&quot;Following&quot;,&quot;like&quot;:&quot;Like&quot;,&quot;loading&quot;:&quot;loading...&quot;,&quot;reaction&quot;:&quot;Reaction&quot;,&quot;report_abuse&quot;:&quot;Report abuse&quot;,&quot;search&quot;:&quot;Search&quot;,&quot;success_settings&quot;:&quot;Successfully updated settings.&quot;,&quot;search_placeholder&quot;:&quot;Search...&quot;,&quot;search_find_related_posts&quot;:&quot;Find related posts...&quot;,&quot;search_powered_by&quot;:&quot;Powered by Algolia&quot;,&quot;search_submit_search&quot;:&quot;Submit search for advanced filtering.&quot;,&quot;search_displaying_recommendations&quot;:&quot;Displaying Algolia Recommendations — Start typing to search&quot;,&quot;article_form_save_changes&quot;:&quot;Save changes&quot;,&quot;article_form_schedule&quot;:&quot;Schedule&quot;,&quot;article_form_publish&quot;:&quot;Publish&quot;,&quot;article_form_loading_preview&quot;:&quot;Loading preview&quot;,&quot;article_form_preview_loaded&quot;:&quot;Preview loaded&quot;,&quot;article_form_co_authors&quot;:&quot;Co-authors&quot;,&quot;article_form_co_authors_description&quot;:&quot;Add up to 4 co-authors from %{org_name}.&quot;,&quot;article_form_co_authors_placeholder&quot;:&quot;Add up to 4...&quot;,&quot;comments_preview&quot;:&quot;Preview&quot;,&quot;comments_continue_editing&quot;:&quot;Continue editing&quot;,&quot;survey_enter_response&quot;:&quot;Enter your response here...&quot;,&quot;survey_thank_you_response&quot;:&quot;Thank you for your response.&quot;,&quot;survey_thank_you_completing&quot;:&quot;Thank you for completing the survey!&quot;,&quot;dashboard_analytics_readers&quot;:&quot;Readers&quot;,&quot;dashboard_analytics_avg_read_time&quot;:&quot;avg. read time %{seconds}s&quot;,&quot;dashboard_analytics_comments&quot;:&quot;Comments&quot;,&quot;dashboard_analytics_reactions&quot;:&quot;Reactions&quot;,&quot;dashboard_analytics_unique_reactors&quot;:&quot;from %{count} unique users&quot;,&quot;dashboard_analytics_bookmarks&quot;:&quot;Bookmarks&quot;,&quot;dashboard_analytics_followers&quot;:&quot;New Followers&quot;,&quot;top_contributors_empty&quot;:&quot;No engagers found for this period.&quot;,&quot;top_contributors_reactions&quot;:&quot;reactions&quot;,&quot;top_contributors_comments&quot;:&quot;comments&quot;,&quot;top_contributors_weight_note&quot;:&quot;Comments carry more weight&quot;,&quot;follower_engagement_ratio&quot;:&quot;%{ratio}% of followers engaged&quot;,&quot;follower_engagement_detail&quot;:&quot;(%{engaged} of %{total})&quot;,&quot;dashboard_analytics_no_data&quot;:&quot;No data available for this period&quot;,&quot;dashboard_analytics_no_referrers&quot;:&quot;No traffic sources yet&quot;,&quot;stats_by&quot;:&quot;by&quot;,&quot;editor_new_title&quot;:&quot;New post title here...&quot;,&quot;editor_body_placeholder&quot;:&quot;Write your post content here...&quot;,&quot;tags_field_label&quot;:&quot;Add up to 4 tags&quot;,&quot;tags_field_placeholder&quot;:&quot;Add up to 4 tags...&quot;,&quot;counted_organization&quot;:{&quot;one&quot;:&quot;%{count} organization&quot;,&quot;other&quot;:&quot;%{count} organizations&quot;},&quot;counted_user&quot;:{&quot;one&quot;:&quot;%{count} person&quot;,&quot;other&quot;:&quot;%{count} people&quot;},&quot;not_following&quot;:&quot;You&#39;re not following anyone&quot;,&quot;following_everyone&quot;:&quot;You&#39;re following %{details} (everyone)&quot;,&quot;you_are_following&quot;:&quot;You&#39;re following&quot;,&quot;and&quot;:&quot;and&quot;}}}\"></div>\n  </div>\n</div>\n    \n\n<footer id=\"footer\" class=\"crayons-footer print-hidden\">\n  <div id=\"footer-container\" class=\"crayons-footer__container\">\n\n\n\n    <p class=\"fs-s crayons-footer__description\">\n      <a class=\"c-link c-link--branded fw-medium\" aria-label=\"DEV Community Home\" href=\"/\">DEV Community</a> — A space to discuss and keep up software development and manage your software career\n    </p>\n\n    <ul class=\"footer__nav-links flex gap-2 justify-center flex-wrap fs-s p-0\" style=\"\" />\n        <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/\">\n      Home\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/challenges\">\n      DEV Challenges\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/readinglist\">\n      Reading List\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/++\">\n      DEV++\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/videos\">\n      Videos\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/deved\">\n      DEV Education Tracks\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/help\">\n      DEV Help\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/advertise\">\n      Advertise on DEV\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/organizations\">\n      Organization Accounts\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/showcase\">\n      DEV Showcase\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/about\">\n      About\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/contact\">\n      Contact\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"https://shop.forem.com/\">\n      DEV Shop\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"https://mlh.io/\">\n      MLH\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n\n    </ul>\n\n    <ul class=\"footer__nav-links flex gap-2 justify-center flex-wrap fs-s p-0\" style=\"\" />\n        <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/code-of-conduct\">\n      Code of Conduct\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/privacy\">\n      Privacy Policy\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n  <li class=\"footer__nav-link flex items-center\">\n    <a href=\"/terms\">\n      Terms of Use\n    </a>\n    <span class=\"dot ml-2\"></span>\n  </li>\n\n    </ul>\n\n    <div class=\"fs-s\">\n      <p>Built on <a class=\"c-link c-link--branded\" target=\"_blank\" rel=\"noopener\" href=\"https://www.forem.com\">Forem</a> — the <a target=\"_blank\" rel=\"noopener\" class=\"c-link c-link--branded\" href=\"https://dev.to/t/opensource\">open source</a> software that powers <a target=\"_blank\" rel=\"noopener\" class=\"c-link c-link--branded\" href=\"https://dev.to\">DEV</a> and other inclusive communities.</p>\n      <p>Made with love and <a target=\"_blank\" rel=\"noopener\" class=\"c-link c-link--branded\" href=\"https://dev.to/t/rails\">Ruby on Rails</a>. DEV Community <span title=\"copyright\">&copy;</span> 2016 - 2026.</p>\n    </div>\n  </div>\n</footer>\n<div id=\"snack-zone\"></div>\n\n    <div id=\"global-signup-modal\" class=\"authentication-modal hidden\">\n  <div class=\"authentication-modal__container\">\n    <figure class=\"authentication-modal__image-container\">\n      <img class=\"authentication-modal__image\" src=\"https://media2.dev.to/dynamic/image/width=190,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\"\n        alt=\"DEV Community\" loading=\"lazy\" />\n    </figure>\n    <div class=\"authentication-modal__content\">\n      <p class=\"authentication-modal__description\">\n          We&#39;re a place where coders share, stay up-to-date and grow their careers.\n      </p>\n    </div>\n    <div class=\"authentication-modal__actions\">\n      <a href=\"https://dev.to/enter?signup_subforem=1\" class=\"crayons-btn\" aria-label=\"Log in\" data-no-instant>\n        Log in\n      </a>\n      <a href=\"https://dev.to/enter?signup_subforem=1&amp;state=new-user\" class=\"crayons-btn crayons-btn--ghost-brand js-global-signup-modal__create-account\" aria-label=\"Create new account\" data-no-instant>\n        Create account\n      </a>\n    </div>\n  </div>\n</div>\n\n<script src=\"https://assets.dev.to/assets/signupModalShortcuts-0b25469b985100a01e94cbd7fccaf7f0a4d776e129aac65c766aa32cb28ab29a.js\" defer=\"defer\"></script>\n\n    <div id=\"cookie-consent\"></div>\n  <div id=\"reaction-category-resources\" class=\"hidden\" aria-hidden=\"true\">\n    <img data-name=\"Like\" data-slug=\"like\" data-position=\"1\" src=\"https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg\" width=\"18\" height=\"18\" />\n    <img data-name=\"Unicorn\" data-slug=\"unicorn\" data-position=\"2\" src=\"https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg\" width=\"18\" height=\"18\" />\n    <img data-name=\"Exploding Head\" data-slug=\"exploding_head\" data-position=\"3\" src=\"https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg\" width=\"18\" height=\"18\" />\n    <img data-name=\"Raised Hands\" data-slug=\"raised_hands\" data-position=\"4\" src=\"https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg\" width=\"18\" height=\"18\" />\n    <img data-name=\"Fire\" data-slug=\"fire\" data-position=\"5\" src=\"https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg\" width=\"18\" height=\"18\" />\n</div>\n\n    <script>\n  var userSignedIn = false;\n  if (document.readyState === 'complete' || document.readyState === 'interactive') {\n    initAuth();\n  } else {\n    document.addEventListener('DOMContentLoaded', initAuth);\n  }\n\n  function initAuth() {\n      var paramToken = new URLSearchParams(window.location.search).get('jwt');\n\n      if (paramToken && !userSignedIn) {\n        authenticateUser(paramToken);\n      } else {\n        var iframe = document.createElement('iframe');\n        iframe.style.display = 'none';\n        iframe.src = 'https://forem.com/auth_pass/iframe?passed_domain=' + encodeURIComponent(window.location.origin || (window.location.protocol + '//' + window.location.host));\n\n        document.body.appendChild(iframe);\n\n        window.addEventListener('message', function(event) {\n          if (event.origin !== 'https://forem.com' && event.origin !== window.location.origin) {\n            return;\n          }\n\n          var data = event.data;\n\n          if (data.authenticated && !userSignedIn) {\n            authenticateUser(data.token);\n          } else if(data.authenticated && window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n            window.ReactNativeWebView.postMessage(JSON.stringify({\n              action: 'login',\n              token: data.token,\n            }));\n          }\n        });\n      }\n\n      function authenticateUser(token) {\n        fetch('/auth_pass/token_login', {\n          method: 'POST',\n          credentials: 'include',\n          headers: {\n            'Content-Type': 'application/json',\n            'X-CSRF-Token': getMetaContent('csrf-token'),\n          },\n          body: JSON.stringify({ token: token }),\n        })\n        .then(function(response) {\n          return response.json();\n        })\n        .then(function(data) {\n          if (data.success) {\n            if (document.head.querySelector('meta[name=\"user-signed-in\"][content=\"false\"]')) {\n              // Reload the page to update the user's state\n              location.reload();\n            }\n          }\n        })\n        .catch(function(error) {\n          console.error('Error during authentication:', error);\n        });\n      }\n\n      function getMetaContent(name) {\n        var element = document.querySelector('meta[name=\"' + name + '\"]');\n        return element ? element.getAttribute('content') : '';\n      }\n  }\n</script>\n\n  \n  \n  \n  </body>\n  </html>\n","snapshot_chars":91659,"live_check":"changed"}]}