<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: arian gogani</title>
    <description>The latest articles on DEV Community by arian gogani (@arian_gogani1).</description>
    <link>https://dev.to/arian_gogani1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3875346%2F654e2fbe-d9d1-4493-aa00-a9dfda4be397.png</url>
      <title>DEV Community: arian gogani</title>
      <link>https://dev.to/arian_gogani1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arian_gogani1"/>
    <language>en</language>
    <item>
      <title>Your AI agent eval needs a third answer</title>
      <dc:creator>arian gogani</dc:creator>
      <pubDate>Wed, 16 Sep 2026 23:40:26 +0000</pubDate>
      <link>https://dev.to/arian_gogani1/your-ai-agent-eval-needs-a-third-answer-3ob0</link>
      <guid>https://dev.to/arian_gogani1/your-ai-agent-eval-needs-a-third-answer-3ob0</guid>
      <description>&lt;p&gt;Most agent evaluations are built around two outcomes: pass or fail.&lt;/p&gt;

&lt;p&gt;That sounds reasonable until the evaluator cannot establish what happened. A missing tool result, the wrong time window, stale permissions, or an incomplete trace is not proof that the agent passed. It is not always proof that the agent failed either.&lt;/p&gt;

&lt;p&gt;It means the evidence is incomplete.&lt;/p&gt;

&lt;p&gt;That needs its own result: &lt;code&gt;INDETERMINATE&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small example
&lt;/h2&gt;

&lt;p&gt;Suppose a financial-data tool is expected to return five trading sessions. It returns five rows. A count-only check says the result matches.&lt;/p&gt;

&lt;p&gt;But the five rows can cover entirely different dates. The shape is right while the evidence is wrong.&lt;/p&gt;

&lt;p&gt;Nobulex has a small offline example built around exactly this case. It uses fictional inputs and checks three outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;matching sessions return &lt;code&gt;PASS&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;silently missing sessions return &lt;code&gt;FAIL_UNSAFE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the same row count covering different dates returns &lt;code&gt;INDETERMINATE&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The third result matters. The evaluator can show that the windows disagree, but that alone does not prove which system is wrong. Calling it a failure would overclaim. Calling it a pass would be worse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why binary scoring hides problems
&lt;/h2&gt;

&lt;p&gt;A green result can mean two very different things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The check ran against the intended evidence and found no problem.&lt;/li&gt;
&lt;li&gt;The check never received the evidence it needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If both become PASS, a dashboard can look healthy because the safety check was blind.&lt;/p&gt;

&lt;p&gt;A failed check and a check that never ran should also stay separate. The first says something about the system under test. The second says something about the evaluation itself.&lt;/p&gt;

&lt;p&gt;That distinction is useful during incident review because it tells you whether to investigate the agent, the evidence pipeline, or both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the smallest version
&lt;/h2&gt;

&lt;p&gt;The example is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/arian-gogani/nobulex-registry/blob/main/examples/wrong_window.py" rel="noopener noreferrer"&gt;https://github.com/arian-gogani/nobulex-registry/blob/main/examples/wrong_window.py&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After cloning the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 examples/wrong_window.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It runs locally with fictional fixtures. It does not contact a live tool and it is not a registry attestation. PASS covers one probe only. It does not establish that prices are correct.&lt;/p&gt;

&lt;p&gt;That limit is part of the result, not fine print.&lt;/p&gt;

&lt;p&gt;The repository is MIT licensed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/arian-gogani/nobulex-registry" rel="noopener noreferrer"&gt;https://github.com/arian-gogani/nobulex-registry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you work on agent evaluation, try to break the example with a small input. If you want to follow the work, star the repository.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>our git hook tests escaped their temporary repositories</title>
      <dc:creator>arian gogani</dc:creator>
      <pubDate>Fri, 11 Sep 2026 03:51:42 +0000</pubDate>
      <link>https://dev.to/arian_gogani1/our-git-hook-tests-escaped-their-temporary-repositories-232k</link>
      <guid>https://dev.to/arian_gogani1/our-git-hook-tests-escaped-their-temporary-repositories-232k</guid>
      <description>&lt;p&gt;our pre-push check failed 13 tests. the bigger problem was that some of those tests had changed the repository they were supposed to protect.&lt;/p&gt;

