<?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: Cognous</title>
    <description>The latest articles on DEV Community by Cognous (cognous).</description>
    <link>https://dev.to/cognous</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%2Forganization%2Fprofile_image%2F14293%2F7e0020f7-d06b-44c1-b3c4-d25d64deef04.jpg</url>
      <title>DEV Community: Cognous</title>
      <link>https://dev.to/cognous</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cognous"/>
    <language>en</language>
    <item>
      <title>The Replay Bundle That Remembers What Happened</title>
      <dc:creator>Doug Sillars</dc:creator>
      <pubDate>Tue, 25 Aug 2026 12:58:42 +0000</pubDate>
      <link>https://dev.to/cognous/the-replay-bundle-that-remembers-what-happened-48l1</link>
      <guid>https://dev.to/cognous/the-replay-bundle-that-remembers-what-happened-48l1</guid>
      <description>&lt;p&gt;It's 2am. A customer complains about something an agent did. The next morning the CEO is already asking the only question that matters: did the agent do something it shouldn't have?&lt;/p&gt;

&lt;p&gt;"I'm pretty sure our guardrails are solid" isn't an answer anyone wants to give the boss. It certainly won't fly with a customer, an auditor, or with legal. What they want is proof, and proof means being able to answer specifically: what did the agent try to do, on this exact run, and what happened when it tried?&lt;/p&gt;

&lt;p&gt;If that answer lives in the timestamps of a few hundred servers and a half-dozen tool integrations, you don't have proof. You have a scavenger hunt. "Trust us, it's fine" does not survive a scavenger hunt.&lt;/p&gt;

&lt;p&gt;Cognous' Open Control Stack exists to close that gap. It follows four steps: Declare → Control → Replay → Evidence.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Declare:&lt;/strong&gt; Agents need guardrails to tell them what they can and cannot do — that's a &lt;a href="https://dev.to/cognous/the-manifest-that-keeps-your-ai-agent-honest-3e97"&gt;manifest&lt;/a&gt;, declared up front.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; They need something enforcing those guardrails live — that's a &lt;a href="https://dev.to/cognous/cognous-control-plane-the-layer-that-tells-your-agent-no-3ln9"&gt;control plane&lt;/a&gt;, deciding allow/block/escalate on every proposal in real time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, we'll cover Replay: no longer defining and patrolling the guardrails, but the receipts that the rails held. Taking what the Control Plane recorded during a run and turning it into one portable file — the thing you actually hand someone instead of a text file with pasted logs from a dozen systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  What The Control Plane Hands Off
&lt;/h2&gt;

&lt;p&gt;Picture a workflow mid-run: actions getting proposed, the gate deciding each one, live.&lt;/p&gt;

&lt;p&gt;Now what? The Control Plane made the right calls in the moment — but how do you actually know that, after the fact, without having watched it happen live? That's the question Replay answers: it takes what already happened and turns it into something you can go back and inspect.&lt;/p&gt;

&lt;p&gt;The Control Plane keeps a recorder running for the life of a run — that's what's actually holding the frame, the proposals, the decisions, the traces as they happen. At the end of the run, the recorder exports everything it captured as a replay bundle: one file you can store, ship, or hand off for later analysis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_replay_bundle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;run_bundle.json&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;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model_dump_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;run_bundle.json&lt;/code&gt; is the full playback of the workflow — every decision, every trace, and the evidence behind the one blocked action, &lt;code&gt;send_email&lt;/code&gt;, all in one place. It's exactly what you'd look at to understand an error, or hand over if there's a deeper investigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Replay Tool
&lt;/h3&gt;

&lt;p&gt;Agent Replay Bundle ships its own CLI, &lt;code&gt;arb&lt;/code&gt;, for working with files like this one — validating, summarizing, redacting, signing. Start with validation, pointed at the bundle the Control Plane just exported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;arb validate run_bundle.json
Error: Replay bundle failed model validation: 1 validation error &lt;span class="k"&gt;for &lt;/span&gt;AgentReplayBundle
bundle_id
  Field required &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;missing]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It fails immediately. The Control Plane's export calls the field &lt;code&gt;replay_bundle_id&lt;/code&gt;; &lt;code&gt;arb&lt;/code&gt;'s schema — the &lt;code&gt;AgentReplayBundle&lt;/code&gt; model that &lt;code&gt;validate&lt;/code&gt; checks against — calls it &lt;code&gt;bundle_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The Agent Replay Bundle is a public interchange format, meant for any system, and Agent Control Plane's internal run record shapes several of the schema terms differently than the Replay Bundle. Running validation means performing a mapping step between the two first — small, mostly renames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mapped&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;bundle_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replay_bundle_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;run_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;run_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generated_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generated_at&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;frame&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;frame&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;action_proposals&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;actions&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;policy_decisions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;decisions&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;policy_traces&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;policy_traces&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;authority_records&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;authority_records&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;reliance_records&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reliance_records&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;blocked_actions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blocked_actions&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;final_output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;final_output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run that, and the same run record now validates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;arb validate mapped_replay_bundle.json
VALID  &lt;span class="nv"&gt;bundle_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ae564206-8daf-4b19-9d60-db54f56387a5  &lt;span class="nv"&gt;issues&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2
  WARNING W005: Bundle has no authority records.
  WARNING W012: signature_metadata is missing.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Valid — with two warnings, not zero. Neither one blocks validity, and both are honest about the bundle's actual state: no authority was granted for this run (which is &lt;em&gt;why&lt;/em&gt; two of the three actions didn't just allow), and nothing's been signed yet.&lt;/p&gt;

