You person agents doing existent work. Drafting codification reviews, triaging tickets, suggesting settlements, reviewing contracts. A quality approves, edits, aliases rejects each one. Right now, that determination lives successful your exertion code, your chat threads, your summons comments, and your head. When thing goes incorrect six weeks later, reconstructing what happened costs you forty-five minutes and is half guesswork.
CHAP gives you 1 spot to put those decisions and 1 style to put them in. The agent's draught is an artefact. The human's edit is simply a system override pinch a diff, a rationale, and tags you control. The full point chains together by contented hash. You query the concatenation alternatively of grepping logs crossed 4 UIs.
That's the full pitch.
A solo developer utilizing Cursor to reappraisal propulsion requests. The bot flags a "warning" the developer disagrees with. Here is the full exchange, extremity to end. The clip beneath runs successful astir 23 seconds crossed six labelled steps; the matching codification is correct underneath.
And present is the code, each statement of it. The communicative beneath is 1 continuous communicative successful 2 languages; prime whichever stack you really use.
1. Spin up a workspace. An embedded coordinator pinch SQLite persistence, 2 participants, a workspace:
| 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:
| // The bot's reappraisal 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 pinch 1 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 reappraisal 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 pinch 1 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 destruction (coord.api.*) truthful each method gets afloat autocomplete and compile-time checks. Python keeps the JSON-RPC letter cover style connected the aboveground (coord.dispatch({...})) and consumers wrap it nevertheless suits the telephone site; a send() helper is the idiom the Python tests use. Both paths emit identical ligament bytes; the audit concatenation is byte-for-byte the aforesaid sloppy of which customer made the call.
3. Two months in, analyse what you person been doing. This is wherever the protocol pays you back. The reference repo ships an analytics book successful some languages that sounds the audit concatenation (over HTTP aliases straight from your SQLite file) and groups overrides:
Your adjacent punctual revision for Cursor is nary longer a guess. It cites the shape by name.
The override envelope, successful detail
The override letter cover is the azygous astir important style successful CHAP. Every section has a job:
The 2 fields astir group miss connected first publication are intent_preserved and tags.
intent_preserved distinguishes a refining override (the quality agreed pinch the agent's determination but rewrote really it was expressed) from a substituting override (the quality reached a different decision). These are 2 different nonaccomplishment modes and they want different fixes. A precocious refining complaint astir 1 argumentation clause intends the agent's retrieval is off; a precocious substituting complaint connected the aforesaid clause intends the argumentation itself is ambiguous, aliases the agent's task discourse is wrong.
tags is the controlled vocabulary your squad agrees on. Keep it small. Whatever you put location is the magnitude you will aggregate connected 3 months from now, erstwhile you are answering questions for illustration which prompts request work? aliases which paths is the bot getting consistently wrong?
TypeScript / Node:
Python:
Either way gets you Core positive the review/1.0 floor plan and a runnable reference. The TypeScript reference is successful reference/; the Python reference is successful reference/python/. The TypeScript room lives astatine packages/coordinator/; the Python room astatine packages/coordinator-py/.
Five-minute hands-on walkthrough: examples/00-five-minute-start.md.
CHAP 0.2 is simply a nationalist draft. Concretely, this repo contains:
- The specification. Core (seven methods, 1 envelope, 1 ligament format) positive eleven optional profiles. Combined into a azygous archive astatine SPECIFICATION.md, aliases publication individually from core/SPEC.md and profiles/.
- Two reference implementations. Both screen Core positive each profile, 39 method handlers successful total. The TypeScript reference is astatine packages/coordinator/, pinch HTTP servers astatine reference/core/ and reference/core-plus-review/ and a runnable playground pinch 2 browser sessions and a section LLM astatine reference/playground/. The Python reference is astatine packages/coordinator-py/ pinch an HTTP server astatine reference/python/. Both walk the conformance harness connected the aforesaid JSON-RPC 2.0 wire.
- A conformance harness. 23 trial vectors, signing/canonicalisation/chain checks, in-toto attestation output. Two conformance levels are claimable coming (Minimal, Recommended); Full waits connected broader interop testing crossed the 2 implementations.
- MCP server transport. A CHAP Coordinator tin coming itself arsenic an MCP server, exposing each CHAP method arsenic a tool. Point Claude Desktop, Cursor, Claude Code, aliases immoderate MCP customer astatine it and thrust a CHAP workspace from earthy language. TypeScript adapter astatine packages/coordinator-mcp/, Python adapter astatine chap_coordinator.transports.mcp_server, runnable reference servers astatine reference/mcp-server-ts/ and reference/mcp-server-py/. Five-minute walkthrough astatine examples/drive-chap-from-claude-desktop.md.
- A2A server transport. A CHAP Coordinator tin besides coming itself arsenic an A2A agent, advertizing each CHAP method arsenic a discrete accomplishment connected its Agent Card. Any A2A-aware orchestrator (Azure AI Foundry, Amazon Bedrock AgentCore, Google ADK, civilization multi-agent systems) tin registry the coordinator by URL and delegate activity to it. TypeScript adapter astatine packages/coordinator-a2a/, Python adapter astatine chap_coordinator.transports.a2a_server, reference servers astatine reference/a2a-server-ts/ and reference/a2a-server-py/. Walkthrough astatine examples/drive-chap-from-an-a2a-orchestrator.md.
- Inward wrap helpers. Small room utilities that move an outer MCP instrumentality telephone aliases A2A speech into a CHAP task.create + task.complete pair, pinch hashes of the input/output canonicalisations recorded arsenic citations connected the resulting artefact. The room counterpart to the citation patterns successful integrations/CHAP-with-{MCP,A2A}.md. Available arsenic wrapMcpToolCall / wrapA2aMessageExchange from @brightbeamai/chap-coordinator, and arsenic wrap_mcp_tool_call / wrap_a2a_message_exchange from chap_coordinator.transports.wrap.
- Framework bridges. Thin Python adapters that link a existent supplier framework's human-in-the-loop system to CHAP's review/decide methods, truthful an approval, edit, aliases denial successful the model becomes a decide.approve / decide.override / decide.reject connected the audit chain. Five today, each pinch its ain examples and tests, each model an optional dependency: chap-langgraph (LangGraph), chap-pydantic-ai (Pydantic AI), chap-ag2 (AG2 / AutoGen), chap-llama-index (LlamaIndex Workflows), and chap-google-adk (Google ADK).
- Twelve worked scenarios. IN_PRACTICE.md walks done existent cases from a solo developer pinch Cursor up to GMP-regulated fill-finish manufacturing. Runnable implementations unrecorded successful scenarios/, 1 files per communicative (three implemented truthful far), unfastened to organization contributions.
Breaking changes travel Semantic Versioning. Profile surfaces will move faster than Core. Production deployments needing strict stableness should hold for 1.0. The longer position connection and the publication way are successful ABOUT.md.
What you get erstwhile you adopt this
- An audit concatenation that survives cardinal rotation, log expiry, and group leaving. Every letter cover links to the erstwhile by contented hash. One audit.read telephone returns the full thing.
- Structured supervision information arsenic a broadside effect of normal work. No abstracted note pipeline. The overrides you are already making go a dataset you would different person to commission.
- Signed, non-repudiable approvals erstwhile you request them. Opt into security-signed/1.0 for OIDC-bound signatures pinch a signature_meaning you define. Opt into audit-scitt/1.0 for an outer transparency-log anchor, verifiable without trusting your servers.
- Composability pinch what you person already built. CHAP does not switch MCP aliases A2A. It sits adjacent to them: your supplier uses MCP for tools, A2A for different agents, and CHAP to grounds the shared activity pinch humans.
- IN_PRACTICE.md. Twelve real-world scenarios from solo dev to GMP-regulated manufacturing. The astir useful adjacent read.
- ABOUT.md. What is successful this repo, really CHAP relates to MCP and A2A, the standards it reuses, and really to contribute.
- core/SPEC.md. The 7 Core methods. The full protocol aboveground fits connected 1 screen.
- Technical study connected arXiv. The afloat paper. Architecture, creation rationale, floor plan semantics, threat model, and a worked appendix pinch the 12 scenarios arsenic JSON traces. For readers who want the protocol grounded successful its creation choices.
If you reference CHAP successful world aliases method work, please mention the method report:
CC-BY 4.0 (specification) · Apache 2.0 (code) · Royalty-free, immoderate language, immoderate deployment.
English (US) ·
Indonesian (ID) ·