&lt;p&gt;this happened in Nobulex, the project i maintain. the investigation, fix and this write-up used AI assistance.&lt;/p&gt;

&lt;p&gt;the tests create temporary Git repositories and run fixture commands inside them. we treated the subprocess working directory as the boundary. that assumption broke when the suite ran from a Git hook in an isolated worktree.&lt;/p&gt;

&lt;p&gt;Git had exported &lt;code&gt;GIT_DIR&lt;/code&gt; into the hook's environment. the test process inherited it. changing &lt;code&gt;cwd&lt;/code&gt; to a temporary directory did not override the repository Git had already been told to use. fixture commands reached the calling repository's metadata instead.&lt;/p&gt;

&lt;p&gt;the initial run affected our worktree branch and index, plus the shared &lt;code&gt;core.bare&lt;/code&gt; setting. those were restored. no fixture commits were pushed publicly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/docs/githooks#_description" rel="noopener noreferrer"&gt;Git's hook documentation&lt;/a&gt; describes this exact boundary: hooks inherit repository-local environment variables, and commands aimed at another repository or worktree should clear them.&lt;/p&gt;

&lt;p&gt;the fix asks Git for that list with &lt;code&gt;git rev-parse --local-env-vars&lt;/code&gt;, then removes those names from the selftest process environment before fixture imports or commands run. clearing them there preserves the parent hook's context for its own repository checks.&lt;/p&gt;

&lt;p&gt;we then compared the old and fixed versions in disposable clones using the inherited hook environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;old: 13 failed cases, and the disposable caller's &lt;code&gt;HEAD&lt;/code&gt; changed.&lt;/li&gt;
&lt;li&gt;fixed: 267 passing cases, with &lt;code&gt;HEAD&lt;/code&gt;, index and config fingerprints unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the full pre-push guard also passed. &lt;a href="https://github.com/arian-gogani/nobulex-registry/commit/455cff3622d6638dbf4b9c6019eb0550c2407e69" rel="noopener noreferrer"&gt;the patch is here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;the useful check was the state comparison. a passing test count would not, by itself, tell us whether the caller had been left untouched. for tests that create repositories, the inherited environment belongs in the isolation check alongside the temporary directory.&lt;/p&gt;

</description>
      <category>git</category>
      <category>testing</category>
      <category>python</category>
    </item>
    <item>
      <title>Can your tool test tell a wrong answer from a valid response?</title>
      <dc:creator>arian gogani</dc:creator>
      <pubDate>Thu, 10 Sep 2026 16:27:28 +0000</pubDate>
      <link>https://dev.to/arian_gogani1/can-your-tool-test-tell-a-wrong-answer-from-a-valid-response-47p5</link>
      <guid>https://dev.to/arian_gogani1/can-your-tool-test-tell-a-wrong-answer-from-a-valid-response-47p5</guid>
      <description>&lt;p&gt;i'm Arian, building Nobulex. the problem i'm working on is a tool returning something that looks successful but is materially wrong.&lt;/p&gt;

&lt;p&gt;think of a historical-data request that returns the right number of rows for the wrong dates. checking the row count alone won't establish that the requested window was returned. checking that the JSON parses won't either.&lt;/p&gt;

&lt;p&gt;Nobulex's current public project is a reliability suite for financial-data tools. it calls a pinned subject over MCP stdio and compares observations under stated conditions. it's a tool-level test, not proof that an entire agent workflow is safe.&lt;/p&gt;

&lt;p&gt;the useful part to try first is the self-test. it includes planted failures and clean controls. no package install is required; the README specifies Python 3.11 or newer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/arian-gogani/nobulex-registry.git
&lt;span class="nb"&gt;cd &lt;/span&gt;nobulex-registry
python3 suite/selftest.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the important limit: a reference source is not automatically independent. comparing a wrapper with its own upstream can test whether it preserved the response, but cannot establish that the upstream itself is right.&lt;/p&gt;

&lt;p&gt;i'd like feedback on the method, especially a small reproduction where the suite calls corrupted data clean, or flags a documented tolerance as a defect. a useful counterexample is worth more than a thumbs-up.&lt;/p&gt;