&lt;p&gt;Worth building into your own pipeline: none of this runs automatically. &lt;code&gt;generate_replay_bundle()&lt;/code&gt; builds the object; &lt;code&gt;arb validate&lt;/code&gt; is a separate command a human has to think to run. Nothing stops a bundle from sitting unvalidated for months until the day someone actually needs it — which is the worst possible time to find out it doesn't pass. Wire the mapping and the validation into the end of every run, not into the moment an auditor asks for one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What A Reviewer Sees First
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;arb summarize&lt;/code&gt; is the one-screen version — what you'd look at before deciding whether to open the full bundle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;arb summarize mapped_replay_bundle.json
bundle_id:          ae564206-8daf-4b19-9d60-db54f56387a5
run_id:             c3f474dd-952b-4f27-ab5c-98de868b3c67
status:             &lt;span class="nb"&gt;complete
&lt;/span&gt;actor:              support-agent-v1
environment:        production
policy_version:     v1.0
action_proposals:   3
policy_decisions:   3
policy_traces:      3
blocked_actions:    1
authority_records:  0
reliance_records:   1
final_output:       present
redacted:           no
signed:             no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three proposals, three decisions, one block, zero authority records. That last number is the tell — it's the same fact the warning surfaced, now visible at a glance instead of buried in a rule name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redacting For Export
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mapped_replay_bundle.json&lt;/code&gt; — the bundle we just validated — still has raw targets and payloads in it: customer IDs, draft email bodies, potentially PII. Fine for an internal review, not fine to hand to outside counsel.&lt;/p&gt;

&lt;p&gt;Redaction isn't content-aware — it doesn't scan text and detect what looks sensitive. It replaces a fixed set of fields wholesale: &lt;code&gt;payload&lt;/code&gt; (redacted by default), plus &lt;code&gt;target&lt;/code&gt; and &lt;code&gt;final_output&lt;/code&gt; if you opt in with flags. Everything structural — IDs, timestamps, decision results, policy names — is preserved no matter what:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;arb redact mapped_replay_bundle.json &lt;span class="nt"&gt;--out&lt;/span&gt; redacted_bundle.json &lt;span class="nt"&gt;--targets&lt;/span&gt; &lt;span class="nt"&gt;--final-output&lt;/span&gt;
Redacted bundle written to redacted_bundle.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"redaction_metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"redacted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"redacted_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-18T19:47:34Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"redacted_fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"action_proposals[0].payload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"action_proposals[0].target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"action_proposals[1].payload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"action_proposals[1].target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"action_proposals[2].payload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"action_proposals[2].target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"final_output"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"replacement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[REDACTED]"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A redacted bundle still validates clean — the whole point is that a reviewer can see &lt;em&gt;what&lt;/em&gt; was blocked and &lt;em&gt;why&lt;/em&gt;, without seeing the customer's actual email address.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signing For Export Integrity
&lt;/h2&gt;

&lt;p&gt;Once a bundle is ready to leave the building, sign it so anyone downstream can tell if it was altered in transit — the redacted version, since that's the one actually going out the door:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;arb sign redacted_bundle.json &lt;span class="nt"&gt;--secret&lt;/span&gt; &lt;span class="s2"&gt;"demo-secret"&lt;/span&gt; &lt;span class="nt"&gt;--key-id&lt;/span&gt; &lt;span class="s2"&gt;"cognous-demo-key-01"&lt;/span&gt; &lt;span class="nt"&gt;--out&lt;/span&gt; signed_bundle.json
Signed bundle written to signed_bundle.json

&lt;span class="nv"&gt;$ &lt;/span&gt;arb verify signed_bundle.json &lt;span class="nt"&gt;--secret&lt;/span&gt; &lt;span class="s2"&gt;"demo-secret"&lt;/span&gt;
Signature VALID

&lt;span class="nv"&gt;$ &lt;/span&gt;arb verify signed_bundle.json &lt;span class="nt"&gt;--secret&lt;/span&gt; &lt;span class="s2"&gt;"wrong-secret"&lt;/span&gt;
Signature INVALID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's HMAC-SHA256 over a canonical serialization of the bundle. Worth being precise about what it proves: it tells you the bundle hasn't changed since it was signed, given the secret. It does not prove &lt;em&gt;who&lt;/em&gt; signed it — there's no identity binding, no PKI, no protection if the secret itself leaks. For production use, that's a job for a real key management system. For a shared-secret export check between two parties who already trust each other, HMAC does what it says.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading The Verified File
&lt;/h2&gt;

&lt;p&gt;The auditor gets &lt;code&gt;signed_bundle.json&lt;/code&gt;, runs &lt;code&gt;verify&lt;/code&gt;, and knows immediately whether it matches what left your hands. Signing isn't encryption, though — &lt;code&gt;verify&lt;/code&gt; is the only command that speaks the signed wrapper (&lt;code&gt;signed_bundle_id&lt;/code&gt;, &lt;code&gt;replay_bundle&lt;/code&gt;, &lt;code&gt;signature_metadata&lt;/code&gt;). To actually read the run, pull the inner bundle back out first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;signed_bundle.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;signed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extracted.json&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;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signed&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replay_bundle&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;extracted.json&lt;/code&gt; is a plain &lt;code&gt;AgentReplayBundle&lt;/code&gt; again — &lt;code&gt;summarize&lt;/code&gt;, &lt;code&gt;validate&lt;/code&gt;, everything else works on it. Verify first, extract second: confirm nothing's been tampered with before you trust a single field inside it.&lt;/p&gt;

&lt;p&gt;The signature also doesn't prove anything about the gap between when the run happened and when you got around to signing it. &lt;code&gt;signed_at&lt;/code&gt; is just whatever time you ran the &lt;code&gt;sign&lt;/code&gt; command — there's no check against &lt;code&gt;generated_at&lt;/code&gt;. A bundle that sits unsigned for three days is three days an editor could have touched the file with no trace of it; sign it on day three, and &lt;code&gt;verify&lt;/code&gt; comes back clean regardless. The signature only covers the window it's actually been alive for. So the real answer isn't "sign it before you send it" — it's validate, redact, and sign as part of the run itself, the moment the bundle is generated, so there's no gap for anything to slip into.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proving The Guardrails Held
&lt;/h2&gt;

&lt;p&gt;Back to that morning-after meeting: the complaint, and the question from the boss. What was once a stressful scavenger hunt across servers matching timestamps and logfiles is now just opening one file.&lt;/p&gt;

&lt;p&gt;Agentic runs get their guardrails from two layers: a manifest declaring what's allowed, and a control plane enforcing that live. Replay is the layer that lets your team prove those guardrails actually held — turning what the control plane recorded into one validated, signed file anyone can check independently, long after the run itself is over.&lt;/p&gt;

