cd /news/ai-agents/how-do-you-audit-what-your-autonomou… Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-60772] src=github.com β†— pub= topic=ai-agents verified=true sentiment=Β· neutral

How do you audit what your autonomous agents did?

BrightbeamAI released CHAP, an open-source protocol that logs and chains autonomous agent actions and human overrides into queryable, verifiable envelopes, enabling teams to audit agent decisions weeks later without log-grepping across multiple UIs.

read8 min views1 publishedJul 15, 2026
How do you audit what your autonomous agents did?
Image: source

The protocol for humans and agents doing real work together.

When a bot drafts something and a human edits it, where does that edit live? In CHAP, it lives in an envelope you can query, replay, and verify six months later.

Install Β· The 90-second tour Β· Twelve scenarios Β· About this repo Β· Paper

You have agents doing real work. Drafting code reviews, triaging tickets, suggesting settlements, reviewing contracts. A human approves, edits, or rejects each one. Right now, that decision lives in your application code, your chat threads, your ticket comments, and your head. When something goes wrong six weeks later, reconstructing what happened costs you forty-five minutes and is half guesswork.

CHAP gives you one place to put those decisions and one shape to put them in. The agent's draft is an artefact. The human's edit is a structured override with a diff, a rationale, and tags you control. The whole thing chains together by content hash. You query the chain instead of grepping logs across four UIs.

That's the whole pitch.

A solo developer using Cursor to review pull requests. The bot flags a "warning" the developer disagrees with. Here is the whole exchange, end to end. The clip below runs in about 23 seconds across six labelled steps; the matching code is right underneath.

And here is the code, every line of it. The narrative below is one continuous story in two languages; pick whichever stack you actually use.

1. Spin up a workspace. An embedded coordinator with SQLite persistence, two participants, a workspace:

TypeScript Python
import { Coordinator } from "@brightbeamai/chap-coordinator";
import { SqliteStore } from
  "@brightbeamai/chap-coordinator/storage/sqlite";

const coord = new Coordinator({
  store: new SqliteStore("./chap.db"),
});

coord.api.workspace.create({
  workspace: "wsp_pr_reviews",
  profiles:  ["core/1.0", "review/1.0"],
});

coord.api.participant.join({
  workspace: "wsp_pr_reviews",
  from:      "human:me@local",
  type:      "human",
});

coord.api.participant.join({
  workspace: "wsp_pr_reviews",
  from:      "agent:cursor#v1",
  type:      "agent",
});

|

from chap_coordinator import Coordinator
from chap_coordinator.storage.sqlite \
    import SqliteStore

coord = Coordinator(store=SqliteStore("./chap.db"))

def send(method, params):
    return coord.dispatch({
        "jsonrpc": "2.0", "id": method,
        "method": method, "params": params,
    })

send("workspace.create", {
    "workspace": "wsp_pr_reviews",
    "profiles":  ["core/1.0", "review/1.0"],
})

send("participant.join", {
    "workspace": "wsp_pr_reviews",
    "from":      "human:me@local",
    "type":      "human",
})

send("participant.join", {
    "workspace": "wsp_pr_reviews",
    "from":      "agent:cursor#v1",
    "type":      "agent",
})

|

2. The bot drafts, you override. Wire your existing Cursor integration to emit envelopes:

TypeScript Python
// The bot's review is the output of a task.
const { task_id } = coord.api.task.create({
  workspace: "wsp_pr_reviews",
  from:      "agent:cursor#v1",
  assignee:  "agent:cursor#v1",
  kind:      "code_review",
  input:     { pr_id: "PR-482" },
});

coord.api.task.complete({
  workspace: "wsp_pr_reviews",
  from:      "agent:cursor#v1",
  task_id,
  output:    cursorReview,
});

coord.api.review.request({
  workspace: "wsp_pr_reviews",
  from:      "agent:cursor#v1",
  task_id,
  artefact:  cursorReview,
  to:        "human:me@local",
});

// You disagree with one comment. Override it.
coord.api.decide.override({
  workspace:        "wsp_pr_reviews",
  from:             "human:me@local",
  task_id,
  intent_preserved: true,
  diff: [{ op: "replace",
           path: "/comments/0/severity",
           value: "info" }],
  rationale: "False positive. Framework " +
             "convention, not a bug.",
  tags: ["false-positive",
         "framework-pattern-misread"],
});

|