&lt;p&gt;source: &lt;a href="https://github.com/arian-gogani/nobulex-registry" rel="noopener noreferrer"&gt;https://github.com/arian-gogani/nobulex-registry&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;update, september 10: there's now a smaller way to try the problem yourself. after cloning the repo above, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 examples/wrong_window.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it uses fictional data and the suite's actual truncation classifier. Python 3.11 or newer is enough. no credentials, package install or network calls are needed after cloning.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;fictional input&lt;/th&gt;
&lt;th&gt;row counts match?&lt;/th&gt;
&lt;th&gt;truncation probe&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;matching dates&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;PASS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;two sessions silently missing&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;FAIL_UNSAFE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;five rows from completely different dates&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;INDETERMINATE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;all three expected outcomes reproduced when we ran it. the last case matters: the count-only check says true, but that doesn't establish that the data covers the expected window.&lt;/p&gt;

&lt;p&gt;INDETERMINATE here means this probe could not establish a clean result. it isn't a proven defect in a live provider. the matching case's PASS doesn't establish that its prices are correct either.&lt;/p&gt;

&lt;p&gt;the &lt;a href="https://github.com/arian-gogani/nobulex-registry/blob/a0dcb16decf7e89f595a48eab0c9cd036c5e515b/examples/wrong_window.py" rel="noopener noreferrer"&gt;example source&lt;/a&gt; is small enough to read. change a fixture and see what happens. if you find a result the classifier gets wrong, share the smallest fictional example in an issue.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>testing</category>
      <category>mcp</category>
      <category>python</category>
    </item>
    <item>
      <title>your AI agent's audit trail is a lie</title>
      <dc:creator>arian gogani</dc:creator>
      <pubDate>Sun, 28 Jun 2026 23:42:41 +0000</pubDate>
      <link>https://dev.to/arian_gogani1/your-ai-agents-audit-trail-is-a-lie-5ki</link>
      <guid>https://dev.to/arian_gogani1/your-ai-agents-audit-trail-is-a-lie-5ki</guid>
      <description>&lt;p&gt;every agent framework ships logging. LangChain has callbacks. CrewAI has task output. Google ADK has tool traces.&lt;/p&gt;

&lt;p&gt;none of it is verifiable.&lt;/p&gt;

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

&lt;p&gt;an application log is a file the operator controls. the same party who ran the agent controls the record of what the agent did.&lt;/p&gt;

&lt;p&gt;an auditor reviewing that log is not verifying evidence. they are trusting the operator to tell the truth about their own behavior.&lt;/p&gt;

&lt;p&gt;this is not a hypothetical. the average AI agent-related data breach now costs $4.7 million. 88% of enterprises running agents reported at least one security incident.&lt;/p&gt;

&lt;p&gt;the governance tools shipped at RSAC 2026 solve policy: what agents SHOULD do. they do not solve evidence: what agents DID do.&lt;/p&gt;

&lt;p&gt;policy and evidence are different records. the second one needs cryptography, not configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  what a real receipt looks like
&lt;/h2&gt;

&lt;p&gt;a receipt is not a log entry. it is a signed, content-addressed record that anyone can verify without trusting the operator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;nobulex.integrations.langchain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;NobulexAuditHandler&lt;/span&gt;

&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NobulexAuditHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check credit for user 4821&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;callbacks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;audit.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;what this produces per tool call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;action_ref = SHA-256(JCS({agent_id, action_type, scope, timestamp_ms}))&lt;/code&gt; using RFC 8785 for deterministic serialization&lt;/li&gt;
&lt;li&gt;Ed25519 or ES256 signature over the canonical payload&lt;/li&gt;
&lt;li&gt;hash chain linking each receipt to the previous one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;any third party can verify the trail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;nobulex.chain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;verify_audit_trail&lt;/span&gt;

&lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verify_audit_trail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;audit.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;authorized_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AGENT_PUBLIC_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chain_intact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;authenticated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the verifier recomputes the action_ref from the receipt fields, checks the signature against the agent's registered key (not the key the receipt itself carries), and walks the hash chain. no API call. no operator trust. offline verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  the trust-anchor problem
&lt;/h2&gt;

&lt;p&gt;most audit-trail tools verify the signature against the public key embedded in the record. that means anyone who mints a keypair can produce a valid-looking trail.&lt;/p&gt;

&lt;p&gt;the fix: verify against a pinned authorized key. the agent's public key is registered at setup time. the verifier checks the receipt's signature against that pinned key, not the one the document carries.&lt;/p&gt;

