Metadata-Version: 2.5
Name: agentbarrier
Version: 1.1.0
Summary: Transaction-safe policy, approval, and execution gateway for AI-agent actions
Project-URL: Homepage, https://github.com/binaydhakal/agentbarrier
Project-URL: Documentation, https://github.com/binaydhakal/agentbarrier#readme
Project-URL: Repository, https://github.com/binaydhakal/agentbarrier
Project-URL: Issues, https://github.com/binaydhakal/agentbarrier/issues
Project-URL: Changelog, https://github.com/binaydhakal/agentbarrier/blob/main/CHANGELOG.md
Project-URL: Compatibility, https://github.com/binaydhakal/agentbarrier/blob/main/docs/compatibility.md
Project-URL: CI Guide, https://github.com/binaydhakal/agentbarrier/blob/main/docs/ci.md
Project-URL: Deployment, https://github.com/binaydhakal/agentbarrier/blob/main/docs/deployment.md
Author-email: Binaya Dhakal <binaydhakal35@gmail.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agent-safety,agentic-ai,agents,ai,ai-firewall,approval,blast-radius,cancellation,guardrails,human-in-the-loop,idempotency,kill-switch,llm,mcp,policy-as-code,pytest,rate-limiting,safety,testing,tool-calling
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Pytest
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: all
Requires-Dist: autogen-core<0.8,>=0.7.5; extra == 'all'
Requires-Dist: google-adk<3,>=2.7; extra == 'all'
Requires-Dist: httpx2<3,>=2.12; extra == 'all'
Requires-Dist: httpx<1,>=0.27; extra == 'all'
Requires-Dist: langgraph<2,>=1.2; (python_version >= '3.11') and extra == 'all'
Requires-Dist: mcp<3,>=2; extra == 'all'
Requires-Dist: openai-agents<1,>=0.22; extra == 'all'
Requires-Dist: opentelemetry-api<2,>=1.31; extra == 'all'
Requires-Dist: psycopg<4,>=3.3; extra == 'all'
Requires-Dist: pydantic-ai-slim<3,>=2.32; extra == 'all'
Requires-Dist: starlette<2,>=0.47; extra == 'all'
Requires-Dist: uvicorn<1,>=0.34; extra == 'all'
Provides-Extra: autogen
Requires-Dist: autogen-core<0.8,>=0.7.5; extra == 'autogen'
Provides-Extra: crewai
Requires-Dist: crewai<2,>=1.15.17; (python_version < '3.14') and extra == 'crewai'
Requires-Dist: onnxruntime<1.24,>=1.22; (python_version < '3.11') and extra == 'crewai'
Provides-Extra: google-adk
Requires-Dist: google-adk<3,>=2.7; extra == 'google-adk'
Provides-Extra: langgraph
Requires-Dist: langgraph<2,>=1.2; (python_version >= '3.11') and extra == 'langgraph'
Provides-Extra: mcp
Requires-Dist: httpx2<3,>=2.12; extra == 'mcp'
Requires-Dist: mcp<3,>=2; extra == 'mcp'
Requires-Dist: uvicorn<1,>=0.34; extra == 'mcp'
Provides-Extra: observability
Requires-Dist: opentelemetry-api<2,>=1.31; extra == 'observability'
Provides-Extra: openai
Requires-Dist: openai-agents<1,>=0.22; extra == 'openai'
Provides-Extra: postgres
Requires-Dist: psycopg<4,>=3.3; extra == 'postgres'
Provides-Extra: postgres-binary
Requires-Dist: psycopg[binary]<4,>=3.3; extra == 'postgres-binary'
Provides-Extra: pydantic-ai
Requires-Dist: pydantic-ai-slim<3,>=2.32; extra == 'pydantic-ai'
Provides-Extra: service
Requires-Dist: httpx<1,>=0.27; extra == 'service'
Requires-Dist: starlette<2,>=0.47; extra == 'service'
Requires-Dist: uvicorn<1,>=0.34; extra == 'service'
Provides-Extra: slack
Requires-Dist: httpx<1,>=0.27; extra == 'slack'
Requires-Dist: starlette<2,>=0.47; extra == 'slack'
Requires-Dist: uvicorn<1,>=0.34; extra == 'slack'
Provides-Extra: test
Requires-Dist: build>=1.2.2; extra == 'test'
Requires-Dist: jsonschema>=4.26; extra == 'test'
Requires-Dist: mypy>=1.15; extra == 'test'
Requires-Dist: pytest-cov>=6.0; extra == 'test'
Requires-Dist: pytest>=8.3; extra == 'test'
Requires-Dist: pyyaml<7,>=6; extra == 'test'
Requires-Dist: ruff>=0.11; extra == 'test'
Requires-Dist: twine>=6.1; extra == 'test'
Description-Content-Type: text/markdown