r = send("task.create", {
    "workspace": "wsp_pr_reviews",
    "from":      "agent:cursor#v1",
    "assignee":  "agent:cursor#v1",
    "kind":      "code_review",
    "input":     {"pr_id": "PR-482"},
})
task_id = r["result"]["task_id"]

send("task.complete", {
    "workspace": "wsp_pr_reviews",
    "from":      "agent:cursor#v1",
    "task_id":   task_id,
    "output":    cursor_review,
})

send("review.request", {
    "workspace": "wsp_pr_reviews",
    "from":      "agent:cursor#v1",
    "task_id":   task_id,
    "artefact":  cursor_review,
    "to":        "human:me@local",
})

send("decide.override", {
    "workspace":        "wsp_pr_reviews",
    "from":             "human:me@local",
    "task_id":          task_id,
    "intent_preserved": True,
    "diff": [{"op":    "replace",
              "path":  "/comments/0/severity",
              "value": "info"}],
    "rationale": "False positive. Framework "
                 "convention, not a bug.",
    "tags": ["false-positive",
             "framework-pattern-misread"],
})

|

About the surfaces.TypeScript ships a typed facade (coord.api.*

) so every method gets full autocomplete and compile-time checks. Python keeps the JSON-RPC envelope shape on the surface (coord.dispatch({...})

) and consumers wrap it however suits the call site; asend()

helper is the idiom the Python tests use. Both paths emit identical wire bytes; the audit chain is byte-for-byte the same regardless of which client made the call.

3. Two months in, analyse what you have been doing. This is where the protocol pays you back. The reference repo ships an analytics script in both languages that reads the audit chain (over HTTP or directly from your SQLite file) and groups overrides:

$ npm --prefix reference/core-plus-review run analyze -- --db ./chap.db wsp_pr_reviews

$ python3 reference/python/analyze_overrides.py --db ./chap.db wsp_pr_reviews

Total overrides: 47

By tag:
  false-positive             β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  31  (66%)
  framework-pattern-misread  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ       22  (47%)
  cosmetic-pref              β–ˆβ–ˆβ–ˆβ–ˆ              8   (17%)

Top file paths:
  src/handlers/                                    18 overrides
  src/components/                                  9  overrides

Your next prompt revision for Cursor is no longer a guess. It cites the pattern by name.

The override envelope is the single most important shape in CHAP. Every field has a job:

The two fields most people miss on first read are intent_preserved

and tags

.

intent_preserved