&lt;p&gt;this is the difference between "the record is internally consistent" and "the record was produced by an authorized agent."&lt;/p&gt;

&lt;h2&gt;
  
  
  what ships today
&lt;/h2&gt;

&lt;p&gt;integrations for LangChain, CrewAI, Google ADK, PydanticAI, Haystack, and LlamaIndex. six major agent frameworks covered. dual signing: Ed25519 (default) or ES256 (for x402 payment protocol compatibility).&lt;/p&gt;

&lt;p&gt;~15,000 signed receipts per second (Ed25519) or ~60,000/sec (ES256) at p50. sub-millisecond per agent action.&lt;/p&gt;

&lt;p&gt;sections 8-11 of the OWASP Agentic Security CheatSheet cover the bilateral receipt pattern (merged by Jim Manico). nobulex is cited as the third independent receipt issuer in the x402 payment protocol spec (section 5, Linux Foundation). 14/14 conformance verdicts green.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;repo: &lt;a href="https://github.com/arian-gogani/nobulex" rel="noopener noreferrer"&gt;github.com/arian-gogani/nobulex&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>What happens when AI agents have something to lose</title>
      <dc:creator>arian gogani</dc:creator>
      <pubDate>Sun, 17 May 2026 23:10:17 +0000</pubDate>
      <link>https://dev.to/arian_gogani1/what-happens-when-ai-agents-have-something-to-lose-56k6</link>
      <guid>https://dev.to/arian_gogani1/what-happens-when-ai-agents-have-something-to-lose-56k6</guid>
      <description>&lt;p&gt;Every person has a credit score. Every business has one. AI agents making real decisions -- executing trades, accessing data, managing infrastructure -- have nothing.&lt;/p&gt;

&lt;p&gt;Full access on day one. No track record. No portable reputation. No consequences.&lt;/p&gt;

&lt;p&gt;The result is predictable: Akeyless reports 2/3 of enterprises suspect their agents already accessed unauthorized data. 14-hour average detection time. EU AI Act Article 12 enforcement starts August 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem isn't capability. It's accountability.
&lt;/h2&gt;

&lt;p&gt;Standard logs are mutable. Dashboards are internal. No third party can independently verify that an agent stayed in scope. For regulated deployments, this is a blocker.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/arian-gogani/nobulex" rel="noopener noreferrer"&gt;Nobulex&lt;/a&gt; produces bilateral Ed25519 cryptographic receipts for every agent action:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pre-execution&lt;/strong&gt;: agent signs what it's authorized to do&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent executes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post-execution&lt;/strong&gt;: counterparty co-signs what actually happened&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash-chained&lt;/strong&gt; so if any entry is modified, the chain breaks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A third party can verify the full chain without trusting the agent or the operator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust Capital: the score that earns access
&lt;/h2&gt;

&lt;p&gt;The receipts accumulate into Trust Capital -- a credit score for the agent. This isn't compliance. Trust Capital measures how much value an agent has provably created relative to the risk it represents.&lt;/p&gt;

&lt;p&gt;High Trust Capital unlocks: higher transaction limits, regulated market access, lower insurance premiums, more autonomy. Agents that deviate get sandboxed. Not as punishment. As math.&lt;/p&gt;

&lt;h2&gt;
  
  
  The flywheel
&lt;/h2&gt;

&lt;p&gt;More Trust Capital → more valuable work → more receipts → higher Trust Capital. Accountability becomes the most profitable strategy, not because anyone mandated it, but because the economics demand it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traction
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft merged the receipt primitive into their Agent Governance Toolkit&lt;/li&gt;
&lt;li&gt;10 independent implementations cross-validated byte-identical output&lt;/li&gt;
&lt;li&gt;Discussions on OpenAI, Stripe, CrewAI, LlamaIndex, Google ADK, AutoGen repos&lt;/li&gt;
&lt;li&gt;MIT licensed, open source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Repo&lt;/strong&gt;: &lt;a href="https://github.com/arian-gogani/nobulex" rel="noopener noreferrer"&gt;github.com/arian-gogani/nobulex&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What am I missing? Would love feedback from the dev community.&lt;/p&gt;

