Why production LLM agents get stuck in loops, leak PII, and burn budgets — and how AURA 0.3.6 adds non-invasive runtime governance to your existing agent stack.
If you have deployed an autonomous agent to production, you have likely encountered at least one of these quiet disasters:
- The 3:00 AM Loop: The agent encounters an unexpected API response, tries the same tool with slight variations, falls into a 2-state oscillation ($A \leftrightarrow B$), and burns $200 in OpenAI tokens before a hard timeout triggers.
- The PII in Trace Logs: An agent processes customer queries, fetches an unmasked database record containing SSNs or credit card numbers, and writes the raw text straight into your central telemetry or LLM context window.
- The Secret Spill: To make an API call, the LLM is given raw bearer tokens or AWS secret keys in its prompt context. One prompt injection later, that token is compromised.
- The Schema Drift: The model hallucinates an invalid parameter type, causing downstream tool execution to crash without an audit trail of why the payload failed.
Most agent frameworks (LangGraph, CrewAI, AutoGen, or custom while True: loops) focus on orchestration and reasoning. They are designed to let the agent run.
They are rarely designed to govern the runtime at the boundary.
That is the problem we are solving with AURA Harness.
What is AURA?
AURA is an open-source Python runtime coat for agent loops.
It does not replace your framework, orchestrator, or model. You don't have to rewrite your agents in a new DSL. Instead, AURA sits at the boundary of your agent like a membrane:
- Ingress: Injects verified operator context and declared session variables.
- Egress: Enforces tool policies, schemas, and credential brokering before calls execute.
- Observers: Monitors execution traces in parallel on an append-only causal spine.
- Audit: Produces tamper-evident, SHA-256 hash-chained JSONL audit receipts on session close.
Today we released v0.3.6. Here is a walkthrough of what is new and why these patterns matter for anyone building reliable agent systems.
1. Trajectory Cycle Detection & Loop Governance (preset: break)
Repeated tool calls are not always bad. In a long-running research agent, calling web_search 15 times over 40 turns is healthy behavior.
Blunt global rate-limiters fail because they trip on healthy sessions while missing dangerous local deadlocks.
In AURA 0.3.6, the break observer preset has been upgraded with sliding-window trajectory locality ($K=8$) and multi-cycle topology detection:
from aura.api import agent
# Declare agent governance policy
bot = agent(
"support-investigator",
observers=[
{
"preset": "break",
"config": {
"window_size": 8,
"max_identical_actions": 3, # 1-cycle: A -> A -> A
"max_oscillation_cycles": 2, # 2-cycle: A <-> B <-> A <-> B
"max_choreography_cycles": 2, # 3-cycle: A -> B -> C -> A -> B -> C
"max_error_churn": 3, # Identical error fingerprint churn
"thought_similarity_threshold": 0.85, # Reasoning inertia (>85% text match)
"burn_velocity_guard": True, # FinOps token tracking
"max_cycle_token_waste": 1500, # Trip alert on token threshold
"action": "pause", # alert_only | pause | circuit_break
},
}
],
)
What this catches in real life:
- Action Fixation (1-cycle): The agent executes the same tool with identical arguments 3 times consecutively because it did not understand the previous output.
- State Oscillation (2-cycle): The agent gets caught in a toggle trap — for example, pulling git status, stashing changes, checking status, unstashing, and repeating.
- Execution Choreography (3-cycle): Multi-step choreography loops ($A \to B \to C \to A \to B \to C$), such as repeatedly searching, editing a file, and running tests that fail in the exact same pattern.
- Reasoning Inertia: The model's thought steps stall, generating essentially the same reasoning text (>85% text similarity across consecutive turns) without progressing.
-
FinOps Token Guard: AURA tracks token consumption across repeating sequences. If a cycle consumes more than the defined threshold, a
burn_rate_spikealert fires immediately. -
EU AI Act Art. 14 Cryptographic Proofs: When an alert trips, AURA captures immutable SHA-256 spine event hashes (
cycle_entry_hash,cycle_recurrence_hash) directly into the alert payload, providing non-repudiable proof of algorithmic deadlock for compliance auditors.
2. Sequencer Middleware & PII Masking Engine
Sending sensitive customer data to third-party model providers is a compliance nightmare under GDPR, HIPAA, and CCPA.
AURA 0.3.6 introduces a two-tier PII sanitization engine that runs at step boundaries or as an explicit pipeline operation:
from aura.api import agent
data_agent = agent(
"data-sanitizer",
sequencer={
"steps": [
{"id": "fetch_record", "tool": "db.get_customer"},
{
"id": "mask_pii",
"type": "op",
"ref": "middleware.pii_mask",
"config": {
"strategy": "pseudonymize", # redact | mask | pseudonymize
"entities": ["EMAIL_ADDRESS", "PHONE_NUMBER", "CREDENTIAL_TOKEN"],
"strict": False,
},
},
{"id": "llm_summary", "tool": "ai.summarize"},
]
},
)
Deterministic Pseudonymization
Instead of just redacting ([REDACTED]), AURA can generate deterministic session-scoped pseudonym tokens (e.g., EMAIL_PSEUDO_a1b2c3d4).
This preserves entity equivalence across multi-turn reasoning: the LLM understands that Customer A in turn 1 is the same Customer A in turn 4, without ever seeing Customer A's real email address.
- Tier 1 (Built-in, zero dependencies): Algorithmic regex patterns with Luhn validation for credit cards, RFC emails, E.164 phone numbers, SSNs, IPv4/IPv6, and API keys.
- Tier 2 (Pluggable): Optional providers for contextual NER models (Presidio, Skillware, or custom models).
3. Capability Broker: No More Secrets in LLM Prompts
A common anti-pattern in agent design is providing the model with raw API keys or instructing it to read secrets from environment variables.
In AURA 0.3.6, agents declare capabilities with secret references, never raw secrets:
from aura.api import agent, EnvSecretBroker
# Environment holds the real token, but the agent profile only knows the ref
agent_profile = agent(
"stripe-billing-bot",
capabilities=[
{
"id": "billing_charge",
"tools": ["stripe.charge"],
"inject": [
{
"ref": "STRIPE_SECRET_KEY",
"as": "headers.Authorization",
"prefix": "Bearer ",
}
],
}
],
)
broker = EnvSecretBroker()
with agent_profile.session(secret_broker=broker) as run:
# The agent emits tool intent without credentials
run.emit("tool.call", {"tool": "stripe.charge", "args": {"amount": 5000}})
# Egress injects the Authorization header right before execution.
# The spine, summary, and exported OTel spans automatically redact the secret.
The model never sees the API key, the prompt never contains the token, and the exported audit log automatically redacts all secret values and sensitive keys.
4. Egress JSON Schema Constitution Checks
When agents call external tools, unexpected argument formats cause silent failures or corrupt downstream databases.
AURA 0.3.6 enables declarative JSON Schema checks at the egress boundary:
# Profile configuration
variables:
schema_refs:
sql_query:
type: object
required: [query, timeout_seconds]
properties:
query:
type: string
pattern: "^SELECT " # Enforce read-only queries at schema level
timeout_seconds:
type: integer
maximum: 30
If the agent emits an unapproved INSERT or drops the timeout_seconds argument, AURA's membrane blocks execution with constraint.violated, logs a SCHEMA_VIOLATION in the audit report, and prevents the call from hitting your production infrastructure.
Running a Guarded Session in 20 Lines of Python
Here is how simple it is to wrap any workflow in AURA:
from aura.api import agent
# 1. Define agent with break observer and spectrum level
my_agent = agent(
"autonomous-devops",
spectrum={"level": "full"}, # Auto-wires monitor & break observers
)
# 2. Run your existing agent loop inside an AURA session coat
with my_agent.session() as session:
session.emit("turn.start", {"thought": "Investigating disk space on server..."})
# Tool call guarded by egress constraints and cycle observers
session.emit("tool.call", {"tool": "exec_cmd", "args": {"cmd": "df -h"}})
session.emit("tool.result", {"tool": "exec_cmd", "result": "/dev/sda1 92% full"})
session.emit("turn.end", {"summary": "Disk space critical on sda1"})
# 3. Session closes atomically:
# - Generates tamper-evident SHA-256 hash-chained JSONL trail
# - Generates structured audit report with findings and scorecard
# - Exports OpenTelemetry spans for Datadog / Honeycomb
On close, AURA generates an audit report:
{
"verdict": "pass",
"scorecard": {
"policy": { "declared_rules": 2, "violations": 0 },
"observers": { "alerts": 0, "loop_cycles": 0 },
"middleware": { "applied": 1, "pii_redactions": 2 }
},
"findings": [],
"hash_chain_valid": true
}
Who is AURA for?
- AI Engineering Teams: Who want loop safety, rate limits, and egress controls without ditching their favorite agent framework.
- FinOps & Platform Leads: Who cannot afford agents burning thousands of dollars in runaway reasoning loops overnight.
- Compliance & Security Teams: Who need non-repudiable audit trails, PII scrubbing, and credential isolation to satisfy SOC 2, HIPAA, or EU AI Act human-oversight mandates.
Get Started
AURA is MIT-licensed and available on PyPI:
pip install aura-harness==0.3.6
- GitHub Repository: github.com/ARPAHLS/aura
- Documentation: github.com/ARPAHLS/aura/tree/main/docs
- Examples (14 complete tours): github.com/ARPAHLS/aura/tree/main/examples
If you are building autonomous agents, give it a spin and let us know what cycle patterns you run into in the wild!
Top comments (0)