acrf-trace
A causal trace tool for AI agent communication. Implements the ACRF-08 (Cascading Failure Blindness) defense pattern.
Part of the ACRF framework: https://github.com/kannasekar-alt/ACRF PyPI: https://pypi.org/project/acrf-trace/ Presented at RSA Conference 2026.
Try it in your environment right now
No Docker. No setup. No config. Just Python 3.10+.
Step 1 - Install:
pip install acrf-trace
Step 2 - Add to any agent function:
from acrf_trace import wrap
@wrap(agent_name="PricingAgent")
def pricing_agent(ticker):
return trade_agent(ticker)
@wrap(agent_name="TradeAgent")
def trade_agent(ticker):
return f"BUY 10 shares {ticker}"
pricing_agent("TSLA")
Step 3 - Get your ACRF-08 score:
acrf-trace report
That is it. You now have your ACRF-08 maturity level, causal chain coverage, and exact gaps to fix.
The problem this solves
Imagine PriceAgent calls TradeAgent, which calls ExecutionAgent:
PriceAgent -> TradeAgent -> ExecutionAgent
ExecutionAgent makes a bad trade. Your team asks: who caused this?
Without tracing -- nobody knows. The chain is invisible. This is ACRF-08: Cascading Failure Blindness.
acrf-trace gives every agent call a unique ID, links each call to whoever triggered it, and lets you reconstruct the full chain from any single action -- all the way back to the root cause.
If TradeAgent received poisoned input, you find it instantly:
ExecutionAgent <- TradeAgent (POISONED HERE) <- PriceAgent
Install
pip install acrf-trace
Or from source:
git clone https://github.com/kannasekar-alt/ACRF.git
cd tools/acrf-trace
pip install -e .
Quickstart -- 2 lines to add tracing
Before (your existing agent code):
def price_agent(ticker):
return f"price: $150 for {ticker}"
After (with tracing added):
from acrf_trace import wrap
@wrap(agent_name="PriceAgent")
def price_agent(ticker):
return f"price: $150 for {ticker}"
That is the only change. Every call is now recorded automatically.
Causal chain tracing -- agents calling agents
When agents call other agents, the chain links automatically. No extra code needed. No arguments to pass. It just works.
Example -- 3 agents in a chain:
from acrf_trace import wrap
@wrap(agent_name="PriceAgent")
def price_agent(ticker):
return trade_agent(ticker, action="BUY")
@wrap(agent_name="TradeAgent")
def trade_agent(ticker, action):
return execution_agent(f"{action} {ticker}")
@wrap(agent_name="ExecutionAgent")
def execution_agent(order):
return f"executed: {order}"
price_agent("TSLA")
What gets recorded:
PriceAgent trace: f1966a1e parent: ROOT
TradeAgent trace: cc525327 parent: f1966a1e
ExecutionAgent trace: 0b63544f parent: cc525327
PriceAgent started the chain (ROOT). TradeAgent was called BY PriceAgent. ExecutionAgent was called BY TradeAgent.
Trace backward from any agent
If ExecutionAgent produced bad output, find the root cause:
from acrf_trace import get_store
chain = get_store().get_chain("0b63544f")
for hop in chain:
print(hop.agent_name)
print(" Input: ", hop.input_data)
print(" Output:", hop.output_data)
print()
Output:
PriceAgent
Input: args=('TSLA',)
Output: executed: BUY TSLA
TradeAgent
Input: args=('TSLA',) kwargs={'action': 'BUY'}
Output: trade decided, then executed: BUY TSLA
ExecutionAgent
Input: args=('BUY TSLA',)
Output: executed: BUY TSLA
Full chain. Every input. Every output. Every hop.
CLI report -- ACRF-08 compliance check
After your agents have been running, generate a compliance report:
acrf-trace report
Example output:
ACRF-08 Trace Report
==================================================
Database: acrf_trace.db
Total traces: 3
Agents seen: 3
Per-agent call counts:
ExecutionAgent 1 calls
PriceAgent 1 calls
TradeAgent 1 calls
ACRF-08 Compliance Checks:
CF-2 Trace IDs present: 100% of traces have trace IDs
CF-2 Causal chain links: 67% of traces reference a parent
CF-3 Log integrity hashes: Not yet implemented (planned v0.2)
CF-1 Circuit breakers: Cannot verify from traces alone
ACRF-08 Maturity Level: 2/4 - DEFINED
Other CLI commands:
acrf-trace count how many traces are recorded
acrf-trace clear wipe the database and start fresh
What the maturity levels mean
Level 0 - NONE No tracing at all
Level 1 - INITIAL Trace IDs exist but no causal links
Level 2 - DEFINED Full causal chain reconstructable
Level 3 - MANAGED Log integrity protected against tampering
Level 4 - OPTIMIZED Tested time-to-reconstruct meets a defined target
Installing acrf-trace gets you to Level 2 with two lines of code per agent function.
Storage
Traces are saved to acrf_trace.db (SQLite) in your current directory. The file survives process restarts. You can run agents today and query the data tomorrow.
Use a custom database path:
from acrf_trace import set_store
from acrf_trace.store import SQLiteTraceStore
set_store(SQLiteTraceStore("/var/log/agents/traces.db"))
Use in-memory storage for tests (no file created):
from acrf_trace import set_store
from acrf_trace.store import TraceStore
set_store(TraceStore())
ACRF-08 control objectives addressed
CF-2 Every agent call has a trace ID.
Every call records who triggered it (parent trace ID).
Full causal chain reconstructable from any single action.
Planned for v0.2:
CF-3 Integrity hashes on trace records.
Detects if anyone tampered with the logs.
Out of scope for this library (your infrastructure):
CF-1 Circuit breakers that halt agent chains on anomaly.
CF-4 Tested time-to-reconstruct a cause chain.
Works with any Python agent framework
acrf-trace is framework-agnostic. Works with:
LangChain agents
CrewAI agents
AutoGen agents
Custom Python functions
Any callable that takes input and returns output
If it is a Python function, you can wrap it.
Real-world use -- on a client engagement
You are assessing a client's AI agent system. They have multiple agents talking to each other. You want to know their ACRF-08 maturity level.
Step 1 -- Install on the client's system:
pip install acrf-trace
Step 2 -- Ask the client to add @wrap to each agent function. Two lines per function. No other changes:
from acrf_trace import wrap
@wrap(agent_name="CustomerServiceAgent")
def customer_service_agent(query):
return billing_agent(query)
@wrap(agent_name="BillingAgent")
def billing_agent(query):
return "your bill is $500"
Step 3 -- Let agents run normally for a day or a week.
Step 4 -- Generate the maturity report:
acrf-trace report
You get:
- Which agents are talking to which
- Whether causal chains are fully traceable
- ACRF-08 maturity level (0-4)
- Specific gaps to remediate
That is a billable deliverable from one command. The gap report tells the client exactly what to fix and why.
Authors
Ravi Karthick Sankara Narayanan Kanna Sekar
License
Apache 2.0
Metadata
Release files for acrf-trace 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| acrf_trace-0.1.1.tar.gz | 11.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| acrf_trace-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.0 kB
Release files / acrf_trace-0.1.1.tar.gz
| Download URL | acrf_trace-0.1.1.tar.gz |
|---|---|
| Size | 11.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2745719152c55c9622e66098b519c656bea9610a5db4245d7b451142281b6b81
|
|
BLAKE2b-256 checksum How to use checksums |
665a2929e1fb38e6bc1a399f9f4170f91e5e407ae13447e19a8adb90d41dbf9e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / acrf_trace-0.1.1-py3-none-any.whl
| Download URL | acrf_trace-0.1.1-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a12eef38f7eafa025d2bd4fdad7e0f0e4f63dbae05e0e1a0241b5be92e480907
|
|
BLAKE2b-256 checksum How to use checksums |
523476dfd78a394349b460d0c78682b3f9938c6eb2495f0c9ecf674214918425
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for acrf-trace 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.