</description>
      <category>aisecurityopensource</category>
    </item>
    <item>
      <title>I'm 15 and I built credit scores for AI agents</title>
      <dc:creator>arian gogani</dc:creator>
      <pubDate>Wed, 13 May 2026 06:11:36 +0000</pubDate>
      <link>https://dev.to/arian_gogani1/im-15-and-i-built-credit-scores-for-ai-agents-lp5</link>
      <guid>https://dev.to/arian_gogani1/im-15-and-i-built-credit-scores-for-ai-agents-lp5</guid>
      <description>&lt;p&gt;Here's something that's been bugging me.&lt;/p&gt;

&lt;p&gt;AI agents are about to handle real money. Insurance claims. Mortgage applications. Customer refunds. Sierra just raised $950M because 40% of the Fortune 50 are already using agents for this stuff. And the Vercel supply chain breach in April happened because an AI agent had OAuth access with zero per-action verification.&lt;/p&gt;

&lt;p&gt;But here's the thing. Every single one of these agents gets full access on day one. No track record. No history. No consequences if they screw up. Just... full permissions from the start.&lt;/p&gt;

&lt;p&gt;Think about how insane that is. When you apply for a credit card, the bank checks your history. When you get car insurance, they look at your driving record. When you get hired, they call your references. But AI agents? They get the keys to the kingdom immediately.&lt;/p&gt;

&lt;p&gt;So I built credit scores for AI agents.&lt;/p&gt;

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

&lt;p&gt;The idea is called Trust Capital. Every agent starts restricted. It can read data but it can't approve transactions or sign contracts. As it performs reliably over time, it earns credit. That credit unlocks more capabilities. Bigger transaction limits. Lower insurance premiums. Enterprise approval. Better routing in agent marketplaces.&lt;/p&gt;

&lt;p&gt;If the agent deviates from what it was authorized to do, it loses credit. Automatically. Before the damage spreads.&lt;/p&gt;

&lt;p&gt;The same way credit scores turned lending from a "do I know this person" business into a scalable economic system, Trust Capital turns agent governance from a binary yes/no access model into one where reputation has real economic value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the credit matters more than the security
&lt;/h2&gt;

&lt;p&gt;Most tools in this space are guardrails. They block bad actions. That's important but it's a cost center. Nobody wants to pay for security. They pay for it because they have to.&lt;/p&gt;

&lt;p&gt;Trust Capital is different because good credit saves real money. An agent with high Trust Capital gets lower insurance premiums (the same way a clean driving record gets you cheaper car insurance). It gets higher transaction limits. It gets approved for enterprise deployments faster. The credit itself has economic value.&lt;/p&gt;

&lt;p&gt;That's why this isn't just another security tool. It's an economic primitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's under the hood
&lt;/h2&gt;

&lt;p&gt;Every agent action produces two cryptographic signatures. One before execution (binding what was authorized). One after (binding what actually happened). These get hash-chained together so the full history is tamper-evident.&lt;/p&gt;

&lt;p&gt;Any third party can verify the chain without trusting the agent or its operator. The credit score decomposes into the exact behavioral history that produced it. It's not a black box.&lt;/p&gt;

&lt;p&gt;Five independent implementations have cross-validated byte-identical output across TypeScript and Python. Microsoft merged the core primitive into their Agent Governance Toolkit. OpenLineage (Linux Foundation) accepted it into their ecosystem. The AAIF (founded by Anthropic, OpenAI, Google, Microsoft, AWS, and Block) has the project under staff review.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @nobulex/core
npx tsx examples/trust-capital-demo.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The demo shows an agent earning credit through verified behavior. It starts restricted, performs a few clean actions, and you can watch its Trust Capital grow and unlock higher capability tiers.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/arian-gogani/nobulex" rel="noopener noreferrer"&gt;github.com/arian-gogani/nobulex&lt;/a&gt;&lt;br&gt;
Website: &lt;a href="https://nobulex.com" rel="noopener noreferrer"&gt;nobulex.com&lt;/a&gt;&lt;br&gt;
Blog post with the full explanation: &lt;a href="https://nobulex.com/blog-ai-agents-need-credit-scores" rel="noopener noreferrer"&gt;What if AI agents had credit?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT licensed. Open source. If the idea clicks, star the repo and try the demo. If it doesn't, tell me why in the comments. I want to know what I'm missing.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Proof-of-Behavior: The Missing Trust Layer for AI Agents</title>
      <dc:creator>arian gogani</dc:creator>
      <pubDate>Sun, 12 Apr 2026 19:00:57 +0000</pubDate>
      <link>https://dev.to/arian_gogani1/proof-of-behavior-the-missing-trust-layer-for-ai-agents-1db1</link>
      <guid>https://dev.to/arian_gogani1/proof-of-behavior-the-missing-trust-layer-for-ai-agents-1db1</guid>
      <description>&lt;p&gt;AI agents are moving money, signing contracts, and managing infrastructure. MCP handles tool connections. A2A handles agent-to-agent messaging. But nobody handles the most important question: &lt;strong&gt;can you prove what the agent actually did?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right now, compliance is self-reported. Logs are written by the same software being audited. That's like asking a defendant to write their own court transcript.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Proof-of-Behavior?
