<?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: Arsalan Shahid</title>
    <description>The latest articles on DEV Community by Arsalan Shahid (@arsalan_shahid116).</description>
    <link>https://dev.to/arsalan_shahid116</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4038925%2F2a482e0c-9a8d-4ce3-9ecc-f6244b5b3bbc.jpg</url>
      <title>DEV Community: Arsalan Shahid</title>
      <link>https://dev.to/arsalan_shahid116</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arsalan_shahid116"/>
    <language>en</language>
    <item>
      <title>Your agent asked for approval. Where did the answer go?</title>
      <dc:creator>Arsalan Shahid</dc:creator>
      <pubDate>Thu, 20 Aug 2026 22:58:33 +0000</pubDate>
      <link>https://dev.to/arsalan_shahid116/your-agent-asked-for-approval-where-did-the-answer-go-47m8</link>
      <guid>https://dev.to/arsalan_shahid116/your-agent-asked-for-approval-where-did-the-answer-go-47m8</guid>
      <description>&lt;p&gt;An agent drafts a refund decision. A reviewer reads it, changes the amount, adds a line about the customer's contract, and approves. The refund goes out. Everyone moves on.&lt;/p&gt;

&lt;p&gt;Six months later somebody asks who approved that refund, and why the amount changed. The agent's draft is in a trace. The final amount is in the payments system. The reviewer's reasoning was a sentence in a chat thread that has since scrolled away, and the fact that a human changed the number at all is not recorded anywhere as a distinct event. The trace shows a call. The database shows a result. Nobody can show the decision.&lt;/p&gt;

&lt;p&gt;This is not an unusual failure. It is what happens by default, because the plumbing we have built for AI agents moves work around without recording the&lt;br&gt;
judgment applied to it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The protocols move tasks, not decisions
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol connects an agent to tools. A2A lets agents discover one another and exchange messages. Both do their jobs well, and neither is trying to do this one.&lt;/p&gt;

&lt;p&gt;A paper by Kang and Diponegoro makes the point precisely. They take five agent interoperability protocols, including MCP and A2A, and score them against six&lt;br&gt;
governance dimensions drawn from organisational theory: membership, deliberation,&lt;br&gt;
voting, dissent preservation, human escalation, and audit or replay. Their&lt;br&gt;
conclusion is that these protocols coordinate tasks but cannot express a governed&lt;br&gt;
community. You cannot state in MCP who is allowed to approve something, how a&lt;br&gt;
dissent is preserved, or when a human must be brought in. Governance, they argue,&lt;br&gt;
is a missing architectural layer above these protocols rather than a feature&lt;br&gt;
inside them.&lt;/p&gt;

&lt;p&gt;That matches what we kept running into. We build AI systems for regulated&lt;br&gt;
industries, where a client cannot simply assert that a human was in the loop.&lt;br&gt;
They have to produce the evidence, sometimes years later, to somebody who is paid&lt;br&gt;
to be sceptical. "The logs show a call was made" is not evidence that a person&lt;br&gt;
exercised judgment.&lt;/p&gt;
&lt;h2&gt;
  
  
  What a decision record has to contain
&lt;/h2&gt;

&lt;p&gt;The temptation is to log an approval as a boolean and move on. Approved: true.&lt;br&gt;
This is where most implementations start, and it is worth being clear about what&lt;br&gt;
it throws away.&lt;/p&gt;

&lt;p&gt;An approval and an edit are different events. If a reviewer changed the draft&lt;br&gt;
before approving it, then the thing that went out is not the thing the agent&lt;br&gt;
produced, and the difference is the most interesting part of the record. It is&lt;br&gt;
where the human judgment actually lives.&lt;/p&gt;

&lt;p&gt;So the record needs the agent's output as an artefact, and the human's&lt;br&gt;
intervention as an override that carries the diff, the reviewer's rationale, and&lt;br&gt;
a flag for whether the edit refined the agent's intent or replaced it. Refining&lt;br&gt;
and substituting are different signals: one says the agent was roughly right, the&lt;br&gt;
other says it was wrong. Aggregate a few hundred of those and you have an honest&lt;br&gt;
measure of where the agent is failing, which is a byproduct of the audit trail&lt;br&gt;
rather than a separate analytics project.&lt;/p&gt;

&lt;p&gt;Rejections and escalations matter too, and for the same reason. A record that&lt;br&gt;
only preserves the decisions that went through preserves the successes and&lt;br&gt;
discards the disagreements, which is precisely backwards from an accountability&lt;br&gt;
point of view.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why the record has to be verifiable
&lt;/h2&gt;

&lt;p&gt;A decision record that the system producing it can quietly edit is not evidence.&lt;br&gt;
It is a claim.&lt;/p&gt;

&lt;p&gt;The fix is old and well understood: sign each record, and chain it by content&lt;br&gt;
hash so each entry commits to the one before it. Change any entry after the fact&lt;br&gt;
and every subsequent link breaks. A verifier can then re-walk the chain and say&lt;br&gt;
whether it is intact, without trusting the system that produced it.&lt;/p&gt;