distinguishes a refining override (the human agreed with the agent's decision but rewrote how it was expressed) from a substituting override (the human reached a different decision). These are two different failure modes and they want different fixes. A high refining rate around one policy clause means the agent's retrieval is off; a high substituting rate on the same clause means the policy itself is ambiguous, or the agent's task context is wrong.

tags

is the controlled vocabulary your team agrees on. Keep it small. Whatever you put there is the dimension you will aggregate on three months from now, when you are answering questions like which prompts need work? or which paths is the bot getting consistently wrong?

TypeScript / Node:

npm install @brightbeamai/chap-coordinator

Python:

pip install chap-coordinator

Either path gets you Core plus the review/1.0

profile and a runnable reference. The TypeScript reference is in reference/; the Python reference is in

. The TypeScript library lives at

reference/python/

; the Python library at

packages/coordinator/

.

packages/coordinator-py/

Five-minute hands-on walkthrough: examples/00-five-minute-start.md.

CHAP 0.2 is a public draft. Concretely, this repo contains:

The specification. Core (seven methods, one envelope, one wire format) plus ten optional profiles. Combined into a single document at, or read individually fromSPECIFICATION.md

andcore/SPEC.md

.profiles/

Two reference implementations. Both coverCore plus every profile, 39 method handlers in total. The TypeScript reference is at, with HTTP servers atpackages/coordinator/

andreference/core/

and a runnable playground with two browser sessions and a local LLM atreference/core-plus-review/

. The Python reference is atreference/playground/

with an HTTP server atpackages/coordinator-py/

. Both pass the conformance harness on the same JSON-RPC 2.0 wire.reference/python/

A conformance harness. 23 test vectors, signing/canonicalisation/chain checks, in-toto attestation output. Two conformance levels are claimable today (Minimal, Recommended); Full waits on broader interop testing across the two implementations.MCP server transport. A CHAP Coordinator can present itself as anMCPserver, exposing every CHAP method as a tool. Point Claude Desktop, Cursor, Claude Code, or any MCP client at it and drive a CHAP workspace from natural language. TypeScript adapter at, Python adapter atpackages/coordinator-mcp/

, runnable reference servers atchap_coordinator.transports.mcp_server

andreference/mcp-server-ts/

. Five-minute walkthrough atreference/mcp-server-py/

.examples/drive-chap-from-claude-desktop.md

A2A server transport. A CHAP Coordinator can also present itself as anA2Aagent, advertising every CHAP method as a discrete skill on its Agent Card. Any A2A-aware orchestrator (Azure AI Foundry, Amazon Bedrock AgentCore, Google ADK, custom multi-agent systems) can register the coordinator by URL and delegate work to it. TypeScript adapter at, Python adapter atpackages/coordinator-a2a/

, reference servers atchap_coordinator.transports.a2a_server

andreference/a2a-server-ts/

. Walkthrough atreference/a2a-server-py/

.examples/drive-chap-from-an-a2a-orchestrator.md

Inward wrap helpers. Small library utilities that turn an external MCP tool call or A2A exchange into a CHAPtask.create

+task.complete

pair, with hashes of the input/output canonicalisations recorded as citations on the resulting artefact. The library counterpart to the citation patterns inintegrations/CHAP-with-{MCP,A2A}.md

. Available aswrapMcpToolCall

/wrapA2aMessageExchange

from@brightbeamai/chap-coordinator

, and aswrap_mcp_tool_call

/wrap_a2a_message_exchange

fromchap_coordinator.transports.wrap

.Framework bridges. Thin Python adapters that connect a real agent framework's human-in-the-loop mechanism to CHAP'sreview

/decide

methods, so an approval, edit, or denial in the framework becomes adecide.approve

/decide.override

/decide.reject

on the audit chain. Five today, each with its own examples and tests, each framework an optional dependency:(LangGraph),chap-langgraph

(Pydantic AI),chap-pydantic-ai

(AG2 / AutoGen),chap-ag2

(LlamaIndex Workflows), andchap-llama-index

(Google ADK).chap-google-adk

Twelve worked scenarios. walks through real cases from a solo developer with Cursor up to GMP-regulated fill-finish manufacturing. Runnable implementations live inIN_PRACTICE.md

, one folder per story (three implemented so far), open to community contributions.scenarios/

Breaking changes follow Semantic Versioning. Profile surfaces will move faster than Core. Production deployments needing strict stability should wait for 1.0. The longer status statement and the contribution path are in ABOUT.md.

An audit chain that survives key rotation, log expiry, and people leaving. Every envelope links to the previous by content hash. Oneaudit.read

call returns the whole thing.Structured supervision data as a side effect of normal work. No separate annotation pipeline. The overrides you are already making become a dataset you would otherwise have to commission.Signed, non-repudiable approvals when you need them. Opt intosecurity-signed/1.0

for OIDC-bound signatures with asignature_meaning

you define. Opt intoaudit-scitt/1.0

for an external transparency-log anchor, verifiable without trusting your servers.Composability with what you have already built. CHAP does not replace MCP or A2A. It sits next to them: your agent uses MCP for tools, A2A for other agents, and CHAP to record the shared work with humans.

. Twelve real-world scenarios from solo dev to GMP-regulated manufacturing. The most useful next read.IN_PRACTICE.md

. What is in this repo, how CHAP relates to MCP and A2A, the standards it reuses, and how to contribute.ABOUT.md

. The seven Core methods. The whole protocol surface fits on one screen.core/SPEC.md

. The full paper. Architecture, design rationale, profile semantics, threat model, and a worked appendix with the twelve scenarios as JSON traces. For readers who want the protocol grounded in its design choices.Technical report on arXiv

If you reference CHAP in academic or technical work, please cite the technical report:

@techreport{chap2026,
  author      = {Shahid, Arsalan and Suttie, Gordon and Black, Philip},
  title       = {Collaborative Human-Agent Protocol (CHAP): An open protocol for auditable, structured multi-human and multi-agent collaboration},
  institution = {Brightbeam AI},
  year        = {2026},
  type        = {Technical Report},
  number      = {arXiv:2606.09751},
  url         = {https://arxiv.org/abs/2606.09751}
}

CC-BY 4.0 (specification) Β· Apache 2.0 (code) Β· Royalty-free, any language, any deployment.

── more in #ai-agents 4 stories Β· sorted by recency
── more on @brightbeamai 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/how-do-you-audit-wha…] indexed:0 read:8min 2026-07-15 Β· β€”