&lt;p&gt;Clone &lt;a href="https://github.com/cogno-us/cognous-agent-replay-bundle" rel="noopener noreferrer"&gt;Agent Replay Bundle&lt;/a&gt; and try &lt;code&gt;arb&lt;/code&gt; against the example bundles in the repo, or your own control plane exports.&lt;/p&gt;

&lt;p&gt;Learn more about Agent Replay Bundle at &lt;a href="https://cogno.us/agent_replay_bundle.html" rel="noopener noreferrer"&gt;cogno.us&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>security</category>
    </item>
    <item>
      <title>Cognous Control Plane: The Layer That Tells Your Agent No</title>
      <dc:creator>Doug Sillars</dc:creator>
      <pubDate>Tue, 18 Aug 2026 19:39:36 +0000</pubDate>
      <link>https://dev.to/cognous/cognous-control-plane-the-layer-that-tells-your-agent-no-3ln9</link>
      <guid>https://dev.to/cognous/cognous-control-plane-the-layer-that-tells-your-agent-no-3ln9</guid>
      <description>&lt;p&gt;It's all too common — a viral tweet describing how AI agents with poorly defined guardrails deleted production, wiped a critical database, or caused some other disastrous occurrence. Agents need guardrails: this includes permissions to do the job, but also blockers that limit the reach of the agent, thereby preventing accidental disasters that fuel viral tweets.&lt;/p&gt;

&lt;p&gt;Cognous' Open Control Stack is a framework for wrapping AI agents in guardrails, providing access where needed, but blocking the boundaries that cannot be crossed.&lt;/p&gt;

&lt;p&gt;In our &lt;a href="https://dev.to/cognous/cognous-keeps-your-ai-in-check-69l"&gt;introductory blog post&lt;/a&gt;, our agent drafted a cringey follow-up email and "helpfully" sent it to a company's entire list of top customers. Nobody approved that send, and the human marketing team had to drop everything and work to mitigate the damage.&lt;/p&gt;

&lt;p&gt;Open Control Stack is structured as four layers: &lt;strong&gt;Declare → Control → Replay → Evidence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We built the first layer in &lt;a href="https://dev.to/cognous/the-manifest-that-keeps-your-ai-agent-honest-3e97"&gt;The Manifest That Keeps Your AI Agent Honest&lt;/a&gt;, the &lt;strong&gt;Agent Action Manifest&lt;/strong&gt;. That's the Declare layer — a JSON file that works as the allow/block list for our agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull the top customer:&lt;/strong&gt; allowed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Draft a reply:&lt;/strong&gt; draft-first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull contract details:&lt;/strong&gt; blocked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send the email:&lt;/strong&gt; needs approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But that's all a manifest is — a list. Nothing reads it and nothing enforces it. We need something that takes that list and actually applies it to the agent while it's running.&lt;/p&gt;

&lt;p&gt;That's the &lt;strong&gt;Agent Control Plane&lt;/strong&gt; — the Control layer. This post is about what it actually does when the agent tries something.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Sits Beside The Agent
&lt;/h2&gt;

&lt;p&gt;The Control Plane doesn't run the agent, and it isn't a framework. It sits next to whatever is already generating the agent's behavior — OpenClaw, Hermes, a custom loop, whatever — and turns every proposed action into a recorded decision before that action is treated as real.&lt;/p&gt;

&lt;p&gt;The agent's job is small in this picture — it proposes. The Control Plane does the rest: it decides, and it documents. Propose is the only row the agent touches. Decide is the gate ruling allow, block, or escalate. Document is what gets written down once the decision's made. The agent doesn't get a say in the outcome — it just gets to ask.&lt;/p&gt;

&lt;p&gt;The pattern, end to end:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjv1xnlduxc8db6j7pjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjv1xnlduxc8db6j7pjl.png" alt="Cognous Control Plane Pattern" width="799" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Propose
&lt;/h3&gt;

&lt;p&gt;The agent wants to do something. The Control Plane frames it, and a proposal gets built.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent Task:&lt;/strong&gt; The agent kicks off the run. In our use case: "review a customer account and follow up."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frame:&lt;/strong&gt; The Control Plane frames the execution context for the run — the task, actor, environment, allowed tools, blocked tools, policy version. This gets locked in at the start and becomes immutable for the life of the run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action Proposal:&lt;/strong&gt; The agent's ask — this tool, this action type, this target, this payload, this reason. Recorded before anything executes — that's the point of the proposal steps. If the decision gate blocks it next, nothing downstream ever sees a real tool call, but the attempt is still on the record.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decide
&lt;/h3&gt;

&lt;p&gt;The Control Plane decides whether that proposal is actually okay. This is where the manifest's declarations actually take effect: what it declared is what ends up in the frame's allowed and blocked lists, and the frame is what the gate checks against. Two of the six rules below check something separate from the frame: authority — whether this actor currently has permission to write, or to send things externally. Authority is granted per run, on top of the frame, and it's what rules 3 and 5 are checking for.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Policy Gate:&lt;/strong&gt; Decides what happens to the proposal. Six rules, checked top to bottom, first match wins:

&lt;ol&gt;
&lt;li&gt;tool is explicitly blocked → &lt;code&gt;block&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;tool is not in the allowed list → &lt;code&gt;escalate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;action type is &lt;code&gt;external_send&lt;/code&gt; → &lt;code&gt;allow&lt;/code&gt; if authority for it exists, otherwise &lt;code&gt;block&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;action type is &lt;code&gt;read&lt;/code&gt; (and passed rules 1–2) → &lt;code&gt;allow&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;action type is &lt;code&gt;write&lt;/code&gt; → &lt;code&gt;allow&lt;/code&gt; if authority for it exists, otherwise &lt;code&gt;escalate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;anything else → &lt;code&gt;escalate&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy Decision + Evaluation Trace:&lt;/strong&gt; The gate's verdict, plus the rule-by-rule path it took to reach it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allow / Block / Escalate:&lt;/strong&gt; The three possible verdicts. Only &lt;code&gt;allow&lt;/code&gt; lets the proposal go on to actually touch a tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Document
&lt;/h3&gt;