&lt;p&gt;For the strongest form, that chain can be anchored in an external transparency&lt;br&gt;
log. This is what the IETF's SCITT work is for, and it means a relying party can&lt;br&gt;
check a decision happened without asking either party involved. We have an&lt;br&gt;
optional profile for it, and we have been discussing the details on the SCITT&lt;br&gt;
mailing list, where several implementers pointed out things we had wrong. More on&lt;br&gt;
that in a moment, because it is the most useful part of this post.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sixty seconds
&lt;/h2&gt;

&lt;p&gt;CHAP is our attempt at this layer. It is an open protocol, Apache-2.0, and it&lt;br&gt;
rides on MCP and A2A as transport rather than competing with them.&lt;/p&gt;

&lt;p&gt;The Python coordinator has no runtime dependencies, so the fastest way to see&lt;br&gt;
what a decision record looks like is to run one of the worked scenarios straight&lt;br&gt;
from a clone, with nothing installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/BrightbeamAI/chap
&lt;span class="nb"&gt;cd &lt;/span&gt;chap/scenarios/02-marketing-copy
python3 scenario.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That scenario runs a small marketing workflow with one drafter and one editor. It&lt;br&gt;
prints the chain, verifies it, tampers with a copy to show the verification&lt;br&gt;
failing at the exact entry, reconstructs a single edit with its diff and&lt;br&gt;
rationale, and reports which kind of override the editor kept making. The whole&lt;br&gt;
thing is deterministic, so you get the same output every time and can read the&lt;br&gt;
script to see exactly what produced it.&lt;/p&gt;

&lt;p&gt;If you would rather wire it into something, the coordinator and the framework&lt;br&gt;
bridges are published:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;chap-coordinator
pip &lt;span class="nb"&gt;install &lt;/span&gt;chap-langgraph        &lt;span class="c"&gt;# or chap-pydantic-ai, chap-llama-index, chap-ag2, chap-google-adk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @brightbeamai/chap-coordinator
npx &lt;span class="nt"&gt;-y&lt;/span&gt; @brightbeamai/chap-coordinator-mcp   &lt;span class="c"&gt;# expose CHAP as MCP tools&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What we got wrong
&lt;/h2&gt;

&lt;p&gt;This is the part worth reading if you are building anything similar, because&lt;br&gt;
these were not obvious to us and most of them came from other people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adapters must not infer decisions.&lt;/strong&gt; Our first bridges tried to be helpful.&lt;br&gt;
If a framework's human-input hook returned an empty string, that looked like&lt;br&gt;
assent, so the bridge recorded an approval. It also joined the reviewer as a&lt;br&gt;
human participant regardless of what identity the caller supplied. Both are&lt;br&gt;
unforgivable in a record whose entire purpose is attributing a decision to a&lt;br&gt;
person. An adapter that guesses is manufacturing evidence. Now an explicit&lt;br&gt;
decision is required, unknown identity schemes are rejected rather than assumed&lt;br&gt;
to be human, and a bot cannot be recorded as a human approver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An override must diff against the artefact under review.&lt;/strong&gt; Ours originally&lt;br&gt;
took the "before" value from the caller. That let a reviewer record an override&lt;br&gt;
against a document that was never actually reviewed, which makes the diff a&lt;br&gt;
fiction while leaving the rationale and the signature perfectly valid. The base&lt;br&gt;
now always comes from the coordinator's own record of what was sent for review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reading a log should not change it.&lt;/strong&gt; For a while, calling the audit read&lt;br&gt;
method appended an entry to the audit chain, which meant inspecting the log&lt;br&gt;
altered it, and so did verifying it. Obvious in hindsight, invisible in practice&lt;br&gt;
until somebody looked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two implementations will disagree about bytes.&lt;/strong&gt; We have a TypeScript&lt;br&gt;
coordinator and a Python one, and they hash records identically, except that&lt;br&gt;
Python sorts object keys by code point and the JSON canonicalisation standard&lt;br&gt;
sorts by UTF-16 code unit. For any key outside the basic multilingual plane the&lt;br&gt;
two produce different canonical bytes, and therefore different hashes for the&lt;br&gt;
same object, which quietly breaks cross-implementation verification. If you have&lt;br&gt;
two implementations of anything hash-based, test them against each other with&lt;br&gt;
awkward input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrity checks cannot see a record that was never written.&lt;/strong&gt; This one came&lt;br&gt;
from another implementer on the SCITT list, who has operated a public transparency&lt;br&gt;
log and found four cases of it. Chaining and signing prove that the records you&lt;br&gt;
hold are intact. They say nothing about a record that failed to be created, and a&lt;br&gt;
chain of signed links reads identically whether an approval never happened or&lt;br&gt;
happened and was lost. For a human oversight trail that distinction is the whole&lt;br&gt;
ballgame. The fix is ordering rather than cleverness: admit the record first, and&lt;br&gt;
make the decision's success conditional on it.&lt;/p&gt;

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