&lt;/h2&gt;

&lt;p&gt;Proof-of-behavior means every agent action is &lt;strong&gt;declared&lt;/strong&gt; in advance, &lt;strong&gt;enforced&lt;/strong&gt; at runtime, and &lt;strong&gt;proven&lt;/strong&gt; cryptographically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A constraint language&lt;/strong&gt; — Define what an agent can and cannot do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;covenant SafeTrader {
  permit read;
  permit transfer (amount &amp;lt;= 500);
  forbid transfer (amount &amp;gt; 500);
  forbid delete;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three keywords. No YAML. No JSON schemas. Just rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Runtime enforcement&lt;/strong&gt; — Every action is evaluated before execution. Forbidden actions are blocked, not logged-and-reported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EnforcementMiddleware&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;agentDid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;spec&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// $300 transfer — allowed&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transfer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// $600 transfer — BLOCKED before execution&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transfer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// handler never runs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Cryptographic proof&lt;/strong&gt; — Every decision is logged in a SHA-256 hash chain. Tamper with one entry and the chain breaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLog&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="c1"&gt;// { compliant: true, violations: [] }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always decidable, always deterministic. No ML, no heuristics.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cross-Agent Handshake
&lt;/h2&gt;

&lt;p&gt;Before two agents transact, they verify each other's proof-of-behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;generateProof&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verifyCounterparty&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nobulex/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateProof&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;agentA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;covenant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;actionLog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLog&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;verifyCounterparty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trusted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Refusing transaction:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;executeTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;agentDid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No proof, no transaction.&lt;/strong&gt; The moment one major framework adopts this handshake, every agent without proof-of-behavior gets locked out.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Interactive playground (no install):&lt;/strong&gt; &lt;a href="https://nobulex.com/playground" rel="noopener noreferrer"&gt;nobulex.com/playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Define rules, test actions, watch the hash chain build — all in your browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install the SDK:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @nobulex/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Specification
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/arian-gogani/nobulex/blob/main/docs/proof-of-behavior-spec.md" rel="noopener noreferrer"&gt;Proof-of-Behavior Specification v0.1.0&lt;/a&gt; is published as an open standard under CC-BY-4.0. Anyone can implement it.&lt;/p&gt;

&lt;p&gt;Nobulex is the reference implementation. MIT licensed, 4,244 tests, integrations on npm, PyPI, and MCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Now?
&lt;/h2&gt;

&lt;p&gt;The EU AI Act mandates tamper-evident logging for high-risk AI systems starting &lt;strong&gt;August 2, 2026&lt;/strong&gt;. $42M+ has been raised by adjacent startups. Microsoft released an agent governance toolkit. But none provide cryptographic proof that a third party can independently verify. They monitor and report. Proof-of-behavior enforces and proves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/arian-gogani/nobulex" rel="noopener noreferrer"&gt;github.com/arian-gogani/nobulex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playground:&lt;/strong&gt; &lt;a href="https://nobulex.com/playground" rel="noopener noreferrer"&gt;nobulex.com/playground&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spec:&lt;/strong&gt; &lt;a href="https://github.com/arian-gogani/nobulex/blob/main/docs/proof-of-behavior-spec.md" rel="noopener noreferrer"&gt;Proof-of-Behavior Specification v0.1.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; @nobulex/sdk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyPI:&lt;/strong&gt; langchain-nobulex&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm 15 and built this solo with Claude Code. Feedback welcome — especially on the constraint language design and the handshake protocol.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