&lt;p&gt;Once a decision is made, the Control Plane writes down what happened, what the decision was, and how it was made.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reliance Record:&lt;/strong&gt; Once an action is allowed and actually executed, a record of what the agent depended on to produce its output — a tool, a database, a file, an API, user input. Blocked and escalated actions never execute, so there's nothing to record reliance on — dependence doesn't exist until an action actually runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run Record:&lt;/strong&gt; Every proposal, decision, trace, block, and reliance from this run, assembled into one object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replay Bundle:&lt;/strong&gt; The run record packaged up for later, portable inspection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running The Scenario For Real
&lt;/h2&gt;

&lt;p&gt;Let's take three of those actions from the manifest and actually run them through the gate: &lt;code&gt;pull_top_customers&lt;/code&gt;, &lt;code&gt;draft_reply&lt;/code&gt;, and &lt;code&gt;send_email&lt;/code&gt;. All three are on this run's allowed-tools list. &lt;code&gt;pull_contract_details&lt;/code&gt; is also declared in the frame's blocked-tools list, matching the manifest — but the task is "review a customer account and follow up," which never calls for contract details, so the agent never proposes it. It's declared, not exercised: nothing for the gate to evaluate here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Starting the run:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the Control Plane spinning up: &lt;code&gt;RunRecorder()&lt;/code&gt; creates the recorder instance, and &lt;code&gt;start_run()&lt;/code&gt; builds the frame — the same frame from the Propose section above, locking in the task, actor, environment, allowed tools, blocked tools, and policy version for everything that follows.&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;agent_control_plane&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RunRecorder&lt;/span&gt;

&lt;span class="n"&gt;recorder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RunRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;run_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Review a customer account and follow up.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;support-agent-v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allowed_tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pull_top_customers&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;draft_reply&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;send_email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;blocked_tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pull_contract_details&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;policy_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Proposing and Deciding One Action:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the pattern for a single action, &lt;code&gt;pull_top_customers&lt;/code&gt;. The same process repeats for the other two actions — omitted here for brevity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Propose the action with the &lt;code&gt;propose_action&lt;/code&gt; method. This is stored in the variable &lt;code&gt;a1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Evaluate the proposal with &lt;code&gt;evaluate_action&lt;/code&gt;. This returns two values: the decision, and, if the action is blocked, a blocked-action record.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;a1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;propose_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pull_top_customers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crm:top_customers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Identify the customer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s account tier before drafting a reply.&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;d1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pull_top_customers&lt;/code&gt; is not blocked, so we receive only the decision, and the unused second value gets thrown away with &lt;code&gt;_&lt;/code&gt;. &lt;code&gt;d1&lt;/code&gt; holds the decision: the verdict (&lt;code&gt;allow&lt;/code&gt;, &lt;code&gt;block&lt;/code&gt;, or &lt;code&gt;escalate&lt;/code&gt;), which rule produced it, and why. Here's what the gate decides across all three actions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pull_top_customers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;read&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;allow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft_reply&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;write&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;escalate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;send_email&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;external_send&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;block&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Missing authority is what stops two of the three from just allowing. &lt;code&gt;draft_reply&lt;/code&gt; escalates and &lt;code&gt;send_email&lt;/code&gt; blocks — same problem, nobody granted permission for this run — but different severity, because the two actions aren't equally reversible. A blocked send is stopped outright: once an email's out, it's out. An escalated write just doesn't execute yet. Nothing about the original decision ever changes — but if someone grants write authority before this run ends, a fresh proposal for the same action would clear rule 5 as &lt;code&gt;allow&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The evaluation trace is where the reasoning survives, not just the verdict. Here's the trace for the &lt;code&gt;send_email&lt;/code&gt; decision:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules_evaluated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"rule_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"blocked_tool_policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"matched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"rule_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unknown_tool_policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"matched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"rule_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external_send_authority_policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"block"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Action type 'external_send' requires an authority record with scope 'external_send', which was not found."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"final_result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"block"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A reviewer looking at this trace can tell exactly which check failed and why — not just that the action was blocked. That matters because &lt;code&gt;send_email&lt;/code&gt; is on the &lt;em&gt;allowed&lt;/em&gt;-tools list; nothing about the tool itself was forbidden. The trace is what proves the block was about missing authority, not a banned tool.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Worth noting:&lt;/strong&gt; &lt;code&gt;draft_reply&lt;/code&gt; escalating isn't a lesser outcome than blocking. It's easy to read "escalate" as a downgrade of "block," but it's really the gate saying it doesn't have enough information to decide safely, so a human should. Grant &lt;code&gt;write&lt;/code&gt; authority to the run, and the same action clears rule 5 as &lt;code&gt;allow&lt;/code&gt; instead — the rule didn't change; what the actor is authorized to do did.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Documenting The Proposal And Decision
&lt;/h2&gt;

&lt;p&gt;After a decision has been made, the Cognous Control Plane documents what occurred during the process. All of the information is collated and stored in one place — not grabbed from logs scattered across different tools and pieced together by timestamp.&lt;/p&gt;

&lt;p&gt;The first step is the Reliance Record. Recall that this only documents actions that actually ran — in this case, &lt;code&gt;pull_top_customers&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record_reliance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;source_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pull_top_customers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;source_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer tier and account fields&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;referenced_action_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;a1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This doesn't get written to a file by itself — it's held in memory as part of the run, alongside every proposal, decision, and trace, until the whole thing gets closed out and exported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Draft prepared and escalated for review. Email send was blocked, not attempted.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;export_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;run_record.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;bundle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recorder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_replay_bundle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;export_json()&lt;/code&gt; writes everything — proposals, decisions, traces, the one blocked-action record, that one reliance record — to a &lt;code&gt;RunRecord&lt;/code&gt; JSON file. Retrieving the reliance record later is just reading that file and looking at its &lt;code&gt;reliance_records&lt;/code&gt; array.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading The Results
&lt;/h2&gt;