<p align="center">
  <img
    src="https://raw.githubusercontent.com/binaydhakal/agentbarrier/main/docs/assets/agentbarrier-icon.png"
    alt="AgentBarrier icon"
    width="160"
  >
</p>

# AgentBarrier

<p align="center">
  <strong>Make consequential AI-agent actions policy-controlled, approval-bound, and retry-safe.</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/agentbarrier/"><img src="https://img.shields.io/pypi/v/agentbarrier.svg" alt="PyPI version"></a>
  <a href="https://pypi.org/project/agentbarrier/"><img src="https://img.shields.io/pypi/pyversions/agentbarrier.svg" alt="Python versions"></a>
  <a href="https://github.com/binaydhakal/agentbarrier/actions/workflows/ci.yml"><img src="https://github.com/binaydhakal/agentbarrier/actions/workflows/ci.yml/badge.svg" alt="CI status"></a>
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/agentbarrier.svg" alt="License"></a>
</p>

AgentBarrier is an open-source policy gateway and approval control plane for AI-agent tool calls.
It sits immediately before a consequential action, decides whether to allow, deny, or pause the
exact call for review, prevents duplicate execution, and records what happened outside the model's
context.

Use it around Python tools or run the MCP gateway in front of an existing tool server. The same
project also includes a deterministic test suite for approval, rejection,
cancellation, timeout, replay, delegation, ambiguous outcomes, audit receipts, and parallel
execution controls. It does not ask a model to judge another model and does not require a model API
key.

