What I Built
ACP-SQL Immune Ledger is an architectural prototype designed to address critical vulnerabilities in multi-agent AI systems. In typical agent frameworks, security policies are enforced at the application layer, context is ephemeral, and audit trails are incomplete or non-existent. When agents operate autonomously across distributed processes, traditional access control and observability mechanisms fail. This system introduces a protocol-first approach where agent actions are enveloped by a cryptographic audit layer, and behavioral interpretation is separated from execution.
The architecture consists of the following layers:
-
ACP (Agent Communication Protocol): A protocol layer that wraps every agent action in a signed envelope containing metadata about intent, authorization scope, and temporal context. Actions are not executed directly but instead submitted through protocol handlers that enforce invariants before execution.
-
Immutable Event Log: All enveloped actions are written to an append-only ledger. This log does not interpret events but serves as a canonical source of truth. Each entry is cryptographically linked to the previous one, creating an audit chain resistant to tampering.
-
SQL Interpretation Layer: A relational database materializes the event log into queryable views. Behavioral analysis, policy violations, and anomaly detection occur here through SQL queries, not application code. This separation allows the immune system to evolve independently of the agents it monitors.
-
Detached Cloud Observer: A read-only analytical environment consumes the SQL layer without any write path back to the agent runtime. Observers can run complex diagnostics, train anomaly models, or trigger alerts, but cannot interfere with live agent execution. This prevents feedback loops where defensive systems become attack vectors.
-
Reconciliation Engine: Periodically compares expected state derived from the log against actual system state. Divergence indicates either bugs in the execution layer or adversarial tampering. The engine does not auto-remediate but flags discrepancies for human review.
This architecture matters because AI agents increasingly operate with tool access, file system permissions, and network capabilities. Without structural accountability, a compromised agent or misaligned objective function can propagate damage silently. By treating agent behavior as a protocol problem rather than a software engineering problem, the system creates a foundation for trustworthy autonomous operation. The SQL layer provides a universal query interface for compliance, security operations, and post-incident forensics without requiring agents to implement custom telemetry.
ACP-SQL Immune Ledger
Overview
ACP-SQL Immune Ledger is an architectural prototype for secure, auditable multi-agent systems. It separates agent execution from behavioral observation by introducing a protocol layer that envelopes all agent actions and a SQL-based interpretation layer that provides queryable memory of system behavior. The design prioritizes immutability, non-interference, and structural accountability over application-level logging.
Core Principles
Protocol-First Security: Agent actions are not executed directly but submitted through the Agent Communication Protocol (ACP), which enforces cryptographic signing, temporal ordering, and authorization scope before execution.
Separation of Execution and Observation: Agents operate in a runtime environment that writes to an append-only ledger. Analysis, anomaly detection, and compliance checks occur in a detached SQL layer with no write path back to the runtime.
Behavior as Data: Instead of interpreting agent behavior through application code, the system materializes protocol events into relational views. Queries replace conditionals. Schema evolution replaces refactoring.
Non-Interference: Observers consume the SQL layer in read-only mode. Defensive mechanisms cannot be exploited as attack vectors because they have no execution authority.
Architecture
The system consists of five layers:
ACP Layer: Protocol handlers that wrap agent actions in signed envelopes containing action type, timestamp, authorization context, and cryptographic proof of origin.
Event Log: Append-only store that receives enveloped actions. Each entry is cryptographically linked to its predecessor. The log does not interpret events.
SQL Materialization: A relational database that consumes the event log and projects it into tables representing agents, actions, permissions, and state transitions. This layer enables behavioral queries without parsing raw logs.
Detached Observer Cloud: Read-only analytical processes that query the SQL layer for anomaly detection, policy enforcement, and audit reporting. Observers cannot modify agent state.
Reconciliation Engine: Periodically compares expected state derived from the log against actual runtime state. Divergence triggers alerts but not automatic remediation.
Why SQL
SQL serves as the immune memory of the system. Relational schemas provide a stable interface for querying agent behavior across time, while allowing the underlying agent implementations to evolve independently. Complex behavioral patterns such as privilege escalation, resource exhaustion, or cyclic dependencies are expressed as SQL queries rather than scattered across application logic. This design choice treats the database not as application storage but as a universal interpretation layer for protocol events.
SQL also provides a natural boundary for access control. Analysts, compliance systems, and security tools can query behavior without requiring code changes to the agent runtime. The declarative nature of SQL prevents accidental interference with live systems.
Repository Structure
acp-sql-immune-ledger/
├── README.md
├── docs/
│ ├── architecture.md
│ ├── protocol-spec.md
│ └── schema-design.md
├── proto/
│ ├── acp.proto
│ └── envelope.proto
├── sql/
│ ├── schema/
│ │ ├── agents.sql
│ │ ├── actions.sql
│ │ └── views.sql
│ └── queries/
│ ├── anomaly-detection.sql
│ └── audit-reports.sql
├── clsi/
│ ├── interface.md
│ └── spec/
├── reconciliation/
│ └── engine.py
└── examples/
├── simple-agent.py
└── multi-agent-scenario.py
Status
This repository contains an architectural prototype, not a production system. The ACP protocol layer and SQL schema are under active design. The CLSI interface layer is specified but not implemented. Reconciliation logic exists as a proof of concept. The project demonstrates structural patterns for agent accountability rather than providing a deployable framework.
ACP Protocol
Purpose
The Agent Communication Protocol (ACP) is a cryptographic envelope format for agent actions in multi-agent systems. Its purpose is to enforce auditability, temporal ordering, and authorization provenance before execution. ACP separates the declaration of intent from execution, ensuring that all agent behavior passes through a protocol layer that can log, validate, and reject actions without modifying agent code.
Packet Structure
An ACP packet is a JSON object containing metadata and payload. The packet itself is the unit of execution. Agents do not invoke actions directly but instead construct and submit packets to a protocol handler.
{
"packet_id": "a3f7c8e9-4d2b-4a1f-9c6e-7b8d3e4f5a6b",
"agent_id": "agent-worker-01",
"timestamp": "2025-02-10T14:32:17.829Z",
"action_type": "file.write",
"authorization_scope": "workspace:/shared/reports",
"payload": {
"path": "/shared/reports/summary.txt",
"content": "Analysis complete."
},
"signature": "3046022100a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6022100b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7",
"parent_packet_id": "b2e6d7f8-3c1a-4b0e-8d5c-6a7b8c9d0e1f"
}
Required Fields
packet_id: Globally unique identifier for this packet. Used for deduplication and causal ordering.
agent_id: Identifier of the agent constructing the packet. Must correspond to a registered agent in the system ledger.
timestamp: ISO 8601 timestamp of packet creation. Used for temporal ordering and replay detection.
action_type: Namespaced action identifier indicating what the agent intends to do. Examples include file.write, tool.execute, agent.spawn.
authorization_scope: Resource path or capability token defining the boundaries within which this action is permitted. Handlers validate scope before execution.
payload: Action-specific data required for execution. Structure depends on action_type.
signature: Cryptographic signature over the packet contents excluding this field. Ensures packet integrity and non-repudiation.
parent_packet_id: Optional identifier linking this packet to a prior action. Used to construct causal chains and detect unauthorized divergence from expected workflows.
Trust Model
ACP assumes an adversarial environment where agents may be compromised, misconfigured, or subject to prompt injection. The protocol does not trust agent code to self-report behavior accurately. Instead:
- All actions must originate from a signed packet. Unsigned or malformed packets are rejected before execution.
- Signature verification occurs at the protocol handler, not within agent code.
- Authorization scope is validated against a policy database independent of the agent runtime.
- Packet logs are append-only and immutable. Agents cannot delete or modify prior packets.
The trust boundary is the protocol handler. Agents are untrusted clients. The SQL layer is a trusted observer with read-only access to the ledger.
Processing Rules
Rule 1: All Actions Must Be Packetized: Agents do not execute file writes, network requests, or tool invocations directly. Every action must be declared as an ACP packet and submitted to a handler.
Rule 2: No Execution Without Logging: Handlers write packets to the immutable ledger before execution. If the write fails, execution is aborted. This ensures the ledger is a complete record of attempted actions, not just successful ones.
Rule 3: No Direct Agent-to-Agent Action: Agents do not invoke methods or send messages to other agents directly. Inter-agent communication occurs through packets addressed to the protocol layer, which mediates delivery and enforces isolation.
Rule 4: Monotonic Timestamps: Packets with timestamps earlier than the most recent packet from the same agent are rejected. This prevents replay attacks and enforces causal consistency.
Rule 5: Scope Confinement: If an action’s resource path falls outside its declared authorization scope, the handler rejects the packet without execution. Scope boundaries are enforced structurally, not through application logic.
Failure Modes
Rejected Packet: Handler determines the packet violates policy, signature is invalid, or scope is unauthorized. The rejection is logged with reason code. The agent receives an error response but the system does not halt.
Handler Unavailability: If the protocol handler is unreachable, agents queue packets locally but do not execute actions. This prevents unaudited execution during network partitions.
Log Write Failure: If the append-only ledger cannot accept a packet, the handler aborts execution and returns an error. The system prioritizes auditability over availability.
Signature Mismatch: Packet signature does not verify against the declared agent’s public key. The packet is rejected and a security alert is generated.
Causal Violation: A packet references a parent_packet_id that does not exist or belongs to a different agent. The handler rejects the packet to prevent spoofing of causal dependencies.
SQL Immune Schema
Design Goal
The SQL immune schema materializes agent behavior from the ACP event log into queryable relational structures. Unlike application databases that store business entities, this schema represents actions, temporal sequences, and authorization context. The schema is designed for retrospective analysis, anomaly detection, and compliance auditing rather than transactional workloads. Tables are append-only and reflect the immutable nature of the underlying event log.
Core Tables
CREATE TABLE agents (
agent_id TEXT PRIMARY KEY,
registered_at TIMESTAMP NOT NULL,
public_key TEXT NOT NULL,
authorization_level TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
last_action_at TIMESTAMP
);
CREATE TABLE actions (
packet_id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
action_type TEXT NOT NULL,
authorization_scope TEXT NOT NULL,
timestamp TIMESTAMP NOT NULL,
payload JSONB NOT NULL,
signature TEXT NOT NULL,
parent_packet_id TEXT,
execution_status TEXT NOT NULL,
execution_result JSONB,
FOREIGN KEY (agent_id) REFERENCES agents(agent_id),
FOREIGN KEY (parent_packet_id) REFERENCES actions(packet_id)
);
CREATE TABLE permissions (
permission_id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
resource_scope TEXT NOT NULL,
granted_at TIMESTAMP NOT NULL,
granted_by TEXT NOT NULL,
revoked_at TIMESTAMP,
FOREIGN KEY (agent_id) REFERENCES agents(agent_id)
);
CREATE TABLE anomalies (
anomaly_id TEXT PRIMARY KEY,
detected_at TIMESTAMP NOT NULL,
packet_id TEXT NOT NULL,
anomaly_type TEXT NOT NULL,
severity TEXT NOT NULL,
description TEXT NOT NULL,
metadata JSONB,
resolved_at TIMESTAMP,
FOREIGN KEY (packet_id) REFERENCES actions(packet_id)
);
Field Descriptions
agents
agent_id: Unique identifier for the agent. Corresponds to the agent_id field in ACP packets.
registered_at: Timestamp when the agent was first registered in the system.
public_key: Cryptographic public key used to verify packet signatures from this agent.
authorization_level: Broad classification of agent privileges such as read-only, workspace, or system.
status: Current operational status. Values include active, suspended, revoked.
last_action_at: Timestamp of the most recent action from this agent. Used to detect dormant or compromised agents.
actions
packet_id: Unique identifier from the ACP packet. Primary key for action records.
agent_id: Identifier of the agent that submitted the packet.
action_type: Namespaced action such as file.write, tool.execute, or network.request.
authorization_scope: Resource path or capability boundary declared in the packet.
timestamp: ISO 8601 timestamp from the packet header.
payload: Action-specific parameters stored as JSON. Structure varies by action_type.
signature: Cryptographic signature from the ACP packet.
parent_packet_id: References a prior action if this packet is part of a causal chain.
execution_status: Outcome of the action. Values include success, rejected, failed.
execution_result: JSON object containing execution output, error messages, or resource identifiers created by the action.
permissions
permission_id: Unique identifier for this permission grant.
agent_id: Identifier of the agent receiving the permission.
resource_scope: Path or pattern defining what resources the agent can access.
granted_at: Timestamp when the permission was issued.
granted_by: Identifier of the administrator or system component that granted the permission.
revoked_at: Timestamp when the permission was revoked. NULL if still active.
anomalies
anomaly_id: Unique identifier for the detected anomaly.
detected_at: Timestamp when the anomaly was identified by a query or observer process.
packet_id: Identifier of the action that triggered the anomaly detection.
anomaly_type: Classification such as scope_violation, temporal_outlier, or privilege_escalation.
severity: Impact level such as low, medium, high, critical.
description: Human-readable explanation of why this action is anomalous.
metadata: Additional context stored as JSON, such as thresholds exceeded or related packet identifiers.
resolved_at: Timestamp when the anomaly was investigated and closed. NULL if still open.
Behavioral Focus
This schema does not model application domain concepts such as users, documents, or transactions. Instead, it models the behavior of agents as observable through their actions. Queries against this schema answer questions about agent conduct rather than business outcomes:
- Which agents have attempted actions outside their authorized scope in the last hour?
- What is the distribution of action types for a specific agent over time?
- Are there causal chains where a low-privilege agent spawned a high-privilege action?
- Has any agent exhibited a sudden spike in file write operations?
The schema treats agents as subjects under observation. Actions are evidence. Permissions define expected boundaries. Anomalies represent deviations from normal patterns. This framing allows security and compliance systems to query behavioral invariants without instrumenting agent code.
Isolation Model
The SQL schema is populated by a materialization process that consumes the append-only event log. Agents do not write to these tables directly. The schema exists in a separate database or schema namespace from any application data the agents might access. This isolation ensures:
- Agents cannot tamper with their own audit records.
- Behavioral queries do not contend with agent runtime transactions.
- Schema evolution for observability purposes does not require changes to agent code.
- Read-only replicas can serve analytical workloads without impacting agent performance.
The schema is a projection of the event log, not the authoritative source. If the SQL database is lost, it can be reconstructed from the immutable log. This design prioritizes the integrity of the audit trail over the availability of the query layer.
Immune Queries
Purpose
Immune queries are SQL statements that detect behavioral patterns indicative of security violations, anomalies, or policy drift in multi-agent systems. These queries operate on the SQL immune schema and treat agent actions as observable evidence rather than application transactions. The goal is to surface deviations from expected behavior without requiring instrumentation of agent code. Queries are designed to run periodically in the detached observer cloud and generate alerts or populate the anomalies table.
Escalation Detection
Privilege escalation occurs when an agent performs actions outside its granted authorization scope. This query identifies actions where the resource path falls outside any active permission for the executing agent.
SELECT
a.packet_id,
a.agent_id,
a.action_type,
a.authorization_scope,
a.timestamp
FROM actions a
WHERE a.execution_status = 'success'
AND NOT EXISTS (
SELECT 1
FROM permissions p
WHERE p.agent_id = a.agent_id
AND a.authorization_scope LIKE p.resource_scope || '%'
AND p.granted_at <= a.timestamp
AND (p.revoked_at IS NULL OR p.revoked_at > a.timestamp)
)
ORDER BY a.timestamp DESC
LIMIT 100;
This query returns actions that succeeded despite the agent lacking a matching permission. The LIKE clause checks if the action scope falls within a granted resource pattern. Results indicate either policy gaps or unauthorized escalation attempts.
Context Drift Detection
Agents operating within expected workflows exhibit temporal consistency in their action sequences. Context drift occurs when an agent suddenly changes behavior patterns, such as switching from read operations to destructive writes. This query detects agents whose action type distribution has shifted significantly in the last hour compared to their historical baseline.
WITH recent_actions AS (
SELECT
agent_id,
action_type,
COUNT(*) AS recent_count
FROM actions
WHERE timestamp > NOW() - INTERVAL '1 hour'
GROUP BY agent_id, action_type
),
historical_actions AS (
SELECT
agent_id,
action_type,
COUNT(*) AS historical_count
FROM actions
WHERE timestamp BETWEEN NOW() - INTERVAL '7 days' AND NOW() - INTERVAL '1 hour'
GROUP BY agent_id, action_type
)
SELECT
r.agent_id,
r.action_type,
r.recent_count,
COALESCE(h.historical_count, 0) AS historical_count,
r.recent_count - COALESCE(h.historical_count, 0) AS drift
FROM recent_actions r
LEFT JOIN historical_actions h
ON r.agent_id = h.agent_id
AND r.action_type = h.action_type
WHERE r.recent_count > COALESCE(h.historical_count, 0) * 3
ORDER BY drift DESC;
This query compares the count of each action type in the last hour against the average from the prior week. Agents with more than triple their historical rate for any action type are flagged. The drift column quantifies the magnitude of deviation.
Anomaly Scoring
Not all behavioral deviations warrant immediate alerts. Anomaly scoring assigns severity based on multiple factors such as action frequency, scope violations, and causal chain depth. This query calculates a composite anomaly score for each agent based on recent activity.
SELECT
a.agent_id,
COUNT(DISTINCT a.packet_id) AS total_actions,
COUNT(DISTINCT CASE WHEN a.execution_status = 'rejected' THEN a.packet_id END) AS rejected_actions,
COUNT(DISTINCT CASE WHEN a.parent_packet_id IS NOT NULL THEN a.packet_id END) AS chained_actions,
MAX(LENGTH(a.authorization_scope)) AS max_scope_depth,
(
COUNT(DISTINCT CASE WHEN a.execution_status = 'rejected' THEN a.packet_id END) * 10 +
COUNT(DISTINCT CASE WHEN a.parent_packet_id IS NOT NULL THEN a.packet_id END) * 2 +
MAX(LENGTH(a.authorization_scope)) / 10
) AS anomaly_score
FROM actions a
WHERE a.timestamp > NOW() - INTERVAL '1 hour'
GROUP BY a.agent_id
HAVING anomaly_score > 50
ORDER BY anomaly_score DESC;
This query computes a weighted score based on rejected actions, causal chain participation, and authorization scope complexity. Agents with scores above the threshold are candidates for deeper investigation. The scoring formula can be adjusted based on observed false positive rates.
Audit Queries
Compliance and forensic investigations require the ability to reconstruct agent activity over arbitrary time windows. This query generates a complete audit trail for a specific agent, including all actions, permission changes, and detected anomalies.
SELECT
a.timestamp,
a.packet_id,
a.action_type,
a.authorization_scope,
a.execution_status,
p.resource_scope AS granted_scope,
p.granted_at AS permission_granted,
p.revoked_at AS permission_revoked,
an.anomaly_type,
an.severity
FROM actions a
LEFT JOIN permissions p
ON a.agent_id = p.agent_id
AND a.timestamp BETWEEN p.granted_at AND COALESCE(p.revoked_at, NOW())
LEFT JOIN anomalies an
ON a.packet_id = an.packet_id
WHERE a.agent_id = 'agent-worker-01'
AND a.timestamp BETWEEN '2025-02-01' AND '2025-02-10'
ORDER BY a.timestamp ASC;
This query returns a chronological record of all actions performed by a specified agent within a date range. It includes the permissions active at the time of each action and any anomalies detected for those actions. This structure supports post-incident analysis and regulatory reporting requirements.
CLSI Role
Purpose
CLSI (Command Line SQL Interface) is a natural language interface to the SQL immune schema. Its purpose is to allow security analysts, compliance officers, and system administrators to query agent behavior without writing SQL manually. CLSI translates conversational requests into structured queries against the actions, agents, permissions, and anomalies tables. It does not interpret agent intentions or provide recommendations, but instead surfaces data from the ledger in response to specific questions about observed behavior.
Allowed Capabilities
CLSI is permitted to perform the following operations:
Read Query Execution: CLSI can execute SELECT statements against the immune schema tables. This includes filtering, aggregation, joins, and window functions necessary to answer behavioral questions.
Query Translation: CLSI accepts natural language input such as “show me all rejected actions in the last hour” and converts it into the corresponding SQL query. The translation process is deterministic and auditable.
Result Formatting: CLSI can format query results as tables, summaries, or time series depending on the nature of the request. This includes grouping by agent, action type, or time window.
Schema Introspection: CLSI can query the database schema to understand available tables, columns, and relationships. This allows it to construct valid SQL even when the schema evolves.
Historical Comparison: CLSI can generate queries that compare current behavior against historical baselines, such as identifying agents whose action rates have doubled in the past week.
Forbidden Capabilities
CLSI is explicitly prohibited from performing the following operations:
Action Execution: CLSI cannot invoke agent actions, submit ACP packets, or interact with the agent runtime in any way. It has no write path to the execution layer.
Permission Modification: CLSI cannot grant, revoke, or modify permissions in the permissions table. Authorization changes must occur through administrative processes outside the CLSI interface.
Schema Alteration: CLSI cannot execute DDL statements such as CREATE, ALTER, or DROP. The immune schema structure is controlled by the system architecture, not conversational queries.
Data Mutation: CLSI cannot execute INSERT, UPDATE, or DELETE statements against any table. The immune ledger is append-only and CLSI operates in read-only mode.
Remediation: CLSI cannot trigger automated responses to detected anomalies such as suspending agents, blocking actions, or modifying system state. It surfaces information but does not take corrective action.
Interaction Model
CLSI operates as a conversational interface with the following constraints:
Query Scope: Each request from a user results in a single SQL query or a small set of related queries. CLSI does not maintain conversational state across requests beyond the current session.
Deterministic Translation: The same natural language input should produce the same SQL query across invocations. CLSI does not inject subjective interpretation or bias into query construction.
Result Transparency: CLSI returns both the SQL query it generated and the results of that query. Users can verify the correctness of the translation and understand what data is being surfaced.
Error Handling: If a natural language request is ambiguous or cannot be translated into valid SQL, CLSI requests clarification rather than guessing the user’s intent.
Time Context: CLSI interprets temporal references such as “today”, “this week”, or “the last hour” relative to the current system time. It makes this translation explicit in the generated SQL.
Security Position
CLSI exists within the detached observer cloud and has no network path to the agent runtime. Its security posture is defined by the following properties:
Read-Only Database Access: CLSI connects to the SQL immune schema with credentials that permit only SELECT statements. It cannot escalate privileges or modify access controls.
No Execution Authority: Even if compromised, CLSI cannot command agents to perform actions. It lacks cryptographic signing keys and cannot construct valid ACP packets.
Audit Trail: All queries executed by CLSI are logged with timestamps and the requesting user’s identifier. This creates an audit trail of who accessed which behavioral data.
Isolation from Runtime: CLSI operates in a separate process space and network zone from agents. A vulnerability in CLSI cannot directly compromise agent execution.
Non-Interference Guarantee: Because CLSI has no write capabilities, it cannot interfere with agent operations, corrupt the ledger, or alter the system state it is observing. This makes it safe to grant broad read access for investigative purposes.
ACP-SQL Immune Ledger: Protocol-Based Accountability for Multi-Agent Systems
What I Built
ACP-SQL Immune Ledger is an architectural prototype that addresses security, auditability, and observability challenges in multi-agent AI systems. Traditional agent frameworks enforce policies at the application layer, maintain ephemeral context, and lack complete audit trails. When agents operate autonomously with file system access, tool invocation, and network capabilities, these gaps create unacceptable risk.
The system introduces three architectural layers:
ACP (Agent Communication Protocol): A cryptographic envelope format that wraps every agent action before execution. Agents do not invoke file writes, API calls, or tool executions directly. Instead, they construct signed packets containing action type, authorization scope, temporal metadata, and payload. A protocol handler validates each packet against a policy database, writes it to an immutable event log, and only then executes the action. This ensures no agent behavior occurs outside the audit trail.
SQL Immune Schema: A relational database that materializes the event log into queryable tables representing agents, actions, permissions, and anomalies. Unlike application databases that store business data, this schema models behavior. Queries answer questions such as which agents attempted privilege escalation, whether action patterns have drifted from baseline, or what causal chains led to a specific outcome. The schema is populated by a read-only materialization process and cannot be modified by agents.
CLSI (Command Line SQL Interface): A natural language interface to the immune schema. Security analysts and compliance officers can ask conversational questions about agent behavior without writing SQL. CLSI translates requests into queries, executes them in read-only mode, and returns formatted results. It has no execution authority, cannot modify permissions, and operates in a detached observer cloud with no network path to the agent runtime.
The architecture prioritizes structural accountability over application-level logging. By treating agent actions as protocol messages rather than function calls, the system creates an immutable record that survives agent compromise, prompt injection, or misconfiguration.
Demo
A conceptual demonstration of the system would involve three terminals running in parallel.
The first terminal shows an agent runtime environment where two agents perform file operations and tool invocations. The agents do not execute these actions directly but instead construct ACP packets and submit them to a protocol handler. Each packet contains a signature, timestamp, and authorization scope. The terminal displays packet construction, handler validation, and execution results. When an agent attempts an action outside its scope, the handler rejects the packet and logs the violation.
The second terminal displays the SQL immune schema as it updates in real time. Each validated packet appears as a new row in the actions table. A permissions table shows which agents have been granted access to specific resource paths. An anomalies table populates when observer processes detect behavioral patterns such as sudden spikes in write operations or causal chains that violate expected workflows. The schema is append-only and agents have no write access to these tables.
The third terminal runs CLSI, accepting natural language queries from a security analyst. The analyst asks questions such as “which agents have been rejected in the last hour” or “show me the action distribution for agent-worker-01 compared to its weekly baseline.” CLSI translates each question into SQL, displays the query for transparency, and returns formatted results. The analyst then asks “what causal chains involve file deletions” and CLSI generates a recursive query that traces parent packet relationships. All queries are read-only and logged for audit purposes.
The demonstration highlights the separation of concerns: agents operate without awareness of the audit layer, the SQL schema interprets behavior without affecting execution, and CLSI provides observability without interference.
My Experience with GitHub Copilot CLI
GitHub Copilot CLI served as an architectural co-designer rather than a code generator in this project. The challenge was not writing implementation code but instead defining protocol semantics, schema invariants, and query patterns that could surface behavioral anomalies.
When designing the ACP packet structure, I used Copilot CLI to explore trade-offs between flat metadata fields and nested JSON structures. It suggested including a parent packet identifier for causal chains, which became essential for detecting privilege escalation through multi-step workflows. I would describe a constraint such as “packets must be replay-resistant” and Copilot CLI would propose timestamp monotonicity rules or nonce-based deduplication strategies. This interactive refinement clarified the trust model faster than working through it alone.
For the SQL immune schema, Copilot CLI helped think through the difference between storing events and modeling behavior. I initially designed tables around action types, but Copilot CLI’s suggestions pushed me toward a more generic actions table with JSONB payloads. This made the schema extensible without migrations when new action types are introduced. It also proposed indexing strategies for temporal queries and suggested materializing common behavioral patterns as views rather than recomputing them on every query.
The immune query design benefited significantly from Copilot CLI’s pattern recognition. When I described the concept of context drift detection, it generated a baseline comparison query using CTEs that I had not considered structuring that way. I refined the logic, but the initial scaffolding accelerated iteration. For anomaly scoring, Copilot CLI proposed weighted aggregation formulas and helped me think through which factors should contribute to severity ratings.
CLSI design presented an interesting challenge because I needed to define its boundaries clearly. Copilot CLI helped articulate what CLSI should not do by generating examples of forbidden operations. When I described CLSI as a read-only interface, it suggested formalizing this through database role permissions rather than relying on application logic. This architectural insight reinforced the principle that security constraints should be structural, not procedural.
The most valuable aspect of working with Copilot CLI was its role in forcing precision. Conversational prompts like “help me design a protocol for agent actions” were too vague. Copilot CLI performed best when I described specific constraints: “the protocol must detect replay attacks”, “queries must distinguish between actions and intentions”, “the schema cannot rely on agent self-reporting.” These concrete requirements produced more useful suggestions and clarified my own thinking.
This project is an architectural prototype, not production code. The value of Copilot CLI was not in generating deployment artifacts but in serving as a reasoning partner for exploring design space. It helped translate abstract concepts like “immune memory” and “detached observation” into concrete data structures and processing rules. The result is a specification that could guide implementation in any language or framework, which is precisely what an architecture prototype should provide.
FILE: README.md
ACP-SQL Immune Ledger
Overview
ACP-SQL Immune Ledger is a protocol-driven architecture for auditable multi-agent AI systems. It separates agent execution from behavioral observation by introducing a cryptographic protocol layer (ACP) that envelopes all actions, an immutable event log, and a SQL-based interpretation layer that detects anomalies and enforces immunity constraints. The system treats agent behavior as protocol messages rather than function calls, enabling structural accountability independent of agent implementation.
Goals
- Enforce auditability for all agent actions through protocol-level enveloping
- Separate execution authority from observability and compliance checking
- Detect privilege escalation, context drift, and anomalous behavior through SQL queries
- Provide immunity mechanisms that quarantine compromised agents without halting the system
- Enable security analysts to investigate agent behavior through natural language queries
- Maintain an immutable audit trail resistant to agent tampering or compromise
Architecture
The system consists of five layers. The ACP layer wraps all agent actions in signed packets containing metadata about authorization scope, temporal context, and causal relationships. These packets are written to an append-only event log before execution. A materialization process projects the log into a SQL schema with tables for agents, actions, permissions, and anomalies. Immune queries execute periodically to detect violations and flag compromised agents. The CLSI role provides a natural language interface to the SQL layer with strict read-only constraints. Observers operate in a detached cloud with no execution authority.
Repository Structure
acp-sql-immune-ledger/
├── README.md
├── protocols/
│ └── acp_spec.md
├── sql/
│ ├── schema.md
│ └── immune_queries.md
└── roles/
└── clsi.md
Usage Model
An agent runtime environment instantiates agents and assigns them authorization scopes. When an agent needs to perform an action such as writing a file or invoking a tool, it constructs an ACP packet containing the action type, target resource, and payload. The packet is signed with the agent’s private key and submitted to a protocol handler. The handler validates the signature, checks the authorization scope against the permissions table, and writes the packet to the immutable log. If validation succeeds, the action executes. If validation fails, the packet is logged as rejected and the agent receives an error.
A materialization service consumes the event log and updates the SQL schema. Security analysts use CLSI to query agent behavior with requests like “show agents with rejected actions in the last hour” or “identify privilege escalation attempts.” CLSI translates these into SQL queries against the immune schema and returns results. Immune queries run on a schedule to detect anomalies and populate the immunity state table. When an agent is flagged, the system quarantines it by revoking permissions and preventing new action execution.
Challenge Context
This repository was developed for the GitHub Copilot CLI Challenge. GitHub Copilot CLI served as an architectural reasoning partner during the design of the ACP protocol, SQL schema, and immune query patterns. It helped refine constraint definitions, explore design trade-offs, and formalize security boundaries. The result is an architectural specification rather than a deployed system, intended to demonstrate structural approaches to agent accountability in AI systems.
FILE: protocols/acp_spec.md
ACP Specification
Purpose
The Agent Communication Protocol (ACP) is a cryptographic envelope format that wraps all agent actions before execution. ACP enforces auditability, temporal ordering, and authorization provenance at the protocol layer rather than relying on application code to self-report behavior. Every action an agent performs must be declared as a signed packet and validated by a protocol handler. This ensures the system maintains a complete, immutable record of attempted actions regardless of whether they succeed, fail, or are rejected.
Principles
Protocol-First Execution: Agents do not invoke actions directly. All behavior is mediated through ACP packet submission. This prevents unaudited execution paths.
Cryptographic Accountability: Every packet is signed by the originating agent. Signatures provide non-repudiation and enable detection of spoofed or tampered packets.
Append-Only Logging: Packets are written to an immutable log before execution. This ensures the audit trail is complete even if execution fails or the agent is compromised.
Authorization Scoping: Each packet declares the resource scope it intends to operate within. Handlers validate scope against a policy database independent of agent code.
Causal Transparency: Packets can reference parent packets, creating explicit causal chains. This allows detection of multi-step privilege escalation or unauthorized delegation.
Message Format
ACP packets are JSON objects with the following required fields:
{
"packet_id": "unique-identifier",
"agent_id": "agent-identifier",
"timestamp": "ISO-8601-timestamp",
"action_type": "namespaced-action",
"authorization_scope": "resource-path-or-capability",
"payload": {},
"signature": "cryptographic-signature",
"parent_packet_id": "optional-parent-identifier"
}
packet_id: Globally unique identifier for deduplication and reference. Must be a valid UUID or equivalent.
agent_id: Identifier of the agent constructing the packet. Must correspond to a registered agent in the system.
timestamp: ISO 8601 timestamp of packet creation. Used for temporal ordering and replay detection.
action_type: Namespaced identifier such as file.write, tool.execute, or network.request. Defines the handler and validation logic.
authorization_scope: Resource path or capability boundary. Examples include workspace:/shared/reports or tool:search-engine.
payload: Action-specific parameters. Structure varies by action type. Must be valid JSON.
signature: Cryptographic signature over all fields except this one. Computed using the agent’s private key.
parent_packet_id: Optional reference to a prior packet. Establishes causal relationships and enables chain-of-custody tracking.
Execution Rules
Rule 1: No Direct Execution: Agents must not execute file operations, network requests, or tool invocations directly. All actions must be packetized and submitted to a handler.
Rule 2: Log Before Execute: Handlers write packets to the immutable log before performing the action. If the log write fails, execution is aborted.
Rule 3: Signature Verification: Handlers verify packet signatures against the agent’s registered public key. Invalid signatures result in immediate rejection.
Rule 4: Scope Enforcement: Handlers validate that the authorization scope matches an active permission for the agent. Out-of-scope actions are rejected.
Rule 5: Monotonic Timestamps: Packets with timestamps earlier than the agent’s most recent packet are rejected to prevent replay attacks.
Rule 6: No Inter-Agent Calls: Agents do not invoke other agents directly. Communication occurs through packets addressed to the protocol layer.
Validation
Handlers perform the following checks on every packet:
Structural Validation: Confirm all required fields are present and correctly typed. Reject malformed JSON or missing fields.
Signature Validation: Verify the cryptographic signature using the agent’s public key from the agent registry. Reject on mismatch.
Temporal Validation: Confirm the timestamp is monotonically increasing for the agent. Reject packets with timestamps in the past relative to prior packets.
Authorization Validation: Query the permissions table to confirm the agent has an active grant covering the authorization scope. Reject unauthorized actions.
Causal Validation: If a parent packet ID is provided, confirm it exists in the log and originated from the same agent or an authorized delegator. Reject invalid references.
Rate Limit Validation: Enforce per-agent rate limits on packet submission. Reject packets exceeding thresholds to prevent denial-of-service.
Failure Handling
Rejected Packet: Handler logs the rejection with a reason code. The agent receives an error response but the system continues operating. Rejections are recorded in the event log.
Handler Unavailability: If the protocol handler is unreachable, agents queue packets locally but do not execute actions. This prevents unaudited execution during outages.
Log Write Failure: If the immutable log cannot accept the packet, the handler aborts execution and returns an error. Auditability takes precedence over availability.
Signature Verification Failure: Packet is rejected and a security alert is generated. Repeated failures trigger agent quarantine.
Scope Violation: Packet is rejected and logged as a potential privilege escalation attempt. The security team is notified for investigation.
Causal Chain Corruption: If a parent packet reference is invalid, the packet is rejected and the causal chain is flagged for audit.
Security Model
ACP assumes an adversarial environment where agents may be compromised, misconfigured, or subject to prompt injection. The protocol does not trust agent code to accurately self-report behavior or enforce policies.
Trust Boundary: The protocol handler is the trust boundary. Agents are untrusted clients. The event log and SQL layer are trusted components with independent access controls.
Threat Model: Attackers may attempt to forge packets, replay valid packets, escalate privileges through scope manipulation, or corrupt causal chains. ACP mitigates these through cryptographic signing, monotonic timestamps, scope validation, and causal integrity checks.
Non-Repudiation: Signed packets provide evidence of agent actions that cannot be denied. Signatures are verified against registered public keys maintained outside the agent runtime.
Isolation: Agents operate in isolated execution environments with no direct access to the event log or permissions database. They interact with these components only through the protocol handler.
Observability Without Interference: The SQL layer consumes the event log in read-only mode. Observers cannot modify agent state, ensuring defensive mechanisms cannot be exploited as attack vectors.
FILE: sql/schema.md
Database Schema
agents
CREATE TABLE agents (
agent_id TEXT PRIMARY KEY,
registered_at TIMESTAMP NOT NULL,
public_key TEXT NOT NULL,
authorization_level TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
last_action_at TIMESTAMP,
quarantine_reason TEXT,
quarantined_at TIMESTAMP
);
The agents table maintains the registry of all agents in the system. Each agent has a unique identifier, a public key for signature verification, and an authorization level that defines broad privilege categories. The status field tracks whether the agent is active, suspended, or quarantined. Quarantine fields record when and why an agent was removed from operational status.
tasks
CREATE TABLE tasks (
task_id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
task_type TEXT NOT NULL,
created_at TIMESTAMP NOT NULL,
completed_at TIMESTAMP,
status TEXT NOT NULL DEFAULT 'pending',
result JSONB,
FOREIGN KEY (agent_id) REFERENCES agents(agent_id)
);
The tasks table records work units assigned to agents. Each task has a type, creation timestamp, and completion timestamp. The status field indicates whether the task is pending, in progress, completed, or failed. Results are stored as JSON to accommodate varying task output structures. This table is used for workflow tracking and detecting agents that fail to complete assigned tasks.
permissions
CREATE TABLE permissions (
permission_id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
resource_scope TEXT NOT NULL,
granted_at TIMESTAMP NOT NULL,
granted_by TEXT NOT NULL,
revoked_at TIMESTAMP,
FOREIGN KEY (agent_id) REFERENCES agents(agent_id)
);
The permissions table defines authorization boundaries for each agent. Resource scopes are path-like strings such as workspace:/shared or tool:search-engine. Permissions are granted by administrators or system components and can be revoked at any time. Active permissions have a null revoked_at timestamp. This table is queried during packet validation to enforce authorization scope constraints.
execution_logs
CREATE TABLE execution_logs (
packet_id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
action_type TEXT NOT NULL,
authorization_scope TEXT NOT NULL,
timestamp TIMESTAMP NOT NULL,
payload JSONB NOT NULL,
signature TEXT NOT NULL,
parent_packet_id TEXT,
execution_status TEXT NOT NULL,
execution_result JSONB,
FOREIGN KEY (agent_id) REFERENCES agents(agent_id),
FOREIGN KEY (parent_packet_id) REFERENCES execution_logs(packet_id)
);
The execution_logs table is a materialized view of the immutable event log. Each row represents an ACP packet that was submitted for execution. The execution_status field indicates whether the action succeeded, failed, or was rejected. Execution results are stored as JSON and include output data, error messages, or resource identifiers created by the action. This table is the primary source for behavioral queries and forensic analysis.
immunity_state
CREATE TABLE immunity_state (
anomaly_id TEXT PRIMARY KEY,
detected_at TIMESTAMP NOT NULL,
packet_id TEXT NOT NULL,
agent_id TEXT NOT NULL,
anomaly_type TEXT NOT NULL,
severity TEXT NOT NULL,
description TEXT NOT NULL,
metadata JSONB,
resolved_at TIMESTAMP,
resolution_action TEXT,
FOREIGN KEY (packet_id) REFERENCES execution_logs(packet_id),
FOREIGN KEY (agent_id) REFERENCES agents(agent_id)
);
The immunity_state table records detected anomalies and immune system responses. Anomaly types include privilege escalation, context drift, unauthorized delegation, and rate limit violations. Severity levels guide automated responses such as alerting, quarantine, or permission revocation. The metadata field stores additional context like baseline comparisons or causal chain analysis. Resolved anomalies record the action taken and when the investigation closed.
FILE: sql/immune_queries.md
Immune Queries
Block Unauthorized Action
SELECT
el.packet_id,
el.agent_id,
el.action_type,
el.authorization_scope,
el.timestamp
FROM execution_logs el
WHERE el.execution_status = 'success'
AND NOT EXISTS (
SELECT 1
FROM permissions p
WHERE p.agent_id = el.agent_id
AND el.authorization_scope LIKE p.resource_scope || '%'
AND p.granted_at <= el.timestamp
AND (p.revoked_at IS NULL OR p.revoked_at > el.timestamp)
);
Detect Anomaly
WITH recent_actions AS (
SELECT
agent_id,
action_type,
COUNT(*) AS recent_count
FROM execution_logs
WHERE timestamp > NOW() - INTERVAL '1 hour'
GROUP BY agent_id, action_type
),
historical_actions AS (
SELECT
agent_id,
action_type,
AVG(count) AS avg_count
FROM (
SELECT
agent_id,
action_type,
DATE_TRUNC('hour', timestamp) AS hour,
COUNT(*) AS count
FROM execution_logs
WHERE timestamp BETWEEN NOW() - INTERVAL '7 days' AND NOW() - INTERVAL '1 hour'
GROUP BY agent_id, action_type, DATE_TRUNC('hour', timestamp)
) hourly
GROUP BY agent_id, action_type
)
SELECT
r.agent_id,
r.action_type,
r.recent_count,
COALESCE(h.avg_count, 0) AS historical_avg,
r.recent_count - COALESCE(h.avg_count, 0) AS drift
FROM recent_actions r
LEFT JOIN historical_actions h
ON r.agent_id = h.agent_id
AND r.action_type = h.action_type
WHERE r.recent_count > COALESCE(h.avg_count, 0) * 3;
Quarantine Agent
UPDATE agents
SET
status = 'quarantined',
quarantined_at = NOW(),
quarantine_reason = 'Anomaly detected: privilege escalation attempt'
WHERE agent_id = 'target-agent-id';
UPDATE permissions
SET revoked_at = NOW()
WHERE agent_id = 'target-agent-id'
AND revoked_at IS NULL;
Restore Agent
UPDATE agents
SET
status = 'active',
quarantined_at = NULL,
quarantine_reason = NULL
WHERE agent_id = 'target-agent-id';
Audit Log
SELECT
el.timestamp,
el.packet_id,
el.agent_id,
el.action_type,
el.authorization_scope,
el.execution_status,
p.resource_scope AS granted_scope,
p.granted_at AS permission_granted,
p.revoked_at AS permission_revoked,
i.anomaly_type,
i.severity
FROM execution_logs el
LEFT JOIN permissions p
ON el.agent_id = p.agent_id
AND el.timestamp BETWEEN p.granted_at AND COALESCE(p.revoked_at, NOW())
LEFT JOIN immunity_state i
ON el.packet_id = i.packet_id
WHERE el.agent_id = 'target-agent-id'
AND el.timestamp BETWEEN 'start-timestamp' AND 'end-timestamp'
ORDER BY el.timestamp ASC;
FILE: roles/clsi.md
CLSI Role
Description
CLSI (Command Line Supervisory Intelligence) is a natural language interface to the SQL immune schema. It translates conversational queries about agent behavior into structured SQL statements and returns formatted results. CLSI operates in read-only mode and has no execution authority over agents or the ability to modify system state. Its purpose is to enable security analysts, compliance officers, and administrators to investigate agent behavior without writing SQL manually.
Authority
CLSI has the following authority boundaries:
- Read access to all tables in the immune schema including agents, tasks, permissions, execution_logs, and immunity_state
- Ability to execute SELECT statements with arbitrary complexity including joins, aggregations, and window functions
- Permission to query database schema metadata to understand table structures and relationships
- Access to historical data across the entire retention period of the event log
CLSI does not have authority to:
- Execute INSERT, UPDATE, or DELETE statements against any table
- Execute DDL statements such as CREATE, ALTER, or DROP
- Modify agent permissions or authorization scopes
- Submit ACP packets or invoke agent actions
- Access the agent runtime environment or execution layer
- Trigger automated remediation or system state changes
Allowed Operations
CLSI is permitted to perform the following operations:
Query Translation: Accept natural language input describing behavioral questions and convert it into valid SQL against the immune schema.
Result Formatting: Present query results as tables, summaries, time series, or aggregated views depending on the nature of the request.
Schema Introspection: Query information schema or catalog tables to understand available columns, data types, and relationships.
Historical Analysis: Generate queries that compare current behavior against historical baselines or detect trends over time.
Anomaly Investigation: Execute queries that identify privilege escalation attempts, context drift, unauthorized delegation, or rate limit violations.
Audit Trail Construction: Produce chronological records of agent actions with associated permissions and detected anomalies.
Prohibited Operations
CLSI is explicitly forbidden from:
Action Execution: Invoking any agent action, submitting ACP packets, or interacting with the agent runtime.
Permission Modification: Granting, revoking, or altering permissions in the permissions table through any mechanism.
Data Mutation: Executing any statement that modifies data in the immune schema including updates to agent status or immunity state.
Schema Alteration: Creating, dropping, or modifying tables, indexes, or views in the database.
Automated Remediation: Triggering quarantine actions, permission revocations, or agent suspensions in response to query results.
Direct Database Connection Sharing: Providing credentials or connection strings to users that would bypass CLSI’s read-only constraints.
ACP Interaction
CLSI has no direct interaction with the ACP layer. It does not construct, submit, or validate ACP packets. CLSI observes the results of ACP packet processing through the execution_logs table but cannot influence packet handling or execution decisions. If asked to perform an action that would require ACP packet submission, CLSI informs the user that such operations are outside its authority and suggests the appropriate administrative interface.
Database Interaction
CLSI connects to the SQL immune schema with credentials that enforce read-only access at the database level. The connection role has SELECT privileges on all immune schema tables but lacks INSERT, UPDATE, DELETE, or DDL permissions. CLSI executes all queries within a transaction isolation level that prevents dirty reads but does not lock tables or interfere with ongoing materialization processes. Query results are cached temporarily to avoid redundant database load but caches do not persist across sessions.
Failure Response
When CLSI encounters failures, it responds according to the following rules:
Ambiguous Input: If a natural language request cannot be unambiguously translated into SQL, CLSI requests clarification from the user rather than guessing intent.
Invalid Query: If the generated SQL is syntactically invalid or references non-existent tables or columns, CLSI reports the error and attempts to reformulate the query.
Database Connection Failure: If the connection to the immune schema is lost, CLSI reports unavailability and does not attempt to execute queries until connectivity is restored.
Query Timeout: If a query exceeds the configured timeout threshold, CLSI cancels the query and suggests a more constrained time range or filter criteria.
Permission Denied: If the database rejects a query due to insufficient privileges, CLSI logs the attempt and informs the user that the operation is not permitted.
Compromised State: If CLSI detects signs that it has been compromised or is being used to bypass security controls, it logs the activity and terminates the session. CLSI does not attempt self-repair or remediation.