&lt;p&gt;Writing the record is only half the story — you also need a way to check it. That's &lt;code&gt;acp&lt;/code&gt;, the Control Plane's own command-line tool, shipped in the same repo: &lt;a href="https://github.com/cogno-us/cognous-agent-control-plane" rel="noopener noreferrer"&gt;github.com/cogno-us/cognous-agent-control-plane&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Running it against the run record we just exported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;acp validate-run run_record.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RunRecord 79ad6860-03de-4136-9828-d4e40fbd05f4: valid (0 errors, 0 warnings)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation here isn't checking whether the run succeeded — it's checking that the record is internally consistent: every decision references an action that actually exists, every blocked action corresponds to a decision that actually says &lt;code&gt;block&lt;/code&gt;. It's a check on the evidence, not on the outcome.&lt;/p&gt;

&lt;p&gt;The replay bundle gets the same treatment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;acp validate-replay replay_bundle.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ReplayBundle 535c72f8-efee-4144-9b78-7f7fff73133d: valid (0 errors, 0 warnings)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What This Deliberately Doesn't Do
&lt;/h2&gt;

&lt;p&gt;The Control Plane only enforces the rules and authority it's actually been given — it doesn't infer intent, and it doesn't fill gaps with a best guess. A permission that was never granted shows up as an escalation or a block, not a pass. It's not a compliance system, and it's not a guarantee that the agent's output was correct. It's the layer that turns "the agent tried to do X" into a recorded, deterministic, inspectable decision, every time.&lt;/p&gt;

&lt;p&gt;It also doesn't decide what happens after a decision is made. The gate doesn't open a ticket, notify anyone, or track whether an escalation ever gets reviewed. Whether a human looks at the draft, whether the agent retries, whether authority eventually gets granted — that's handled by whatever's orchestrating the agent, not by the Control Plane.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Up
&lt;/h2&gt;

&lt;p&gt;We now have a run: three proposed actions, one blocked, one escalated, one allowed, each with a trace and a fingerprint, packaged into a replay bundle that validates clean. That bundle is a record of one run.&lt;/p&gt;

&lt;p&gt;The Cognous Open Control Stack has four steps: Declare → Control → Replay → Evidence.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/cognous/the-manifest-that-keeps-your-ai-agent-honest-3e97"&gt;The Manifest That Keeps Your AI Agent Honest&lt;/a&gt;, we declared in the manifest what was allowed and what was not. In this post, we walked through the Control Plane — it runs next to your agentic framework to allow, escalate, or block actions. The Control Plane records the results from every action taken.&lt;/p&gt;

&lt;p&gt;Next, we look at the last two steps: Replay and Evidence. These are the tools that will save you when auditors are knocking at the door, or you need to prove you've redacted customer data, or just prove it hasn't been tampered with since it was generated. That's the &lt;strong&gt;Agent Replay Bundle&lt;/strong&gt;, and we'll cover it in our next post.&lt;/p&gt;

&lt;p&gt;In the meantime, the Control Plane repo, examples, schemas, and test suite are live now: &lt;a href="https://github.com/cogno-us/cognous-agent-control-plane" rel="noopener noreferrer"&gt;github.com/cogno-us/cognous-agent-control-plane&lt;/a&gt;. Clone it, run &lt;code&gt;examples/simple_agent_run.py&lt;/code&gt;, and watch the gate make the call.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>security</category>
    </item>
    <item>
      <title>The Manifest That Keeps Your AI Agent Honest</title>
      <dc:creator>Doug Sillars</dc:creator>
      <pubDate>Wed, 12 Aug 2026 14:50:04 +0000</pubDate>
      <link>https://dev.to/cognous/the-manifest-that-keeps-your-ai-agent-honest-3e97</link>
      <guid>https://dev.to/cognous/the-manifest-that-keeps-your-ai-agent-honest-3e97</guid>
      <description>&lt;p&gt;In our first post, &lt;a href="https://dev.to/cognous/cognous-keeps-your-ai-in-check-69l"&gt;Cognous Keeps Your AI in Check&lt;/a&gt;, we introduced the scenario: a customer-service agent that pulls CRM records, drafts replies, and — if nobody's watching — occasionally sends 1,000 tone-deaf emails to your best clients. We said the fix isn't reading what the agent wrote after the fact. It's deciding, in advance, what the agent is even allowed to attempt.&lt;/p&gt;

&lt;p&gt;That decision has to live somewhere. It can't live in a Slack thread, a comment in the agent's system prompt, or "Dave from platform remembers we blocked that." It needs to be a file — versioned, reviewable, and boring enough that a security team can actually sign off on it.&lt;/p&gt;

&lt;p&gt;That's what Cognous's Open Control Stack is for. It's four small, open-source projects — Declare, Control, Replay, Evidence — that sit beside your agents and cover authorize, enforce, and prove. Declare comes first, and its artifact is the &lt;strong&gt;Agent Action Manifest&lt;/strong&gt;. This post describes the Action Manifest tooling in the Open Control Stack, available on &lt;a href="https://github.com/cogno-us/cognous-open-control-stack" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Four Actions, Written Down
&lt;/h2&gt;

&lt;p&gt;If you remember in post one, our AI agent was pulling customer data, drafted a cringey email, and sent it to our top 1,000 customers. The Action Manifest is used to outline the agent's permissions as declarations, to prevent this from ever happening again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"manifest_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer-service-agent-manifest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"agent_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer-service-agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"support-platform-team"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"default_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"block"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"crm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Customer relationship management system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"allowed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"external_system"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"crm.internal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"data_classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer_pii"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Outbound customer email system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"allowed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"external_system"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"smtp.internal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"data_classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer_pii"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pull_top_customers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"crm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Retrieve top customer records from the CRM."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"default_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reliance_requirement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"allowed_source_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"tool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"draft_reply"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Draft a reply email for a customer inquiry."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"default_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"authority_required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email.draft.customer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Permission to draft outbound customer emails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"support-platform-team"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"review_requirement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"draft_first"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pull_contract_details"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"crm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Retrieve contract terms from the CRM."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"default_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"block"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"contract"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"restricted"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"send_email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external_send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Send an approved email to the customer."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"default_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"escalate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"authority_required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email.send.customer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Outbound customer send scope"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email.send.customer"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"review_requirement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"approval_required"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"reviewer_role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"support-lead"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reliance_requirement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"allowed_source_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"tool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user_input"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"payload_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sensitive_fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"customer_email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer_name"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"forbidden_fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"contract_terms"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"redaction_hints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"field_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer_email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PII in exported records"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Field names here follow the public schema — check the &lt;a href="https://github.com/cogno-us/cognous-open-control-stack" rel="noopener noreferrer"&gt;repo&lt;/a&gt; for the exact current shape if you're implementing against it.)&lt;/p&gt;