Runtime enforcement applies deterministic allow, deny, and approval rules
directly around synchronous and asynchronous Python tool functions, persists exact approval state
in SQLite, prevents duplicate execution, and emits integrity-linked audit receipts. See the
[runtime guide](https://github.com/binaydhakal/agentbarrier/blob/main/docs/runtime.md).
The [runtime API reference](https://github.com/binaydhakal/agentbarrier/blob/main/docs/runtime-api.md)
documents the public classes, lifecycle, and failure contract.
The [stability and migration policy](docs/stability-policy.md) defines the stable 1.x public surface
and compatibility promise.
The [production deployment and recovery guide](docs/deployment.md) covers the container baseline,
roles, readiness, backup/restore drills, upgrades, rollback, and incident response.
The package includes a deployable
[MCP policy gateway](https://github.com/binaydhakal/agentbarrier/blob/main/docs/mcp-gateway.md)
using the current MCP 2026-07-28 protocol through its official Python SDK, an authenticated
approval API, and [durable signed webhooks](docs/webhooks.md) for approval and operations systems.
Production controls include durable emergency pauses
and atomic fixed-window action or integer-value limits enforced by the Python and MCP execution
boundary, plus a server-rendered approval dashboard with scoped reviewer sessions and CSRF
protection. A PostgreSQL backend lets multiple service processes share the same transaction-safe
approval, replay, control, and audit state; see the [PostgreSQL guide](docs/postgresql.md).
Signed Slack approvals can deliver exact pending actions to a private channel, authorize only
configured member IDs, reject forged or replayed interactions, and record the Slack identity in the
runtime receipt; see the [Slack guide](docs/slack.md).
Organization-scoped roles and requester/reviewer separation isolate shared deployments. API and
dashboard views are tenant-filtered, and every decision rule is enforced again inside the database
transaction; see the [multi-user authorization guide](docs/multi-user-authorization.md).
Optional privacy-safe OpenTelemetry spans and low-cardinality metrics plus structured lifecycle
logs make live action outcomes observable without exporting arguments or results; see the
[observability guide](docs/observability.md).

> **Status:** AgentBarrier 1.x has a stable public API and is intended for self-hosted production
> use. Pin a compatible minor version, keep consequential credentials behind the mediated boundary,
> and follow the deployment and recovery guide before connecting live tools.

<p align="center">
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/adapters.md">Adapter guide</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/mcp-gateway.md">MCP gateway</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/approval-api.md">Approval API</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/multi-user-authorization.md">Multi-user authorization</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/observability.md">Observability</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/stability-policy.md">Stability policy</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/deployment.md">Deployment</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/releasing.md">Releasing</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/dashboard.md">Dashboard</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/postgresql.md">PostgreSQL</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/slack.md">Slack</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/webhooks.md">Webhooks</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/framework-runtime.md">Framework runtime</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/compatibility.md">Compatibility</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/ci.md">CI guide</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/payment-ledger-example.md">Payment example</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/threat-model.md">Threat model</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/ROADMAP.md">Roadmap</a>
  ·
  <a href="https://github.com/binaydhakal/agentbarrier/blob/main/CONTRIBUTING.md">Contributing</a>
</p>

## What this protects in a real application

- a support agent issuing a refund above a configured amount;
- a coding agent deploying, deleting infrastructure, or applying a privileged change;
- a database assistant running writes while ordinary reads remain automatic;
- a communications agent sending external email or publishing content; and
- any MCP client calling a consequential tool hosted by an existing MCP server.

The model can propose the action but cannot change the reviewed arguments afterward or cause the
same approved operation to execute twice through a retry. With organization authorization and
requester/reviewer separation enabled, its service identity also cannot approve its own request.

For local review, a human can select a pending action and decide it without copying identifiers:

```bash
agentbarrier approvals review --db agentbarrier.db --decided-by alice
```

The terminal menu shows the exact arguments and binding before offering Approve, Reject, Back, or
Quit. Production reviewers should use the authenticated dashboard, API, or Slack integration
because the local CLI reviewer identity is asserted by its caller.

## Stop or limit live agent actions

Use the same runtime database as the protected application or MCP gateway. A global pause takes
effect at the next execution claim; scope it with `--namespace`, `--tool`, or both when only one
agent service or capability is affected.

```bash
agentbarrier controls pause \
  --db agentbarrier.db \
  --paused-by on-call \
  --reason "payment provider incident"

agentbarrier controls resume \
  --db agentbarrier.db \
  --resumed-by on-call \
  --reason "provider recovered"
```

Limits reduce blast radius without requiring a person to review every low-risk call. This example
allows at most 20 refunds or 50,000 cents of refund value in each five-minute window, whichever is
reached first:

```bash
agentbarrier controls limit-set refund-budget \
  --db agentbarrier.db \
  --namespace support-agent \
  --tool payments.refund \
  --window-seconds 300 \
  --max-actions 20 \
  --value-argument amount_cents \
  --max-value 50000 \
  --updated-by risk-team \
  --reason "limit automated refund exposure"

agentbarrier controls status --db agentbarrier.db --json
```

Capacity is reserved atomically only when an approved action is about to execute. An uncertain
outcome keeps its reservation; it is released only when downstream reconciliation proves the
effect did not commit. Value budgets intentionally require non-negative integer units such as
cents, tokens, rows, or messages, avoiding ambiguous floating-point money calculations.

## Run as an MCP safety gateway

Install the optional gateway dependencies from PyPI:

```bash
python -m pip install 'agentbarrier[mcp]'
```

Place AgentBarrier between an MCP client and an existing stdio server:

```bash
agentbarrier mcp stdio \
  --policy policy.json \
  --db agentbarrier.db \
  --upstream-command python \
  --upstream-arg server.py \
  --idempotency-argument request_id
```

Or expose a local Streamable HTTP gateway in front of a remote MCP endpoint:

```bash
agentbarrier mcp http \
  --policy policy.json \
  --db agentbarrier.db \
  --upstream-url https://mcp.example.com/mcp \
  --upstream-bearer-token-env MCP_UPSTREAM_TOKEN \
  --auth-config approval-auth.json
```

The HTTP listener binds to `127.0.0.1:8765` and limits request bodies to 1 MiB by default. A
non-loopback listener is rejected unless its auth file grants the caller `mcp:call`; TLS and rate
limiting still belong at trusted ingress. Each call must supply stable business identity through
the configured argument path or the `agentbarrier/idempotencyKey` MCP metadata field. See the
[MCP gateway guide](docs/mcp-gateway.md) for setup, approval flow, and the security boundary.

The same runtime database can be reviewed from the authenticated HTTP service. It uses
scoped bearer identities, takes the reviewer name from authentication rather than request data, and
serves an OpenAPI 3.1 contract. See the [approval API guide](docs/approval-api.md).

People can review that database through the small server-rendered dashboard without shell access.
It exchanges a scoped bearer credential for an opaque in-memory session, never stores the original
credential in the browser or session store, requires CSRF validation for every decision, and uses
the authenticated subject as the reviewer identity:

```bash
agentbarrier dashboard \
  --db agentbarrier.db \
  --auth-config approval-auth.json
```

The local service opens at `http://127.0.0.1:8788/dashboard/`. Remote use requires HTTPS, secure
cookies, a fixed public origin, and trusted rate-limited ingress. See the
[approval dashboard guide](docs/dashboard.md) for scopes, deployment, and session limitations.

For a shared team deployment, install the `postgres` extra, provision the schema with the explicit
`database migrate` command, and give live services a separate least-privilege database identity.
Connection strings are read from a named environment variable and are never accepted as CLI
arguments. The [PostgreSQL guide](docs/postgresql.md) covers migration, concurrency, backup, and
restore operations.

Durable outbound webhooks can notify a separate approval UI, queue, SIEM, or incident workflow.
They use HMAC-SHA256 signatures, automatic and configured secret redaction, bounded retries,
crash-safe claims, stable event IDs, and explicit dead-letter recovery. See the
[signed webhook guide](docs/webhooks.md).

Pending actions can also be reviewed in a private Slack channel. The integration verifies Slack's
signature over the exact request body, checks a strict workspace/member allowlist, binds every
button to the posted message and runtime request digest, and durably retries notifications:

```bash
agentbarrier slack serve \
  --db agentbarrier.db \
  --state-db agentbarrier-slack.db \
  --config slack.json
```

Arguments that do not fit completely in Slack are posted without decision buttons. Bot and signing
credentials are read only from environment variables named by the config. See the
[Slack approval guide](docs/slack.md) for app setup, HTTPS ingress, reviewer permissions, recovery,
and residual risks.

OpenAI Agents Python, LangGraph, PydanticAI, and Google ADK applications can construct normal
framework tools whose original Python callables are protected by the same durable runtime boundary.
Injected framework context is kept out of the reviewed business arguments, and fail-closed
execution settings prevent an approval or uncertain outcome from becoming ordinary model-visible
tool output. See the [framework runtime guide](docs/framework-runtime.md).

## See a real control failure

The first run below uses an intentionally unsafe adapter that commits while approval is still
pending. AgentBarrier catches the real sentinel effect as `AB002`. The second run exercises the
safe reference adapter and passes the same guarantee.

<p align="center">
  <img
    src="https://raw.githubusercontent.com/binaydhakal/agentbarrier/main/docs/assets/agentbarrier-demo.gif"
    alt="AgentBarrier detects an effect committed before approval, then passes the safe reference adapter"
    width="100%"
  >
</p>

<p align="center">
  <sub>The failure is produced by a real sentinel commit. <a href="https://github.com/binaydhakal/agentbarrier/blob/main/docs/demo/failure.tape">View the reproducible recording source.</a></sub>
</p>

## Why

An agent that can send a message, issue a refund, modify a database, or deploy code needs stronger
evidence than a configuration flag named `requires_approval`. AgentBarrier tests the behavior at
the effect boundary:

- no effect before approval;
- no effect after rejection;
- approval is bound to the exact reviewed arguments;
- replay does not execute the same action twice;
- a lost post-commit response is reported as unknown and reconciled before retry;
- cancelled and timed-out work cannot commit later;
- a pending approval can hold sibling effects under the strict run-barrier profile;
- delegated work inherits its parent's rejection; and
- approval decisions produce action-digest-bound receipts.

## Quick start

```bash
python -m pip install agentbarrier
agentbarrier self-test
```

The self-test runs every guarantee against AgentBarrier's safe reference adapter. Application and
framework adapters implement the small `AgentAdapter` / `RunHandle` contract.

Use AgentBarrier in CI when your agent can cross a consequential boundary such as sending a
message, issuing a refund, changing a database, deploying code, or invoking another agent.

```python
from agentbarrier import SuiteRunner
from myapp.agentbarrier_adapter import MyApplicationAdapter

result = SuiteRunner().verify_sync(MyApplicationAdapter())
result.raise_for_failure()
```

### SQLite database boundary example

The repository includes a credential-free
[SQLite payment-ledger example](https://github.com/binaydhakal/agentbarrier/blob/main/docs/payment-ledger-example.md)
with intentionally unsafe and safe adapters. It verifies real local balance and transaction state
across approval, rejection, replay, response loss, cancellation, and timeout—without presenting the
example as production payment code.

```bash
uv run python -m examples.run_payment_ledger
```

### Approval-barrier profiles

The default `run-wide` profile requires any pending approval to hold every sibling effect in the
logical run. Select `per-action` when the intended contract allows ungated siblings to continue but
still requires the gated action itself to remain effect-free until approval.

```python
from agentbarrier import ApprovalBarrierProfile, RunnerOptions, SuiteRunner

runner = SuiteRunner(RunnerOptions(approval_profile=ApprovalBarrierProfile.PER_ACTION))
result = runner.verify_sync(MyApplicationAdapter())
result.raise_for_failure()
```

The equivalent CLI option is `--approval-profile per-action`. A stricter run-wide adapter also
passes the per-action profile; the profile chooses the minimum contract being tested, not how an
adapter must schedule its work.

### Framework probes

The built-in probes use deterministic local plans. They do not call a model provider or require an
API key.

```bash
python -m pip install 'agentbarrier[openai]'
agentbarrier verify agentbarrier.adapters.openai_agents:OpenAIAgentsAdapter

python -m pip install 'agentbarrier[langgraph]'
agentbarrier verify agentbarrier.adapters.langgraph:LangGraphAdapter

python -m pip install 'agentbarrier[pydantic-ai]'
agentbarrier verify agentbarrier.adapters.pydantic_ai:PydanticAIAdapter

python -m pip install 'agentbarrier[google-adk]'
agentbarrier verify agentbarrier.adapters.google_adk:GoogleADKAdapter

python -m pip install 'agentbarrier[autogen]'
agentbarrier verify agentbarrier.adapters.autogen:AutoGenAdapter

python -m pip install 'agentbarrier[crewai]'
agentbarrier verify agentbarrier.adapters.crewai:CrewAIAdapter \
  --approval-profile per-action
```

The core, OpenAI, PydanticAI, Google ADK, AutoGen, and CrewAI adapters support Python 3.10–3.13. The
LangGraph adapter requires Python 3.11+ because its interrupt lifecycle relies on async
runnable-context propagation. Google ADK currently marks its tool-confirmation feature as
experimental, so its adapter may emit that upstream warning during verification.

CrewAI is installed and tested separately from the `all` extra because its current OpenAI SDK 2.x
requirement conflicts with OpenAI Agents' 3.x requirement. Its real pre-tool hook enforces
per-action approval, rejection, and argument binding; CrewAI's threaded tools do not provide a
safe cancellation or timeout fence. See the
[reproducible CrewAI evaluation](https://github.com/binaydhakal/agentbarrier/blob/main/docs/crewai-evaluation.md).

These probes measure the framework's lifecycle behavior in a minimal configuration. For production
confidence, implement an application adapter that replaces your real consequential tools with the
sentinel at dependency-injection time. See
[the adapter guide](https://github.com/binaydhakal/agentbarrier/blob/main/docs/adapters.md).

The same runner is available as a pytest fixture:

```python
def test_agent_controls(agentbarrier):
    result = agentbarrier.verify_sync(MyApplicationAdapter())
    result.raise_for_failure()
```

## CLI reports

```bash
agentbarrier verify myapp.agentbarrier_adapter:create_adapter \
  --approval-profile run-wide \
  --json build/agentbarrier.json \
  --junit build/agentbarrier.xml \
  --sarif build/agentbarrier.sarif
```

The target may be an adapter instance, adapter class, or zero-argument factory. A non-zero exit
status is returned for failed or errored guarantees. `--strict-skips` also treats unsupported
guarantees as a failure. See the
[CI guide](https://github.com/binaydhakal/agentbarrier/blob/main/docs/ci.md) for copy-ready GitHub
Actions and pytest examples.

## Guarantees

| Scenario | Capability | Guarantee |
| --- | --- | --- |
| `approval_hold` | `approval` | No effect commits before approval; one commits afterward. |
| `rejection` | `rejection` | Rejected actions never commit. |
| `argument_binding` | `argument_binding` | Executed arguments exactly match approved arguments. |
| `replay` | `replay` | Replaying a completed action does not commit it twice. |
| `outcome_ambiguity` | `outcome_ambiguity` | A lost post-commit response becomes `UNKNOWN` and is not retried blindly. |
| `outcome_reconciliation` | `outcome_reconciliation` | Bounded identity lookup distinguishes committed, absent, conflicting, and unavailable evidence. |
| `cancellation` | `cancellation` | Work cancelled after it starts cannot commit later. |
| `timeout` | `timeout` | Timed-out work cannot commit later. |
| `parallel_barrier` | `parallel_barrier` | Parallel effects follow the selected approval-barrier profile. |
| `delegation` | `delegation` | Parent rejection prevents every delegated child effect. |
| `audit_receipts` | `audit_receipts` | Requests and decisions have complete, action-bound receipts. |

Unsupported capabilities are explicitly reported as skipped. They are never silently counted as
passing.

The default `run-wide` profile intentionally requires a pending approval to hold all sibling side
effects in the logical run. The `per-action` profile allows ungated siblings to proceed while the
gated action remains held. Reports always record the selected profile so a passing result cannot
silently change meaning.

## Adapter contract

An adapter starts one or more `ActionRequest` objects using the supplied `EffectProbe` and returns
a `RunHandle`. The handle exposes pending actions and lifecycle decisions. See
`agentbarrier.adapters.reference.ReferenceAdapter` for the complete, safe implementation and
`docs/adapters.md` for implementation rules.

Current framework results are recorded in
[the compatibility matrix](https://github.com/binaydhakal/agentbarrier/blob/main/docs/compatibility.md).
The same probe runs also produce
[versioned JSON evidence](https://github.com/binaydhakal/agentbarrier/blob/main/docs/compatibility.json)
that CI checks against the rendered table and uploads for every supported Python version.
The security boundary and limitations are defined in
[the threat model](https://github.com/binaydhakal/agentbarrier/blob/main/docs/threat-model.md).
Planned adapters and release priorities are public in
[the roadmap](https://github.com/binaydhakal/agentbarrier/blob/main/ROADMAP.md).

## Safety

Sentinel tools write only to a temporary SQLite journal owned by the test run. They do not call a
real API or modify production data. Do not replace a sentinel with a production tool when writing
an adapter.

## Research context

AgentBarrier is motivated by research showing that approval, cancellation, timeout, and replay
controls can leak side effects across agent frameworks. The initial scenario vocabulary follows
the failure classes in *Stop Means Stop: Measuring and Repairing the Enforcement Gap in
Agent-Framework Control Primitives* (2026): <https://arxiv.org/abs/2607.14166>.

## Development

```bash
uv sync --extra test --extra all
uv run ruff check .
uv run ruff format --check .
uv run mypy src
uv run pytest --cov=agentbarrier --cov-report=term-missing
uv run --isolated --extra test --extra crewai pytest tests/test_crewai_adapter.py
uv build
uv run twine check dist/*
```

Good first contributions include framework adapters, application examples, and deterministic
reproductions of control failures. Start with the
[contribution guide](https://github.com/binaydhakal/agentbarrier/blob/main/CONTRIBUTING.md) or open a
[framework adapter request](https://github.com/binaydhakal/agentbarrier/issues/new?template=framework_adapter.yml).

## License

Apache-2.0
