Metadata-Version: 2.5
Name: crewai-aer1
Version: 0.1.0
Summary: AER-1 verifiable execution receipts for CrewAI crews: one checkable receipt per tool call, via CrewAI's native event bus.
Project-URL: Homepage, https://zambo.dev
Project-URL: Spec (IETF draft), https://datatracker.ietf.org/doc/draft-zambo-aer1/
Project-URL: Conformance kit, https://gitlab.com/rambozambodotdev/zambo
Author: Brennan Zambo
License: MIT
License-File: LICENSE
Keywords: aer-1,ai-agents,audit,crewai,receipts,verification
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: crewai>=1.0
Description-Content-Type: text/markdown

# crewai-aer1

AER-1 verifiable execution receipts for CrewAI crews. One checkable receipt per tool call, emitted through CrewAI's own typed event bus. No changes to your Crew, Agent, or Task definitions.

## Quickstart

```python
from crewai import Agent, Crew, Task
from crewai_aer1 import AER1Listener

receipts = AER1Listener()  # keep this reference alive for the process

researcher = Agent(
    role="Researcher",
    goal="Find verifiable facts",
    backstory="A careful analyst.",
    tools=[my_search_tool],
)
task = Task(description="...", expected_output="...", agent=researcher)
crew = Crew(agents=[researcher], tasks=[task])

crew.kickoff()
receipts.save("receipts.jsonl")
print(f"{len(receipts.receipts)} verifiable receipts recorded")
```

That is the whole integration. The listener subclasses CrewAI's `BaseEventListener` and registers handlers for `ToolUsageFinishedEvent` (and `CrewKickoffStartedEvent` for crew context) on the singleton event bus in `setup_listeners`. Because the bus is process-wide, every crew you kick off is covered with zero code intrusion. Just make sure the module that instantiates `AER1Listener` is imported, and the instance stays alive (not garbage collected), or handlers stop firing.

## What a receipt proves

Each receipt follows the AER-1 receipt record (IETF Internet-Draft draft-zambo-aer1, Sections 3-6): a stable id, RFC 3339 timestamp, tool identity, provenance class (`EXECUTED BY CREWAI`), base64 canonical bytes, and a SHA-256 output commitment anyone can recompute. A receipt proves the recorded bytes were not changed after the tool ran. It does not prove the tool was correct.

Honest boundaries, enforced in code:
- Cached tool results (`from_cache=True`) are skipped. Nothing executed, so there is nothing to attest.
- Tool calls the tool itself reported as failed are skipped. There is no successful result to commit to.
- A listener exception never breaks a crew run. Every handler is guarded.

## Verify a receipt yourself

```python
from crewai_aer1 import verify_receipt
ok, reason = verify_receipt(receipts.receipts[0])
```

## Spec and conformance

- Spec: https://datatracker.ietf.org/doc/draft-zambo-aer1/ (open Internet-Draft)
- Conformance kit: https://gitlab.com/rambozambodotdev/zambo

## License

MIT