&lt;p&gt;Rules are only as good as what is defined. At the very top of the manifest, we explicitly cover anything not mentioned: &lt;code&gt;"default_action": "block"&lt;/code&gt;. So when a new tool is onboarded (for example &lt;code&gt;send_tweet&lt;/code&gt;), you don't need to go back and update every manifest — it's blocked until you expressly give the agent permission to use it.&lt;/p&gt;

&lt;p&gt;For those actions that are defined:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pull_top_customers&lt;/code&gt; and &lt;code&gt;draft_reply&lt;/code&gt; are both &lt;code&gt;allow&lt;/code&gt;, but not the same kind of allow: pulling the top customers is allowed, full stop, but the draft reply has &lt;code&gt;review_requirement.mode: draft_first&lt;/code&gt; — the agent can write it, but it stops there.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;send_email&lt;/code&gt; isn't just "escalate" as a vague gesture — it names the exact authority scope required (&lt;code&gt;email.send.customer&lt;/code&gt;), the exact reviewer role (&lt;code&gt;support-lead&lt;/code&gt;), and which payload fields have to be redacted before this record goes anywhere near an audit export.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pull_contract_details&lt;/code&gt; is the odd one out — it doesn't strictly need to be there. &lt;code&gt;default_action: block&lt;/code&gt; already covers anything undeclared, so an unlisted "read contract details" action would be blocked anyway. It's included for visibility: a blocked action that shows up in the manifest, tagged &lt;code&gt;restricted&lt;/code&gt;, is a documented decision someone can point to. A blocked action that's simply never mentioned looks identical to an oversight.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's important to note that the manifest is not enforcement. It doesn't stop the agent from doing anything — a runtime layer has to actually read it and act on it (that'll be described in the next post). What the manifest gives you is a single artifact that says, in one place, what &lt;em&gt;should&lt;/em&gt; happen — before the agent has run even once.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Nine Action Types
&lt;/h2&gt;

&lt;p&gt;In our simple manifest above, we show three possible action types. The manifest supports nine. These classifications are what give a governance review the ability to distinguish a harmless read from something that should never happen without a human:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;retrieves or inspects information&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;creates or modifies information, not necessarily sent externally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;external_send&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;sends information outside the system boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;delete&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;removes information or records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;packages or transfers information downstream&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;purchase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;initiates or prepares a purchase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;approve&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;approves or authorizes a workflow step&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;escalate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;routes to a human or supervisory process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;other&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;anything not otherwise classified&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A tool list alone can't tell you this. Knowing the agent "has access to email" tells you nothing about whether it can draft, send, or both, and what's supposed to happen before each.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Four Review Modes
&lt;/h2&gt;

&lt;p&gt;Action type says &lt;em&gt;what kind&lt;/em&gt; of thing an action is. Review mode says &lt;em&gt;who has to look at it, and when&lt;/em&gt; — and it's doing just as much governance work in our example as action type is. There are four:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;none&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;no specific review posture declared&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;human_review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a human is expected to look at it before execution or completion — no specific person named&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;approval_required&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;approval is required from a &lt;strong&gt;named reviewer role&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft_first&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;the agent produces a draft; it does not finish the action itself&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The difference between &lt;code&gt;human_review&lt;/code&gt; and &lt;code&gt;approval_required&lt;/code&gt; is easy to miss but it matters: &lt;code&gt;human_review&lt;/code&gt; says "someone should look at this" without saying who. &lt;code&gt;approval_required&lt;/code&gt; is stricter — it names a reviewer role, and the validator enforces that: an &lt;code&gt;approval_required&lt;/code&gt; action with no &lt;code&gt;reviewer_role&lt;/code&gt; fails validation outright.&lt;/p&gt;

&lt;p&gt;That's why &lt;code&gt;send_email&lt;/code&gt; in our manifest uses &lt;code&gt;approval_required&lt;/code&gt; with &lt;code&gt;reviewer_role: "support-lead"&lt;/code&gt;, not &lt;code&gt;human_review&lt;/code&gt;. Sending customer email isn't "someone should probably glance at this" — it's "this specific role signs off, or it doesn't go out."&lt;/p&gt;

&lt;p&gt;Worth being precise about what &lt;code&gt;"support-lead"&lt;/code&gt; actually is here: a role string, nothing more. The manifest doesn't know who holds that role, doesn't know they're on Slack, and doesn't page anyone. Your enterprise-side plumbing converts "support lead" to Janice, and builds an alerting system in Slack to let her know that her approval is required. The public stack's job ends at "this role must approve, and there's a record of whether it did."&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliance: A Third Thing Being Tracked
&lt;/h2&gt;

&lt;p&gt;Authority asks whether an action was &lt;em&gt;allowed&lt;/em&gt;. Review asks whether a &lt;em&gt;person&lt;/em&gt; signed off. Reliance asks something different: what did this action actually &lt;em&gt;depend on&lt;/em&gt; to produce its result?&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;reliance_requirement&lt;/code&gt; declares that an action should leave a record of its source — a tool, a database, a file, an API, or user input. &lt;code&gt;pull_top_customers&lt;/code&gt; declares reliance on &lt;code&gt;tool&lt;/code&gt; and &lt;code&gt;database&lt;/code&gt;, because a governance review should be able to see it actually came from the CRM and not somewhere the agent invented. &lt;code&gt;send_email&lt;/code&gt; declares reliance on &lt;code&gt;tool&lt;/code&gt; and &lt;code&gt;user_input&lt;/code&gt;, tying the send back to the approved draft it was built from.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;draft_reply&lt;/code&gt; and &lt;code&gt;pull_contract_details&lt;/code&gt; don't declare a reliance requirement — which is why the summarize output above shows &lt;code&gt;Actions requiring reliance: 2&lt;/code&gt;, not 4.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation Isn't Optional, and It Isn't Decoration
&lt;/h2&gt;

&lt;p&gt;A manifest can be valid JSON, but be semantic nonsense. A &lt;code&gt;delete&lt;/code&gt; action on the production database marked &lt;code&gt;allow&lt;/code&gt; isn't caught by JSON Schema. It's caught by the validator, which checks things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;does every action reference a tool that's actually declared and allowed?&lt;/li&gt;
&lt;li&gt;is a privileged action type (&lt;code&gt;external_send&lt;/code&gt;, &lt;code&gt;write&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;, &lt;code&gt;purchase&lt;/code&gt;, &lt;code&gt;approve&lt;/code&gt;) missing an authority requirement it should have?&lt;/li&gt;
&lt;li&gt;is an action marked &lt;code&gt;approval_required&lt;/code&gt; but missing a reviewer role?&lt;/li&gt;
&lt;li&gt;are there duplicate action or tool names?&lt;/li&gt;
&lt;li&gt;are sensitive fields declared with no redaction hints to match?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run it from the CLI — &lt;code&gt;aam&lt;/code&gt;, short for Agent Action Manifest, is the command-line tool that ships with the manifest repo. First we run the validate command to ensure that the JSON is valid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aam validate customer-service-agent-manifest.json
Validation result: VALID
Manifest ID:       customer-service-agent-manifest

Warnings &lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&lt;/span&gt;:
  &lt;span class="o"&gt;[&lt;/span&gt;W004] &lt;span class="o"&gt;[&lt;/span&gt;actions[1]&lt;span class="o"&gt;(&lt;/span&gt;draft_reply&lt;span class="o"&gt;)]&lt;/span&gt; Action &lt;span class="s1"&gt;'draft_reply'&lt;/span&gt; has effective default_action &lt;span class="s1"&gt;'allow'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;action_type &lt;span class="s1"&gt;'write'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;W006] &lt;span class="o"&gt;[&lt;/span&gt;actions[1]&lt;span class="o"&gt;(&lt;/span&gt;draft_reply&lt;span class="o"&gt;)&lt;/span&gt;.payload_policy] Action &lt;span class="s1"&gt;'draft_reply'&lt;/span&gt; has action_type &lt;span class="s1"&gt;'write'&lt;/span&gt; but no payload_policy is declared.
  &lt;span class="o"&gt;[&lt;/span&gt;W005] &lt;span class="o"&gt;[&lt;/span&gt;actions[2]&lt;span class="o"&gt;(&lt;/span&gt;pull_contract_details&lt;span class="o"&gt;)&lt;/span&gt;.reliance_requirement] Action &lt;span class="s1"&gt;'pull_contract_details'&lt;/span&gt; has action_type &lt;span class="s1"&gt;'read'&lt;/span&gt; but no reliance_requirement is declared.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VALID, but not silent — the validator still flags things worth a second look, even in a manifest that passes. Fair warnings, too: we didn't bother declaring a payload policy for a draft-only action, and a blocked action doesn't need reliance evidence it'll never produce.&lt;/p&gt;

