Tool

Track human-agent decisions with auditable approval chains

Open protocol giving human-agent approvals, overrides, and escalations one hash-linked, auditable shape.

Works with mcpsqlitecursoropenaizendesk

91
Spark score
out of 100
Updated 10 days ago
Source checked Sep 10, 2026
Version 0.2.13
Models
gpt 4o

Add to Favorites

Why it matters

CHAP provides a protocol for capturing, chaining, and auditing human approvals, overrides, and escalations when agents perform real work like code reviews, ticket triage, or contract drafts. It creates hash-linked audit trails that survive log expiry and key rotation, turning ad-hoc human edits into structured supervision data while enabling non-repudiable approvals through optional cryptographic signatures and transparency logs.

Outcomes

What it gets done

01

Chain agent drafts and human overrides into hash-linked audit trails queryable with a single API call

02

Capture structured diffs, rationales, and tags when humans edit agent outputs to build supervision datasets

03

Add Ed25519 signatures and OIDC identity binding for non-repudiable approval workflows

04

Anchor decision chains in external transparency logs for tamper-evident compliance records

Source

Get it from source

Spark does not host a copy of it.

Open source

Reports

Agent outcome reports

No reports yet

Overview

Chap

CHAP is an open protocol that records agent drafts and human approvals or overrides as hash-linked, auditable envelopes queryable in one call, sitting alongside MCP and A2A as the shared record of human-agent decisions. Use it when agents do accountable work with human review and that decision history needs to be reconstructable and queryable later, not just left in scattered logs and chat threads.

What it does

CHAP (Collaborative Human-Agent Protocol) gives approvals, overrides, handoffs, and escalations a shared, auditable shape across MCP and A2A. When an agent drafts something and a human approves, edits, or rejects it, that decision normally lives scattered across application code, chat threads, ticket comments, and memory - CHAP instead makes the agent's draft an artefact and the human's edit a structured override carrying a diff, a rationale, and controlled tags, with the whole sequence chained together by content hash so one audit.read call reconstructs the full history instead of grepping logs across several UIs. Two fields matter most in an override envelope: intent_preserved distinguishes a refining override (the human agreed with the decision but rewrote its expression) from a substituting override (the human reached a different decision) - a high refining rate suggests the agent's retrieval is off, a high substituting rate suggests the policy itself is ambiguous; and tags is a small, team-controlled vocabulary that becomes the dimension you aggregate on later, for example to answer which prompts need work.

When to use - and when NOT to

Use CHAP when agents do real accountable work - drafting code reviews, triaging tickets, suggesting settlements, reviewing contracts - and a human's approval, override, or escalation needs to be reconstructable weeks later without guesswork. It sits beside MCP and A2A rather than replacing them: MCP for tools, A2A for other agents, CHAP for the shared decision record between humans and agents. When approvals must be non-repudiable, the security-signed/1.0 profile adds an Ed25519 signature to every envelope, bindable to a real identity via identity-oidc/1.0, and audit-scitt/1.0 anchors the chain in an external transparency log verifiable without trusting your own servers. CHAP 0.2 is a public draft: Core is stable-ish but profile surfaces move faster, so if strict stability is required, wait for 1.0.

Inputs and outputs

npm install @brightbeamai/chap-coordinator
pip install chap-coordinator

A typical flow: create a workspace and join a human and an agent participant, have the agent's task output submitted via task.create/task.complete, request human review with review.request, and record a disagreement with decide.override (carrying an RFC 6902 JSON Patch diff, a rationale string, and tags). Both TypeScript and Python clients emit the same JSON-RPC 2.0 envelope shape, so the audit chain reads identically regardless of which client wrote to it. A bundled analytics script reads the audit chain from HTTP or directly from a SQLite store and groups accumulated overrides by tag and file path into an "Override Learning Report," turning routine human corrections into supervision data a team would otherwise have to commission separately.

Integrations

The specification defines seven Core methods plus eleven optional profiles, with two reference implementations (TypeScript and Python) that cover every profile and pass the same conformance harness over JSON-RPC 2.0. A coordinator can present itself as an MCP server or an A2A agent, and five framework bridges put human-in-the-loop decisions from LangGraph, Pydantic AI, AG2, LlamaIndex Workflows, and Google ADK onto the audit chain. The specification is licensed under CC BY 4.0 and the code under Apache 2.0, both royalty-free for any language or deployment.

Who it's for

Teams running agents that make real decisions with human oversight - code review, ticket triage, contract review, settlement suggestions - who need an auditable, queryable record of every approval and override instead of reconstructing it from scattered logs after the fact.

Source README

Collaborative Human-Agent Protocol (CHAP)

Latest release PyPI package npm package 27 of 27 conformance vectors passing Specification licensed CC BY 4.0 Code licensed Apache 2.0

