Observed since 20 Oct, 18:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
A causal trace tool for AI agent communication — implements ACRF-08 (Cascading Failure Blindness) defense
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.
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.
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
pip install acrf-trace
Or from source:
git clone https://github.com/kannasekar-alt/ACRF.git
cd tools/acrf-trace
pip install -e .
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.
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.
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.
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
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.
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())
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.
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.
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:
That is a billable deliverable from one command. The gap report tells the client exactly what to fix and why.
Ravi Karthick Sankara Narayanan Kanna Sekar
Apache 2.0
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.1 | 28 Apr 2026 | 0 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 18:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:dbcf3386ba0889acc969223f2585670555e234d705347e33f8bfe34c2208beee