A causal trace tool for AI agent communication — implements ACRF-08 (Cascading Failure Blindness) defense
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file acrf_trace-0.1.1.tar.gz.
File metadata
- Download URL: acrf_trace-0.1.1.tar.gz
- Upload date:
- Size: 11.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2745719152c55c9622e66098b519c656bea9610a5db4245d7b451142281b6b81
|
|
| MD5 |
9fe276725ce77dc1db7eabf248775b4f
|
|
| BLAKE2b-256 |
665a2929e1fb38e6bc1a399f9f4170f91e5e407ae13447e19a8adb90d41dbf9e
|
File details
Details for the file acrf_trace-0.1.1-py3-none-any.whl.
File metadata
- Download URL: acrf_trace-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a12eef38f7eafa025d2bd4fdad7e0f0e4f63dbae05e0e1a0241b5be92e480907
|
|
| MD5 |
e4c12ad521778e6208c76020792e3bc0
|
|
| BLAKE2b-256 |
523476dfd78a394349b460d0c78682b3f9938c6eb2495f0c9ecf674214918425
|