&lt;p&gt;CHAP is at 0.2.10, with two reference implementations that answer the same&lt;br&gt;
conformance suite identically, eleven composable profiles, bridges for the five common agent frameworks, and a first external integration from a team building an execution authority layer, which is currently experimental.&lt;/p&gt;

&lt;p&gt;The recent releases have been almost entirely security and audit hardening driven by outside review, which is the argument for doing this in the open. Every item in the section above was either found by somebody else or found by us because somebody else asked a sharp question.&lt;/p&gt;

&lt;p&gt;If you are building agents that take consequential actions, the questions worth asking are the same whether or not you use any of this. Can you produce the record of a single human decision without disclosing the others? Does your override bind to the exact artefact it overrode? Can you tell the difference between no approval and a lost approval?&lt;/p&gt;

&lt;p&gt;If you want to pull at any of it, the spec, the scenarios, and the conformance harness are at &lt;a href="https://github.com/BrightbeamAI/chap" rel="noopener noreferrer"&gt;github.com/BrightbeamAI/chap&lt;/a&gt;, and issues are genuinely welcome, including the ones that tell us we have this&lt;br&gt;
wrong.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>mcp</category>
      <category>opensource</category>
    </item>
    <item>
      <title>When a human edits an agent's output, where does that decision go?</title>
      <dc:creator>Arsalan Shahid</dc:creator>
      <pubDate>Mon, 20 Jul 2026 23:33:21 +0000</pubDate>
      <link>https://dev.to/arsalan_shahid116/when-a-human-edits-an-agents-output-where-does-that-decision-go-30pj</link>
      <guid>https://dev.to/arsalan_shahid116/when-a-human-edits-an-agents-output-where-does-that-decision-go-30pj</guid>
      <description>&lt;p&gt;An agent drafts a reply to an insurance claim. A human reads it, changes one sentence that would have committed the insurer to something it did not mean, and ships it. That edit is the single most valuable thing that happened in the whole interaction. It is a human catching an error a model could not.&lt;/p&gt;

&lt;p&gt;Now ask where that edit is recorded. In most production systems, the answer is: in application code, a chat thread, a ticket comment, or nobody's memory at all. The judgement that mattered most leaves no durable trace. Six months later, when a regulator or a customer asks who decided what and why, you cannot answer.&lt;/p&gt;

&lt;p&gt;This is not a niche problem, and it is getting bigger. Foundation models are moving out of "generate a response" and into operational roles: they plan across steps, call tools, request human input, and coordinate with other agents on work that touches customers, claims, code, contracts and clinical decisions. Real deployments are no longer one human supervising one model. They are multi-human, multi-agent collaborations that cross teams, time zones and trust boundaries. And with the EU AI Act's oversight obligations arriving, "a human was in command, and here is the record" is becoming something you have to be able to show, not just assert.&lt;/p&gt;

&lt;p&gt;Two protocols already standardise parts of this world. MCP standardised how an agent reaches tools and data. A2A standardised how agents talk to each other. Neither defines the shared workspace in which humans and agents do accountable work together. That gap is what CHAP fills.&lt;/p&gt;

&lt;p&gt;CHAP, the Collaborative Human-Agent Protocol, treats human judgement as a first-class, recorded event. Under CHAP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An override becomes a structured event that carries the diff, the rationale, and a content hash. The change, the reason for it, and proof it was not altered later.&lt;/li&gt;
&lt;li&gt;A human approval becomes a signed, non-repudiable decision that can be replayed years later.&lt;/li&gt;
&lt;li&gt;A handoff between shifts becomes a portable envelope, not a pinned message that the next person may never read.&lt;/li&gt;
&lt;li&gt;All of it lands in an append-only evidence log.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The design is deliberately small at the centre and extensible at the edges. A minimal Core defines workspaces, participants, tasks, artefacts, and the evidence log. Composable profiles add review, routing, deliberation, handoff, identity, signatures, and transparency-backed audit, so a light internal tool and a heavily regulated clinical system can both use the same protocol and turn on only what they need.&lt;/p&gt;

&lt;p&gt;Everything is open. The specification is published under CC-BY 4.0 and the code under Apache 2.0, with two interoperable reference implementations and adapters for the main agent frameworks (Pydantic AI, LlamaIndex, AG2 and Google ADK), so you can add it to an agent you already have.&lt;/p&gt;

&lt;p&gt;It is early, and the point of publishing it now is to be argued with. If you build agents that carry real responsibility, we would like you to read the model, try it against your own workflow, and tell us where it does not hold up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/BrightbeamAI/chap" rel="noopener noreferrer"&gt;https://github.com/BrightbeamAI/chap&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Paper: &lt;a href="https://arxiv.org/abs/2606.09751" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2606.09751&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Background: &lt;a href="https://www.brightbeam.com/post/including-the-responsible-human" rel="noopener noreferrer"&gt;https://www.brightbeam.com/post/including-the-responsible-human&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Site: &lt;a href="https://chap.brightbeam.works/" rel="noopener noreferrer"&gt;https://chap.brightbeam.works/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