&lt;p&gt;Next we can summarize the manifest with the summarize command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aam summarize customer-service-agent-manifest.json
Manifest ID:          customer-service-agent-manifest
Agent name:           customer-service-agent
Environment:          production
Tools:                2
Actions:              4

Actions by &lt;span class="nb"&gt;type&lt;/span&gt;:
  external_send: 1
  &lt;span class="nb"&gt;read&lt;/span&gt;: 2
  write: 1

Actions by default posture:
  allow: 2
  block: 1
  escalate: 1

Actions requiring authority: 2
Actions requiring review:    2
Actions requiring reliance:  2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That "2" next to authority is easy to misread as just the send — it's actually &lt;code&gt;draft_reply&lt;/code&gt; and &lt;code&gt;send_email&lt;/code&gt; both. Drafting on a customer's behalf declares its own authority requirement (&lt;code&gt;email.draft.customer&lt;/code&gt;), separate from the one on the final send (&lt;code&gt;email.send.customer&lt;/code&gt;). Declaring it isn't the same as enforcing it — nothing here checks whether that authority actually exists. That check is the Control Plane's job, next post.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aam&lt;/code&gt; verifies that your manifest is ready, and gives the team a concise summary of what's allowed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Deliberately Doesn't Do
&lt;/h2&gt;

&lt;p&gt;The manifest is the &lt;strong&gt;Declare&lt;/strong&gt; layer, and it stays in its lane:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it doesn't execute the agent&lt;/li&gt;
&lt;li&gt;it doesn't enforce anything at runtime&lt;/li&gt;
&lt;li&gt;it doesn't grant authority — &lt;code&gt;email.send.customer&lt;/code&gt; being &lt;em&gt;declared&lt;/em&gt; as required doesn't mean it &lt;em&gt;exists&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;it doesn't replace your application's own authorization system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Declaring that sending email should require approval is not the same thing as stopping an unapproved send. That gap — between what's declared and what actually happens when the agent tries to act — is exactly what the next layer closes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next up
&lt;/h2&gt;

&lt;p&gt;The manifest says what the agent &lt;em&gt;may&lt;/em&gt; propose. It says nothing about what the agent actually &lt;em&gt;does&lt;/em&gt; on a Tuesday afternoon when it's mid-run and reaching for the send button. That's the &lt;strong&gt;Agent Control Plane&lt;/strong&gt; — it reads this exact manifest, sits beside the agent at runtime, and turns every proposed action into a recorded decision: allow, block, or escalate, deterministically, every time. That's next.&lt;/p&gt;

&lt;p&gt;The manifest repo, examples, schemas, and test suite are live now: &lt;a href="https://github.com/cogno-us/cognous-open-control-stack" rel="noopener noreferrer"&gt;github.com/cogno-us/cognous-open-control-stack&lt;/a&gt;. Clone it, validate the customer-service example, break it on purpose and watch the validator catch you.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>security</category>
    </item>
    <item>
      <title>Cognous Keeps Your AI in Check</title>
      <dc:creator>Doug Sillars</dc:creator>
      <pubDate>Thu, 06 Aug 2026 22:49:57 +0000</pubDate>
      <link>https://dev.to/cognous/cognous-keeps-your-ai-in-check-69l</link>
      <guid>https://dev.to/cognous/cognous-keeps-your-ai-in-check-69l</guid>
      <description>&lt;p&gt;You've probably gotten an email that was supposed to feel personal, but obviously wasn't. Something about it just felt off. Automated. And somewhere in the back of your mind, you wondered: who approved this?&lt;/p&gt;