The open protocol for humans and agents doing accountable work together.

CHAP gives approvals, overrides, handoffs and escalations a shared, auditable shape across MCP and A2A.

Start here · Install · MCP quickstart · 90-second tour · Scenarios · Implementations · Wiki · Discussions · Paper

Star CHAP on GitHub to help more implementers find and test the protocol


Same scenario, two stacks. Without CHAP: six tools holding fragments of one decision (OpenAI logs expired, Zendesk thread, Slack scrolled past, Linear comments, webhook tail, Notion runbook), 45 minutes across four UIs to answer 'what did the agent draft and why did we approve it?'. With CHAP: three hash-linked envelopes (task.create → artefact → decide.override) joined by prev_hash, one audit.read call, 30 seconds.


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.

The chain survives key rotation, log expiry, and people leaving; one audit.read call returns the whole thing. The overrides your reviewers were already making accumulate into supervision data you'd otherwise have to commission. When approvals must be non-repudiable, security-signed/1.0 adds an Ed25519 signature to every envelope, bindable to a real identity with identity-oidc/1.0, and audit-scitt/1.0 anchors the chain in an external transparency log, verifiable without trusting your servers. And CHAP sits beside MCP and A2A rather than replacing them: MCP for tools, A2A for other agents, CHAP for the shared work with humans.

That's the whole pitch.

The 90-second tour

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

Six-step CHAP Core+Review walkthrough with a progress bar and step indicator across the top. Step 1: Setup (workspace, two participants, a task). Step 2: Drafting (agent drafts a response). Step 3: Pending review (review.request with the draft artefact). Step 4: Override (human disagrees: diff, rationale, tags). Step 5: Audit chain (hash-linked replay, prev_hash continuous). Step 6: Two months in (override learning report shows framework-pattern as the top tag, pointing the next prompt revision at the right problem).

And here's the code, every line of it. 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:

TypeScriptPython
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:

TypeScriptPython
// 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"],
});
# The bot's review is the output of a task.
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",
})

# You disagree with one comment. Override it.
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; a send() helper is the idiom the Python tests use. Both paths emit the same params and the same envelope shape, so the audit chain reads the same whichever client made the call.

3. Two months in, analyse what you've been doing. The reference repo ships an analytics script in both languages that reads the audit chain (over HTTP or straight from your SQLite file) and groups overrides:

# TypeScript reference, against the SqliteStore from step 1:
$ npm --prefix reference/core-plus-review run analyze -- --db ./chap.db wsp_pr_reviews

# Python reference, same idea:
$ python3 reference/python/analyze_overrides.py --db ./chap.db wsp_pr_reviews

Override Learning Report
========================
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 cites the pattern by name instead of guessing at it.


The override envelope, in detail

If you read one shape closely, make it the override envelope. Every field has a job:

Anatomy of a decide.override envelope, with each field annotated: task_id links to the review chain, from carries queryable identity, logical_id survives revision, intent_preserved separates refining from substituting overrides, diff is RFC 6902 JSON Patch, rationale is the 'why' alongside the 'what', tags are structured supervision data.

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'll aggregate on three months from now, when you're answering questions like which prompts need work? or which paths is the bot getting consistently wrong?

Install

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 reference/python/. The TypeScript library lives at packages/coordinator/; the Python library at packages/coordinator-py/.

New here? START_HERE.md gets you to one real decision in about two minutes, with Python and nothing else:

git clone https://github.com/BrightbeamAI/chap.git && cd chap
python3 start-here/start.py

Five-minute hands-on walkthrough with the envelopes in view: examples/00-five-minute-start.md.

Status

CHAP 0.2 is a public draft. The specification is seven Core methods plus eleven optional profiles (SPECIFICATION.md), with two reference implementations, TypeScript and Python, that cover every profile and pass the conformance harness on the same JSON-RPC 2.0 wire. A coordinator can present itself as an MCP server or an A2A agent, and five framework bridges put LangGraph, Pydantic AI, AG2, LlamaIndex Workflows, and Google ADK human-in-the-loop decisions on the audit chain. The full inventory, the repository layout, and how CHAP relates to MCP and A2A are in ABOUT.md.

Breaking changes follow Semantic Versioning. Profile surfaces move faster than Core, so if you need strict stability, wait for 1.0.

Read this next

If you have not run anything yet, START_HERE.md takes about two minutes. After that, IN_PRACTICE.md, twelve scenarios from a solo developer with Cursor up to GMP-regulated manufacturing; it's the most useful next read. ABOUT.md covers what's in the repo, how CHAP relates to MCP and A2A, the standards it reuses, and how to contribute. core/SPEC.md fits the entire protocol surface on one screen. And the technical report on arXiv grounds the design choices: architecture, profile semantics, threat model, and the twelve scenarios as JSON traces in a worked appendix.

Cite

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.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.