Definition
An Autonomous Software Entity (ASE) is a self-governing software component that operates independently within defined boundaries, makes decisions based on its internal state and external inputs, and coordinates with other entities through structured communication protocols. Unlike passive software modules that execute only when invoked, autonomous entities possess their own execution context, maintain persistent state, react to environmental changes, and pursue objectives without continuous external direction.
In the Prismatic Platform, autonomous software entities are the foundational unit of the AIAD (AI Agent Definition) standard. Each of the platform's 530+ agents is an autonomous entity with a defined tier level, capability set, operational boundaries, and coordination protocol. These entities range from L4 operational specialists that perform focused tasks to L1 supreme coordinators that orchestrate entire platform subsystems.
Overview
The concept of autonomous software entities emerges from the intersection of multi-agent systems theory, distributed computing, and the actor model of concurrent computation. Where traditional software design centers on functions that transform inputs to outputs, autonomous entity design centers on persistent actors that maintain state, pursue goals, and interact with their environment over extended lifespans.
The key distinction between an autonomous entity and a conventional service is the locus of control. A service responds to requests passively -- it does nothing unless asked. An autonomous entity actively monitors its environment, evaluates conditions against its objectives, and initiates actions when appropriate. This shift from reactive to proactive behaviour enables systems that adapt, self-heal, and evolve without constant human intervention.
In the BEAM VM execution model, autonomous entities map naturally to lightweight processes managed by OTP supervision trees. Each entity is a GenServer process with its own heap, mailbox, and execution thread. The BEAM scheduler provides preemptive multitasking across all entities, and the supervision infrastructure provides automatic restart on failure. This alignment between the autonomous entity abstraction and the runtime execution model is what makes Elixir an exceptionally natural host for multi-agent systems.
Core Properties of Autonomous Entities
| Property | Description | Prismatic Implementation |
|---|---|---|
| Autonomy | Operates without external control within boundaries | AIAD tier-based authority levels |
| Reactivity | Perceives environment and responds to changes | Telemetry event subscriptions, message handlers |
| Proactivity | Initiates goal-directed behaviour | Scheduled tasks, condition-triggered actions |
| Social Ability | Communicates and coordinates with other entities | Structured message protocols, registry-based discovery |
| Persistence | Maintains state across interactions | GenServer state, ETS backing, disk persistence |
| Fault Isolation | Failures do not propagate to other entities | BEAM process isolation, supervision trees |
Technical Details
Entity Architecture
An autonomous software entity in Prismatic consists of four layers: the execution substrate (BEAM process), the state management layer (GenServer callbacks), the decision engine (domain logic), and the coordination interface (message protocol).
┌─────────────────────────────────────────┐
│ Coordination Interface │
│ (message protocol, registry, discovery) │
├─────────────────────────────────────────┤
│ Decision Engine │
│ (goals, rules, boundary enforcement) │
├─────────────────────────────────────────┤
│ State Management Layer │
│ (GenServer callbacks, ETS, persistence) │
├─────────────────────────────────────────┤
│ Execution Substrate │
│ (BEAM process, scheduler, mailbox) │
└─────────────────────────────────────────┘Entity Lifecycle
Autonomous entities follow a well-defined lifecycle managed by their supervising process:
defmodule Prismatic.AutonomousEntity do
@moduledoc """
Base module for autonomous software entities in the Prismatic Platform.
Provides lifecycle management, decision boundary enforcement,
and coordination protocol support.
"""
@callback init_entity(config :: map()) :: {:ok, state :: map()} | {:error, reason :: term()}
@callback evaluate(stimulus :: term(), state :: map()) :: {:action, action :: term(), map()} | {:wait, map()}
@callback coordinate(message :: term(), from :: pid(), state :: map()) :: {:reply, term(), map()} | {:defer, map()}
@callback boundary_check(action :: term(), state :: map()) :: :authorized | {:denied, reason :: term()}
defmacro __using__(opts) do
quote do
use GenServer
@behaviour Prismatic.AutonomousEntity
@entity_tier Keyword.get(unquote(opts), :tier, :l4)
@entity_domain Keyword.get(unquote(opts), :domain, :general)
def start_link(config) do
GenServer.start_link(__MODULE__, config, name: via_tuple(config))
end
@impl GenServer
def init(config) do
case init_entity(config) do
{:ok, entity_state} ->
schedule_evaluation()
{:ok, %{
entity: entity_state,
tier: @entity_tier,
domain: @entity_domain,
started_at: DateTime.utc_now(),
decision_count: 0
}}
{:error, reason} ->
{:stop, reason}
end
end
@impl GenServer
def handle_info(:evaluate, state) do
case evaluate(:periodic, state.entity) do
{:action, action, new_entity} ->
case boundary_check(action, state) do
:authorized ->
execute_action(action)
schedule_evaluation()
{:noreply, %{state | entity: new_entity, decision_count: state.decision_count + 1}}
{:denied, reason} ->
:telemetry.execute(
[:prismatic, :entity, :boundary_violation],
%{count: 1},
%{entity: __MODULE__, action: action, reason: reason}
)
schedule_evaluation()
{:noreply, %{state | entity: new_entity}}
end
{:wait, new_entity} ->
schedule_evaluation()
{:noreply, %{state | entity: new_entity}}
end
end
defp schedule_evaluation do
Process.send_after(self(), :evaluate, evaluation_interval())
end
defp evaluation_interval, do: :timer.seconds(30)
defp via_tuple(config) do
{:via, Registry, {Prismatic.EntityRegistry, {__MODULE__, config[:id]}}}
end
defoverridable [evaluation_interval: 0]
end
end
endDecision Boundary Enforcement
Autonomous entities operate within strict boundaries defined by their tier level. The boundary enforcement mechanism prevents entities from exceeding their authority:
| Tier | Authority | Decision Scope | Escalation Target |
|---|---|---|---|
| L1 Supreme | Platform-wide | Cross-domain orchestration | Human operator |
| L2 Tactical | Domain-wide | Multi-entity coordination | L1 commander |
| L3 Strategic | Team-scoped | Team objective pursuit | L2 coordinator |
| L4 Operational | Task-scoped | Individual task execution | L3 commander |
defmodule Prismatic.Entity.BoundaryEnforcer do
@moduledoc """
Enforces operational boundaries for autonomous entities based on
tier level and domain assignment. Non-bypassable.
"""
@spec check(action :: term(), tier :: atom(), domain :: atom()) ::
:authorized | {:denied, reason :: String.t()}
def check(action, tier, domain) do
with :ok <- check_tier_authority(action, tier),
:ok <- check_domain_scope(action, domain),
:ok <- check_rate_limits(action, tier) do
:authorized
else
{:error, reason} -> {:denied, reason}
end
end
@spec check_tier_authority(action :: term(), tier :: atom()) :: :ok | {:error, String.t()}
defp check_tier_authority(%{scope: :platform_wide}, tier) when tier not in [:l1] do
{:error, "Platform-wide actions require L1 authority, got #{}"}
end
defp check_tier_authority(%{scope: :cross_domain}, tier) when tier not in [:l1, :l2] do
{:error, "Cross-domain actions require L2+ authority, got #{}"}
end
defp check_tier_authority(_action, _tier), do: :ok
@spec check_domain_scope(action :: term(), domain :: atom()) :: :ok | {:error, String.t()}
defp check_domain_scope(%{target_domain: target}, domain) when target != domain do
{:error, "Entity in domain #{} cannot act on domain #{}"}
end
defp check_domain_scope(_action, _domain), do: :ok
@spec check_rate_limits(action :: term(), tier :: atom()) :: :ok | {:error, String.t()}
defp check_rate_limits(_action, _tier), do: :ok
endEntity Coordination Protocol
Autonomous entities communicate through structured message protocols rather than ad-hoc function calls. This enables decoupling, asynchronous coordination, and protocol evolution:
defmodule Prismatic.Entity.Protocol do
@moduledoc """
Structured coordination protocol for inter-entity communication.
All messages carry metadata for tracing, authorization, and ordering.
"""
@type envelope :: %{
from: pid(),
to: pid() | atom(),
message_type: :request | :response | :notification | :escalation,
payload: term(),
correlation_id: String.t(),
timestamp: DateTime.t(),
ttl: non_neg_integer()
}
@spec send_request(target :: pid() | atom(), payload :: term(), opts :: keyword()) ::
{:ok, reference()} | {:error, term()}
def send_request(target, payload, opts \\ []) do
envelope = %{
from: self(),
to: target,
message_type: :request,
payload: payload,
correlation_id: generate_correlation_id(),
timestamp: DateTime.utc_now(),
ttl: Keyword.get(opts, :ttl, 30_000)
}
case GenServer.call(target, {:entity_message, envelope}, envelope.ttl) do
{:ok, response} -> {:ok, response}
{:error, reason} -> {:error, reason}
end
end
@spec generate_correlation_id() :: String.t()
defp generate_correlation_id do
:crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower)
end
endEntity Discovery and Registry
Entities discover each other through a registry that supports capability-based lookup:
defmodule Prismatic.EntityRegistry do
@moduledoc """
Registry for autonomous entity discovery. Supports lookup by
capability, domain, tier, and custom metadata.
"""
use GenServer
@spec find_by_capability(capability :: atom()) :: {:ok, [pid()]} | {:error, :none_found}
def find_by_capability(capability) do
case Registry.select(Prismatic.EntityRegistry, [
{{:"$1", :"$2", :"$3"}, [{:==, {:map_get, :capability, :"$3"}, capability}], [:"$2"]}
]) do
[] -> {:error, :none_found}
pids -> {:ok, pids}
end
end
@spec find_by_domain(domain :: atom()) :: {:ok, [pid()]} | {:error, :none_found}
def find_by_domain(domain) do
case Registry.select(Prismatic.EntityRegistry, [
{{:"$1", :"$2", :"$3"}, [{:==, {:map_get, :domain, :"$3"}, domain}], [:"$2"]}
]) do
[] -> {:error, :none_found}
pids -> {:ok, pids}
end
end
endImplementation in Prismatic Platform
The Prismatic Platform implements autonomous software entities through the AIAD standard, where each of the 530+ agents is a formally defined autonomous entity. The implementation spans several layers:
AIAD Agent as Autonomous Entity
Every AIAD agent specification (.aiad/agents/*.agent.md) defines:
- Identity: Unique name, version, tier level
- Capabilities: What the entity can do
- Boundaries: What the entity is forbidden from doing
- Dependencies: Other entities it requires
- Protocols: Communication patterns it supports
- Enforcement: Doctrine compliance requirements (NO MERCY, NO DOUBTS)
Platform Entity Hierarchy
L1 Supreme Entities
├── archer-supreme (Platform-wide orchestration)
├── supreme-coordinator (Cross-domain synthesis)
└── quality-supreme (Quality enforcement)
L2 Tactical Entities
├── red-commander (Adversarial simulation)
├── blue-commander (Epistemic defense)
├── purple-coordinator (Synthesis & closure)
└── white-verifier-commander (Formal verification)
L3 Strategic Entities
├── Domain commanders (16 domains)
├── Team leads (6 color teams)
└── Pipeline coordinators
L4 Operational Entities
├── 370+ specialist agents
├── Tool adapters (120 OSINT tools)
└── Quality monitorsSelf-Healing Through Autonomy
Autonomous entities in Prismatic implement self-healing patterns through the supervision tree and Quality Floor Guardian:
defmodule Prismatic.Entity.SelfHealing do
@moduledoc """
Self-healing capabilities for autonomous entities.
Monitors health metrics and triggers corrective actions.
"""
@spec health_check(state :: map()) :: {:healthy, map()} | {:degraded, map(), [action]}
when action: {:restart_subsystem, atom()} | {:shed_load, float()} | {:escalate, atom()}
def health_check(state) do
checks = [
check_mailbox_depth(self()),
check_memory_usage(self()),
check_decision_latency(state),
check_error_rate(state)
]
case Enum.filter(checks, &match?({:warning, _}, &1)) do
[] -> {:healthy, state}
warnings -> {:degraded, state, derive_actions(warnings)}
end
end
@spec check_mailbox_depth(pid()) :: :ok | {:warning, :mailbox_overflow}
defp check_mailbox_depth(pid) do
{:message_queue_len, len} = Process.info(pid, :message_queue_len)
if len > 1000, do: {:warning, :mailbox_overflow}, else: :ok
end
@spec check_memory_usage(pid()) :: :ok | {:warning, :memory_pressure}
defp check_memory_usage(pid) do
{:memory, bytes} = Process.info(pid, :memory)
if bytes > 100_000_000, do: {:warning, :memory_pressure}, else: :ok
end
@spec check_decision_latency(map()) :: :ok | {:warning, :slow_decisions}
defp check_decision_latency(%{avg_decision_ms: avg}) when avg > 500 do
{:warning, :slow_decisions}
end
defp check_decision_latency(_state), do: :ok
@spec check_error_rate(map()) :: :ok | {:warning, :high_error_rate}
defp check_error_rate(%{error_rate: rate}) when rate > 0.05 do
{:warning, :high_error_rate}
end
defp check_error_rate(_state), do: :ok
@spec derive_actions([{:warning, atom()}]) :: [term()]
defp derive_actions(warnings) do
Enum.map(warnings, fn
{:warning, :mailbox_overflow} -> {:shed_load, 0.5}
{:warning, :memory_pressure} -> {:restart_subsystem, :cache}
{:warning, :slow_decisions} -> {:shed_load, 0.3}
{:warning, :high_error_rate} -> {:escalate, :health_critical}
end)
end
endComparison with Alternatives
| Approach | Autonomy | Fault Isolation | Coordination | State Management | Scalability |
|---|---|---|---|---|---|
| Autonomous Entities (BEAM) | Full (process-level) | Native (process crash boundaries) | Message passing | Per-process heap + ETS | Millions of entities per node |
| Microservices | Full (service-level) | Network boundary | HTTP/gRPC | Database per service | Hundreds of services |
| Actor Model (Akka) | Full (actor-level) | Supervision trees | Message passing | Actor state + persistence | Millions per JVM |
| Service Objects (OOP) | None | None (shared process) | Method calls | Shared heap | Thread-limited |
| Serverless Functions | None | Container isolation | Event triggers | Stateless | Auto-scaling |
| Kubernetes Operators | Partial (reconciliation loop) | Pod isolation | API server | etcd | Cluster-scoped |
The BEAM-based approach provides the best combination of fine-grained autonomy, lightweight fault isolation, and massive scalability. Each entity is a process weighing approximately 2KB of memory, compared to megabytes for microservices or containers. The preemptive scheduler ensures fair execution across millions of entities without cooperative scheduling risks.
Best Practices
Define explicit boundaries before implementation. Every autonomous entity must have a written specification of what it can and cannot do before any code is written. In Prismatic, this is the AIAD agent specification file. Boundaries that exist only in developers' heads are boundaries that will be violated.
Use tier-based authority hierarchies. Not all entities should have equal authority. Establish a clear hierarchy where higher-tier entities can direct lower-tier ones, but not vice versa. This prevents coordination deadlocks and provides clear escalation paths.
Implement health monitoring within each entity. Autonomous entities should monitor their own health metrics (mailbox depth, memory usage, decision latency, error rate) and take corrective action or escalate when thresholds are exceeded. Do not rely solely on external monitoring.
Prefer capability-based discovery over direct addressing. Entities should find collaborators by capability ("I need an entity that can perform DNS enumeration") rather than by name. This enables transparent replacement, load balancing, and evolution of the entity topology.
Keep entity state minimal and recoverable. An autonomous entity should be able to reconstruct its operational state from persistent storage after a restart. Design state as a cache of derived data rather than the authoritative source of truth.
Emit structured telemetry events for all decisions. Every decision an entity makes should produce a telemetry event with the input stimulus, the chosen action, and the boundary check result. This creates an audit trail essential for debugging and compliance.
Common Pitfalls
God entities that do everything. An autonomous entity that handles too many responsibilities becomes a bottleneck and a single point of failure. Apply the single responsibility principle: each entity should have one clearly defined purpose. Split god entities into focused specialists with a coordinator entity above them.
Circular coordination dependencies. When entity A waits for entity B which waits for entity A, the system deadlocks. Use asynchronous message patterns with timeouts, or introduce a coordinator entity that breaks the cycle. The BEAM's per-process mailbox model makes deadlocks visible through mailbox growth.
Ignoring boundary enforcement. Defining boundaries in specifications but not enforcing them in code creates a false sense of safety. Every action an entity takes must pass through the boundary enforcer. In Prismatic, the enforcement policy is non-bypassable.
Stateful entities without persistence. An entity that holds critical state only in its process heap loses that state on crash. Back critical state with ETS tables or disk persistence so the entity can recover after supervisor-triggered restarts.
Over-communicating entities. Entities that send messages to every other entity on every state change create an O(n^2) communication explosion. Use pub/sub patterns with topic-based filtering, or introduce aggregator entities that consolidate and fan out updates.
Premature optimization of entity count. Consolidating multiple logical entities into a single process for "efficiency" destroys fault isolation and autonomy. On the BEAM, processes are cheap (2KB each). Prefer more entities with clear boundaries over fewer entities with blurred responsibilities.
Use Cases
OSINT Intelligence Gathering
Each of Prismatic's 120 OSINT tool adapters operates as an autonomous entity that independently manages rate limits, authentication tokens, retry logic, and result caching for its specific data source. A coordinator entity dispatches queries across relevant adapters and synthesizes results.
Quality Floor Enforcement
The Quality Floor Guardian is an autonomous entity that continuously monitors code quality metrics across all 115 umbrella applications. When quality drops below thresholds, it autonomously triggers corrective actions: blocking commits, escalating to human operators, or initiating auto-healing cycles.
Color Team Security Operations
The color teams are organized as autonomous entity clusters. Red team entities generate adversarial scenarios, blue team entities produce defensive evidence, and purple team entities synthesize findings. Each entity operates independently within its domain while coordinating through structured protocols.
Session Lifecycle Management
The SessionLifecycle entity manages the lifecycle of Claude Code sessions, autonomously executing hooks at session boundaries, monitoring circuit breaker state, and coordinating with the Quality DNA system for cross-session continuity.
Related Concepts
- Autonomous Agent -- The individual agent abstraction underlying autonomous entities
- AIAD -- The standard defining agent specifications, tiers, and protocols
- Multi-Agent System -- Systems composed of multiple cooperating autonomous entities
- Self-Coordinating -- Coordination patterns where entities organize without central control
- Agent Orchestration -- Directed coordination of autonomous entities by higher-tier commanders
- GenServer -- The OTP behaviour providing the execution substrate for entities
- Supervision Tree -- Fault tolerance infrastructure managing entity lifecycle
- Process Isolation -- BEAM mechanism ensuring entity failure boundaries
- Agent Tier -- Authority hierarchy governing entity capabilities
- Agent Registry -- Discovery infrastructure for finding entities by capability
See Also
- Agent Pool -- Pooling strategies for managing groups of autonomous entities
- Agent Module -- Module structure conventions for entity implementations
- Epistemic Pipeline -- Pipeline architecture connecting autonomous entity outputs
- Fault Tolerance -- System-level resilience built from entity isolation
- Color Teams -- Security entities organized into adversarial-defensive teams
- Quality Floor Guardian -- Autonomous entity for quality enforcement
- Architecture -- Platform architecture overview
- Apps -- Umbrella applications hosting autonomous entities
Connect & Contribute
Created by Tomáš Korcak (korczis) | Open Source under GHL