A dialectical AI framework for hallucination-resistant cybersecurity threat detection.
ARES uses structured debate between AI agents to analyze security threats. Instead of trusting a single model's output, three specialized agents argue within a closed-world evidence system where hallucinations become schema violations β not mysterious AI behavior.
2,246 tests | 39 development sessions | Zero regressions
Traditional AI security tools have a fatal flaw: they can confidently fabricate evidence. ARES solves this through dialectical reasoning:
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β ARCHITECT ββββββΊβ SKEPTIC ββββββΊβ ORACLE β
β (Thesis) β β (Antithesis) β β (Synthesis) β
β β β β β β
β "This is a β β "Could be β β "Verdict: β
β privilege β β scheduled β β THREAT_ β
β escalation β β maintenance" β β CONFIRMED" β
β attack!" β β β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β β β
βββββββββββββββββββββββββ΄ββββββββββββββββββββββββ
β
βββββββββββββΌββββββββββββ
β EVIDENCE PACKET β
β (Frozen Facts) β
β β
β All claims must cite β
β facts that exist here β
βββββββββββββββββββββββββ
Key Innovation: Agents cannot invent facts. Every assertion must reference a fact_id from the immutable EvidencePacket. The Coordinator rejects any message containing non-existent references. This transforms potential hallucinations into catchable validation errors.
ares/
βββ graph/ # Security graph schema
β βββ schema.py # Node/Edge definitions for security data
β βββ store.py # Graph storage
β βββ validators.py # Graph validation
β
βββ dialectic/ # Dialectical reasoning engine
β βββ evidence/ # Evidence system
β β βββ provenance.py # Source tracking
β β βββ fact.py # Immutable fact representation
β β βββ packet.py # Frozen evidence container
β β βββ extractors/ # Log-to-evidence converters
β β βββ protocol.py # Extractor protocol
β β βββ windows.py # Windows Event Log extractor
β β βββ syslog.py # Syslog extractor
β β βββ netflow.py # NetFlow extractor
β β
β βββ messages/ # Communication protocol
β β βββ assertions.py # ASSERT, LINK, ALT assertion types
β β βββ protocol.py # DialecticalMessage, MessageBuilder
β β
β βββ coordinator/ # Enforcement layer
β β βββ validator.py # Message validation against evidence
β β βββ cycle.py # Dialectical cycle state machine
β β βββ coordinator.py # Central authority (the "Bouncer")
β β βββ orchestrator.py # Single-turn production pipeline
β β βββ multi_turn.py # Multi-turn debate orchestration
β β
β βββ agents/ # Reasoning agents
β β βββ base.py # AgentBase with critical invariants
β β βββ context.py # TurnContext, DataRequest
β β βββ patterns.py # AnomalyPattern, BenignExplanation, Verdict
β β βββ architect.py # THESIS phase β threat hypothesis
β β βββ skeptic.py # ANTITHESIS phase β benign alternatives
β β βββ oracle.py # SYNTHESIS phase β Judge + Narrator
β β βββ strategies/ # LLM and rule-based agent strategies
β β βββ protocol.py # Strategy protocol
β β βββ rule_based.py # Deterministic strategy
β β βββ llm_strategy.py # Claude-powered strategy
β β βββ client.py # Anthropic API client
β β βββ prompts.py # Agent prompt templates
β β βββ live_cycle.py # Live LLM cycle runner
β β βββ observability.py # Cycle metrics and logging
β β
β βββ memory/ # Memory stream
β β βββ entry.py # Memory entry representation
β β βββ stream.py # Stream interface
β β βββ chain.py # Evidence chain tracking
β β βββ backends/ # Storage backends
β β βββ in_memory.py # In-memory backend
β β
β βββ scripts/ # Benchmark and corpus tools
β βββ scenario_corpus.py # 33-scenario test corpus
β βββ run_llm_benchmark.py # Live LLM benchmark runner
β βββ benchmark_report.py # Report generation
β βββ run_live_cycle.py # Single-scenario live runner
β βββ sample_packets.py # Example evidence packets
β
βββ visual/ # ARES-VISION visualization system
βββ events.py # Dialectical event model
βββ emitter.py # Event emitter for cycles
βββ live_emitter.py # Real-time WebSocket emitter
βββ replayer.py # Session replay engine
βββ diagnostics.py # Visual diagnostics
βββ visualizer/ # Three.js particle physics visualizer
β βββ index_v5.html # Standalone visualizer (latest)
βββ tests/ # Visual pipeline tests
- Python 3.11+
- An Anthropic API key (for live LLM analysis)
# Clone the repository
git clone https://github.com/b33fydan/ARES.git
cd ARES
# Create virtual environment
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Linux/Mac
# Install dependencies
pip install -r requirements.txt# Run all tests (2,246 tests)
python -m pytest ares/ -v
# Run by component
python -m pytest ares/dialectic/tests/agents/ -v
python -m pytest ares/dialectic/tests/coordinator/ -v
python -m pytest ares/visual/tests/ -v
# Run live LLM tests (requires ANTHROPIC_API_KEY)
python -m pytest ares/ -v --run-live-llm
# Run with coverage
python -m pytest ares/ --cov=ares --cov-report=term-missingfrom ares.dialectic.evidence import EvidencePacket, Fact, Provenance, SourceType, EntityType
from ares.dialectic.agents import ArchitectAgent, SkepticAgent, OracleJudge, OracleNarrator
from ares.dialectic.agents.context import TurnContext, AgentRole
from ares.dialectic.messages.protocol import Phase
# 1. Build an evidence packet with security facts
packet = EvidencePacket(packet_id="packet-001")
packet.add_fact(Fact(
fact_id="fact-001",
entity_type=EntityType.USER,
entity_id="user-jsmith",
field="privilege_level",
value="SYSTEM",
provenance=Provenance(source_type=SourceType.WINDOWS_EVENT_LOG, ...)
))
packet.freeze()
# 2. Create agents and bind to evidence
architect = ArchitectAgent(agent_id="arch-001")
skeptic = SkepticAgent(agent_id="skep-001")
architect.observe(packet)
skeptic.observe(packet)
# 3. Run dialectical cycle
arch_context = TurnContext(
phase=Phase.THESIS,
packet_id=packet.packet_id,
snapshot_id=packet.snapshot_id,
cycle_id="cycle-001",
turn_number=1,
seen_fact_ids=frozenset()
)
arch_result = architect.act(arch_context)
skeptic.receive(arch_result.message)
skep_context = TurnContext(
phase=Phase.ANTITHESIS,
packet_id=packet.packet_id,
snapshot_id=packet.snapshot_id,
cycle_id="cycle-001",
turn_number=2,
seen_fact_ids=arch_result.message.fact_ids
)
skep_result = skeptic.act(skep_context)
# 4. Get verdict
verdict = OracleJudge.compute_verdict(
architect_msg=arch_result.message,
skeptic_msg=skep_result.message,
packet=packet
)
print(f"Verdict: {verdict.outcome}") # THREAT_CONFIRMED, THREAT_DISMISSED, or INCONCLUSIVE
print(f"Confidence: {verdict.confidence}")
print(f"Evidence: {verdict.supporting_fact_ids}")ARES enforces five architectural rules as schema violations, not runtime checks:
Agents are bound to a specific EvidencePacket. They cannot use facts from a different packet.
agent.observe(packet_a)
agent.act(context_for_packet_b) # raises PacketMismatchErrorEach agent can only operate in its designated phase.
# Architect = THESIS only | Skeptic = ANTITHESIS only | Oracle = SYNTHESIS only
architect.act(antithesis_context) # raises PhaseViolationErrorAll assertions must cite fact_ids that exist in the bound packet.
coordinator.submit(message_with_fake_facts) # raises ValidationErrorThe Oracle is split into Judge (deterministic) and Narrator (constrained):
- OracleJudge β Pure function, no LLM, computes verdict from evidence
- OracleNarrator β Explains verdict, cannot modify it
Once OracleJudge computes a verdict, it cannot be changed. OracleNarrator receives a locked verdict at construction.
ARES is modeled after the biological immune system:
| Immune System | ARES Component |
|---|---|
| Antigens | Facts in EvidencePacket |
| T-Helper cells | ArchitectAgent (identifies threats) |
| Regulatory T-cells | SkepticAgent (prevents overreaction) |
| T-Killer cells | Coordinator (enforces, terminates) |
| MHC restriction | Packet binding (respond only to bound evidence) |
| Clonal selection | Evidence tracking (only productive responses survive) |
| Autoimmune prevention | Closed-world principle (can't attack self/hallucinate) |
ARES has been developed across 39 sessions with a zero-regression policy.
Core graph schema, evidence system, message protocol, coordinator, and agent foundation.
Live Anthropic integration, strategy pattern, prompt engineering, 33-scenario benchmark corpus, multi-turn debate infrastructure.
Investigated whether multi-turn debate improves accuracy. Finding: single-turn pipelines outperform multi-turn debate. This is a valid research outcome that informed the single-turn production architecture.
Evidence extractors (Windows, Syslog, NetFlow), accuracy hardening, ARES-VISION particle physics visualizer with real-time WebSocket streaming and session replay.
| Component | Tests |
|---|---|
| Evidence System | 449 |
| Agents & Strategies | 505 |
| Coordinator & Orchestration | 389 |
| Benchmark & Scripts | 367 |
| Visual Pipeline | 213 |
| Memory Stream | 158 |
| Messages | 85 |
| Total | 2,246 |
- Language: Python 3.11
- LLM: Anthropic Claude (via
anthropicSDK) - Testing: pytest (2,246 tests, 65 skipped for live LLM)
- Graph: NetworkX
- Visualization: Three.js, WebSocket, particle physics engine
- Data: Frozen dataclasses (immutability as architectural constraint)
This project is in active development. Contributions, issues, and discussions are welcome.
Built by Daniel Gmys-Casiano with structured paranoia and adversarial thinking.
"Hallucinations are schema violations, not mysterious AI behavior."