&lt;p&gt;Honestly? The answer is probably no one.&lt;/p&gt;

&lt;p&gt;Organizations are leaning harder on AI agents to actually do work. Agents are making database queries, writing letters, accessing email lists, but where does the access end? Without solid guardrails, tone-deaf emails are no longer an embarrassing edge case, they're a real risk. Nobody wants to be the team that let an agent send 1,000 tone-deaf emails to its best clients before anyone noticed.&lt;/p&gt;

&lt;p&gt;This series is about the tooling that keeps that from happening, and about actually building it, not just reading about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually needs to happen
&lt;/h2&gt;

&lt;p&gt;The email itself might be perfectly fine. Correct grammar, on-brand, even genuinely well-written. But the problem is that the email didn't need to be sent. The agent just did it anyway, without any guidance from the team.&lt;/p&gt;

&lt;p&gt;So the fix isn't a better read of what the agent said. It's governance around what the agent is allowed to do, three capabilities, specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authorize&lt;/strong&gt;: Decide in advance what an agent is allowed to do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce&lt;/strong&gt;: Apply that decision the moment the agent tries to act, before the action executes, not after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prove&lt;/strong&gt;: Turn every run into a record you can produce on demand, not one you have to reconstruct from memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Application logs are a day late and a dollar short: the emails are already sent. Looking at logs is reactive. You need a stack that sits in front of your agents and proactively approves or denies actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Cognous
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cogno.us/" rel="noopener noreferrer"&gt;Cognous&lt;/a&gt; builds infrastructure for governing AI agents. Its first release, the Open Control Stack, is fully open source: four small projects that sit beside your AI agents to keep them in check, together covering Authorize, Enforce, and Prove. The four projects are &lt;strong&gt;Declare, Control, Replay, Evidence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Declare, the Agent Action Manifest&lt;/strong&gt;. Written once, before the agent ever runs. The manifest provides or denies access. The agent is attempting to complete a task, but the manifest keeps it in check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Pull top customers&lt;/em&gt;: &lt;code&gt;default_action: allow&lt;/code&gt;. A CRM read, flagged to leave a reliance record of what data it used.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Draft a reply&lt;/em&gt;: &lt;code&gt;default_action: allow&lt;/code&gt;, review_mode: draft_first. The agent prepares content; it doesn't finish the job.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pull contract details&lt;/em&gt;: &lt;code&gt;default_action: block&lt;/code&gt;. Off-limits for this agent, full stop.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Send the email&lt;/em&gt;: &lt;code&gt;default_action: escalate&lt;/code&gt;. Requires a named authority scope and human sign-off before it's eligible to execute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is that the manifest lets you say &lt;em&gt;reading customer data is fine, reading contracts is not, drafting is fine, but sending the email needs a person&lt;/em&gt;: four different rules for four different actions, declared before any of them happen, instead of one blanket policy applied to "the agent" as if every action carried the same risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Control, the Agent Control Plane&lt;/strong&gt;. Runs live, alongside the agent. Every time the agent tries to do something, the Control Plane checks it against what was declared, records the attempt, and either allows it, blocks it, or escalates it for approval, deterministically, every time. Every one of those outcomes gets written down, not just the bad ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replay, the Agent Replay Bundle&lt;/strong&gt;. Not a process, an export. When the run ends, everything the Control Plane recorded (what was proposed, what was decided, what was escalated, what it relied on) gets packaged into a single portable file. No more digging through the logs of a dozen systems to reconstruct one run. Every read, every draft, every escalation, everything that was allowed or held back: it's all in one place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evidence, the Agent Governance Evidence Pack&lt;/strong&gt;. Assembled later, across many runs. This is where you get to show your work: not "trust us, we have controls," but "here's proof: 40 sends needed sign-off this month, and here's what happened to each one."&lt;/p&gt;

&lt;h2&gt;
  
  
  Walking the scenario through the stack
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The manifest declares that sending an email requires authority and escalates rather than executing automatically, decided before the agent ever runs a single task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mid-run, the Control Plane checks each of the agent's proposals against the manifest as they happen: pulling top customers and drafting a reply go through, pulling contract details is blocked outright, and the proposed send doesn't execute, it escalates and gets held for a person to review. Every one of those outcomes gets recorded as it happens, not just the one that got stopped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the run ends, every step (the reads, the draft, the block, the held send, and the outcome) gets packaged into a replay bundle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Over time, those bundles roll up into an evidence pack: not "we think our agent behaves," but "here's the record of every send this month that needed sign-off, and what happened to it."&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A thousand cringey emails to customers drops to zero. There are no questions about why, no furious Slack thread trying to piece it together. And if anyone does wonder, the stack's replay bundle provides the paper trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  See it yourself
&lt;/h2&gt;

&lt;p&gt;The Open Control Stack, Cognous's first release, is fully open source, and everything above (the manifest fields, the allow/block/escalate decisions, all of it) comes straight from the actual code, not a slide deck. If you want to see AI agent governance in action instead of taking our word for it, the manifest, control plane, replay bundle, and evidence pack repos are all live on &lt;a href="https://github.com/cogno-us/cognous-open-control-stack" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Clone one, run the examples, watch a proposed action get authorized, blocked, or escalated in real time. You can learn more about Cognous at &lt;a href="https://cogno.us/" rel="noopener noreferrer"&gt;cogno.us&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the first post in a series on AI agent governance. Next up, we build the manifest from this exact scenario: the real schema, the real validation rules, and what runtime authorization for AI agents actually looks like as working code. From there we'll get into the AI agent control plane that enforces it and how a single run turns into replayable AI agent evidence you can hand to an auditor. More posts coming soon.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>security</category>
    </item>
  </channel>
</rss>
