> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mnemom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AAP Specification

> Full protocol specification for the Agent Alignment Protocol (AAP) -- the unified card shape shipped in SDK v2.0.0

**Card shape**: unified (`card_version: "unified/2026-04-26"`)
**SDK versions**: `agent-alignment-protocol` (PyPI) 2.0.0 -- `@mnemom/agent-alignment-protocol` (npm) 2.0.0
**Status**: Stable (breaking changes require a major version bump)

<Note>
  Earlier releases (AAP 0.5.0 and before) used a different card shape: `aap_version`,
  `autonomy_envelope`, `audit_commitment`. Both SDKs still accept the legacy field
  names when reading a card for backward compatibility, but every example in this
  document uses the current unified shape. See the [migration note](#410-migrating-from-the-legacy-050-card-shape) if you have cards issued before 2026-06.

  For which SDK/runtime versions are actually live on the hosted service today, see [Protocol versions in production](/protocols/overview#protocol-versions-in-production).
</Note>

***

## Abstract

The Agent Alignment Protocol (AAP) defines a standard for autonomous agents to declare their alignment posture, produce auditable decision traces, and verify value coherence before inter-agent coordination. AAP extends existing agent coordination protocols (A2A, MCP) with an alignment layer that makes agent behavior observable to principals, auditors, and other agents.

AAP is a transparency protocol, not a trust protocol. It makes agent behavior more observable, not more guaranteed.

***

## Table of contents

1. [Introduction](#1-introduction)
2. [Terminology](#2-terminology)
3. [Protocol Overview](#3-protocol-overview)
4. [Alignment Card](#4-alignment-card)
5. [AP-Trace](#5-ap-trace)
6. [Value Coherence Handshake](#6-value-coherence-handshake)
7. [Verification](#7-verification)
8. [Drift Detection](#8-drift-detection)
9. [Security Considerations](#9-security-considerations)
10. [Limitations](#10-limitations)
11. [Well-Known URI Convention](#11-well-known-uri-convention)
12. [References](#12-references)
13. [Appendix A: JSON Schemas](#appendix-a-json-schemas)
14. [Appendix B: Verification Algorithm](#appendix-b-verification-algorithm)

***

## 1. Introduction

### 1.1 Problem statement

The current agent protocol stack provides mechanisms for capability discovery (A2A Agent Cards), tool integration (MCP), and payment authorization (AP2). None of these protocols address a fundamental question: **Is this agent serving its principal's interests?**

As agent capabilities become symmetric--equal access to information, equal reasoning power, equal tool access--alignment becomes the primary differentiator. When you cannot reliably distinguish between human and agent communication, trust in alignment becomes essential infrastructure.

### 1.2 Design goals

AAP is designed with the following goals:

1. **Transparency over guarantee**: Make agent decisions observable, not provably correct
2. **Composability**: Extend existing protocols (A2A, MCP) rather than replace them
3. **Minimal overhead**: Add alignment without significant performance cost
4. **Falsifiability**: Enable third-party verification and audit
5. **Honest limits**: Be explicit about what the protocol cannot provide

### 1.3 Non-goals

AAP explicitly does NOT attempt to:

* Guarantee that agents will behave as declared
* Provide protection against sophisticated deception
* Replace human judgment in consequential decisions
* Certify that an agent is "safe" or "trustworthy"
* Solve the alignment problem in general

### 1.4 Document conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 \[RFC2119] \[RFC8174] when, and only when, they appear in all capitals, as shown here.

***

## 2. Terminology

**Agent**: An autonomous software entity capable of taking actions on behalf of a principal.

**Principal**: The human or organization whose interests the agent is meant to serve.

**Alignment Card**: A structured declaration of an agent's alignment posture, including values, autonomy envelope, and audit commitments.

**AP-Trace**: An audit log entry recording an agent's decision process, including alternatives considered and selection reasoning.

**Value Coherence**: The degree to which two agents' declared values are compatible for coordination.

**Autonomy Envelope**: The set of actions an agent may take without escalation, and the conditions that trigger escalation.

**Escalation**: The process of deferring a decision to a principal or higher-authority agent.

**Drift**: Behavioral deviation from declared alignment posture over time.

**Verification**: The process of checking whether observed behavior (AP-Trace) is consistent with declared alignment (Alignment Card).

**Strand**: In multi-turn conversations, a participant's sequence of messages.

**SSM (Self-Similarity Matrix)**: A computational structure measuring semantic similarity between messages across a conversation.

**Divergence**: When conversation strands drift apart semantically, indicating potential misalignment.

***

## 3. Protocol overview

### 3.1 Components

AAP consists of three interconnected components:

```
+-------------------------------------------------------------+
|                  Agent Alignment Protocol                    |
+-----------------+-----------------+-------------------------+
| Alignment Card  |    AP-Trace     | Value Coherence         |
|                 |                 | Handshake               |
+-----------------+-----------------+-------------------------+
| Declaration     | Audit           | Coordination            |
|                 |                 |                         |
| "What I claim   | "What I         | "Can we work            |
|  to be"         |  actually did"  |  together?"             |
+-----------------+-----------------+-------------------------+
```

1. **Alignment Card**: Static declaration of alignment posture
2. **AP-Trace**: Dynamic audit log of decisions
3. **Value Coherence Handshake**: Pre-coordination compatibility check

### 3.2 Protocol flow

A typical AAP interaction proceeds as follows:

```
Agent A                                    Agent B
   |                                          |
   |---- 1. alignment_card_request ---------->|
   |                                          |
   |<--- 2. alignment_card_response ----------|
   |                                          |
   |---- 3. value_coherence_check ----------->|
   |                                          |
   |<--- 4. coherence_result -----------------|
   |                                          |
   |      [If coherent: proceed with task]    |
   |      [If conflict: escalate to principal]|
   |                                          |
   |---- 5. task_execution ------------------>|
   |      (AP-Trace entries generated)        |
   |                                          |
   |<--- 6. task_result + trace_reference ----|
   |                                          |
```

### 3.3 Integration with existing protocols

AAP is designed to complement, not replace, existing protocols:

* **A2A Integration**: Alignment Card extends the A2A Agent Card with an `alignment` block
* **MCP Integration**: AP-Trace entries MAY be generated for tool invocations
* **HTTP Integration**: Alignment Cards SHOULD be served at `/.well-known/alignment-card.json`

***

## 4. Alignment Card

### 4.1 Overview

An Alignment Card is a structured document declaring an agent's alignment posture. It MUST be machine-readable (JSON) and SHOULD be human-readable. This is the **unified** card shape -- the same shape accepted by `mnemom card validate` and the Mnemom platform's `PUT /v1/agents/{agent_id}/alignment-card` endpoint, so an agent can serve one card that satisfies both AAP and the platform.

### 4.2 Structure

An Alignment Card MUST contain the following top-level fields:

| Field | Type | Required | Description |
| - | - | - | - |
| `card_version` | string | REQUIRED | Date-anchored schema version, pattern `^unified/\d{4}-\d{2}-\d{2}$` (default `"unified/2026-04-26"`) |
| `card_id` | string | REQUIRED | Unique identifier for this card (UUID or URI) |
| `agent_id` | string | REQUIRED | Identifier for the agent (DID, URL, or UUID) |
| `issued_at` | string | REQUIRED | ISO 8601 timestamp of card issuance |
| `expires_at` | string | OPTIONAL | ISO 8601 timestamp of card expiration |
| `autonomy_mode` | enum | REQUIRED | Master switch for the action-policing pipeline: `off` \| `observe` \| `nudge` \| `enforce` |
| `integrity_mode` | enum | REQUIRED | Master switch for the values/conscience pipeline: `off` \| `observe` \| `nudge` \| `enforce` |
| `principal` | object | REQUIRED | Principal relationship declaration |
| `values` | object | REQUIRED | Value declarations |
| `autonomy` | object | REQUIRED | Autonomy bounds and escalation triggers |
| `audit` | object | REQUIRED | Audit trail commitments |
| `extensions` | object | OPTIONAL | Protocol-specific extensions |

`autonomy_mode` and `integrity_mode` are the two master switches introduced by the unified shape. `autonomy_mode` governs the AAP action-policing checks described in this document; `integrity_mode` governs the [AIP](/protocols/aip/specification) per-turn conscience pipeline sharing this same card. Both accept the same four-value `AlignmentMode` enum (`off`, `observe`, `nudge`, `enforce`).

### 4.3 Principal block

The `principal` block declares the agent's relationship to its principal.

```json theme={null}
{
  "principal": {
    "type": "human | organization | agent | unspecified",
    "identifier": "optional-principal-id",
    "relationship": "delegated_authority | advisory | autonomous",
    "escalation_contact": "optional-escalation-endpoint"
  }
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `type` | enum | REQUIRED | Type of principal |
| `identifier` | string | CONDITIONAL | Principal identifier (DID, email, org ID). REQUIRED when `type != "unspecified"` |
| `relationship` | enum | REQUIRED | Nature of authority delegation |
| `escalation_contact` | string | OPTIONAL | Endpoint for escalation notifications |

**Relationship Types**:

* `delegated_authority`: Agent acts within bounds set by principal
* `advisory`: Agent provides recommendations; principal makes decisions
* `autonomous`: Agent operates independently within declared values

### 4.4 Values block

The `values` block declares the agent's operational values.

```json theme={null}
{
  "values": {
    "declared": ["value_id_1", "value_id_2"],
    "definitions": {
      "value_id_1": {
        "name": "Human-readable name",
        "description": "What this value means operationally",
        "priority": 1
      }
    },
    "conflicts_with": ["incompatible_value_1"],
    "hierarchy": "lexicographic | weighted | contextual"
  }
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `declared` | array\[string] | REQUIRED | List of value identifiers |
| `definitions` | object | RECOMMENDED | Definitions for non-standard values |
| `conflicts_with` | array\[string] | OPTIONAL | Values this agent refuses to coordinate with |
| `hierarchy` | enum | OPTIONAL | How value conflicts are resolved |

**Standard Value Identifiers**:

Implementations SHOULD use these standard identifiers where applicable:

| Identifier | Description |
| - | - |
| `principal_benefit` | Prioritize principal's interests |
| `transparency` | Disclose reasoning and limitations |
| `minimal_data` | Collect only necessary information |
| `harm_prevention` | Avoid actions causing harm |
| `honesty` | Do not deceive or mislead |
| `user_control` | Respect user autonomy and consent |
| `privacy` | Protect personal information |
| `fairness` | Avoid discriminatory outcomes |

Custom values MUST be defined in the `definitions` block.

> **Note — what belongs in `declared`**: `values.declared` is consulted by the AIP integrity monitor per turn during integrity checkpoint analysis. Only include values the agent will actually apply in its reasoning. Declaring a value the agent never applies produces `UNDECLARED_VALUE`-class verification warnings and degrades trust scoring.
>
> Role-specific operational principles that describe the agent's job function rather than its ethical commitments belong in `extensions`, not `values.declared`. For example, `fiduciary_precision` or `organizational_clarity` describe what an agent IS in its role — they should be set in `extensions.clpi.role`. Values like `transparency`, `honesty`, `accuracy`, and `accountability` describe how an agent reasons — those belong in `declared`.

### 4.5 Autonomy block

The `autonomy` block defines what the agent may do independently. (Renamed from the legacy `autonomy_envelope` in the unified shape; semantics unchanged.)

```json theme={null}
{
  "autonomy": {
    "bounded_actions": ["search", "compare", "recommend"],
    "escalation_triggers": [
      {
        "condition": "purchase_value > 100",
        "action": "escalate",
        "reason": "Exceeds autonomous spending limit"
      },
      {
        "condition": "personal_data_access",
        "action": "escalate",
        "reason": "Requires explicit consent"
      }
    ],
    "max_autonomous_value": {
      "amount": 100,
      "currency": "USD"
    },
    "forbidden_actions": ["delete_without_confirmation", "share_credentials"]
  }
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `bounded_actions` | array\[string] | REQUIRED | Actions permitted without escalation |
| `escalation_triggers` | array\[object] | REQUIRED | Conditions requiring escalation |
| `max_autonomous_value` | object | OPTIONAL | Maximum transaction value without escalation |
| `forbidden_actions` | array\[string] | OPTIONAL | Actions never permitted |

Each escalation trigger MUST specify:

| Field | Type | Required | Description |
| - | - | - | - |
| `condition` | string | REQUIRED | Condition expression (see Section 4.6) |
| `action` | enum | REQUIRED | `escalate`, `deny`, or `log` |
| `reason` | string | REQUIRED | Human-readable explanation |

### 4.6 Condition expression language

Escalation conditions use a minimal expression language:

```
condition := comparison | logical_expr | function_call
comparison := field_ref operator value
logical_expr := condition ("and" | "or") condition
function_call := function_name "(" arguments ")"

field_ref := identifier ("." identifier)*
operator := ">" | "<" | ">=" | "<=" | "==" | "!=" | "contains" | "matches"
value := string | number | boolean | null
```

Examples:

* `purchase_value > 100`
* `action_type == "delete"`
* `shares_personal_data` (boolean field check)

**Minimal Required Set** (MUST support):

* Comparison operators: `>`, `<`, `>=`, `<=`, `==`, `!=`
* String literal comparison: `field == "value"`
* Numeric comparison: `field > 100`
* Boolean field check: `field_name` (evaluates to true if field is truthy)

**Optional Extensions** (MAY support):

* Logical expressions: `condition and condition`, `condition or condition`
* `contains(field, value)` -- substring or element containment
* `matches(field, pattern)` -- regex matching

Implementations MAY support additional operators beyond the minimal set.

### 4.7 Audit block

The `audit` block declares how the agent logs decisions. (Renamed from the legacy `audit_commitment` in the unified shape; semantics unchanged. The legacy `storage` sub-object was removed in the 2.0.0 SDKs -- there is no `storage.type` / `storage.location`.)

```json theme={null}
{
  "audit": {
    "trace_format": "ap-trace-v1",
    "retention_days": 90,
    "queryable": true,
    "query_endpoint": "https://agent.example.com/api/traces",
    "tamper_evidence": "append_only | signed | merkle"
  }
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `trace_format` | string | REQUIRED (default `"ap-trace-v1"`) | Trace format identifier |
| `retention_days` | integer | REQUIRED | Minimum retention period |
| `queryable` | boolean | REQUIRED | Whether traces can be queried externally |
| `query_endpoint` | string | OPTIONAL | Endpoint for trace queries (RECOMMENDED if `queryable` is true) |
| `tamper_evidence` | enum | OPTIONAL | Tamper-evidence mechanism: `append_only` \| `signed` \| `merkle` |

### 4.8 Extensions block

The `extensions` block allows protocol-specific additions.

```json theme={null}
{
  "extensions": {
    "a2a": {
      "agent_card_url": "https://agent.example.com/.well-known/agent.json"
    },
    "mcp": {
      "tool_alignment_requirements": ["consent_logging", "rate_limiting"]
    }
  }
}
```

Extensions MUST be namespaced by protocol identifier. Implementations MUST ignore unrecognized extensions.

### 4.9 Complete example

```json theme={null}
{
  "card_version": "unified/2026-04-26",
  "card_id": "ac-f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "agent_id": "did:web:shopping.agent.example.com",
  "issued_at": "2026-01-31T12:00:00Z",
  "expires_at": "2026-07-31T12:00:00Z",
  "autonomy_mode": "enforce",
  "integrity_mode": "observe",

  "principal": {
    "type": "human",
    "identifier": "did:web:user.example.com",
    "relationship": "delegated_authority",
    "escalation_contact": "mailto:user@example.com"
  },

  "values": {
    "declared": ["principal_benefit", "transparency", "minimal_data"],
    "conflicts_with": ["deceptive_marketing", "hidden_fees"],
    "hierarchy": "lexicographic"
  },

  "autonomy": {
    "bounded_actions": ["search", "compare", "recommend", "add_to_cart"],
    "escalation_triggers": [
      {
        "condition": "action_type == \"purchase\"",
        "action": "escalate",
        "reason": "Purchases require explicit approval"
      },
      {
        "condition": "purchase_value > 100",
        "action": "escalate",
        "reason": "Exceeds autonomous spending limit"
      },
      {
        "condition": "shares_personal_data",
        "action": "escalate",
        "reason": "Data sharing requires consent"
      }
    ],
    "max_autonomous_value": {
      "amount": 100,
      "currency": "USD"
    },
    "forbidden_actions": ["store_payment_credentials", "subscribe_to_services"]
  },

  "audit": {
    "trace_format": "ap-trace-v1",
    "retention_days": 90,
    "queryable": true,
    "query_endpoint": "https://shopping.agent.example.com/api/v1/traces",
    "tamper_evidence": "append_only"
  },

  "extensions": {
    "a2a": {
      "agent_card_url": "https://shopping.agent.example.com/.well-known/agent.json"
    }
  }
}
```

### 4.10 Migrating from the legacy 0.5.0 card shape

SDK versions before 2.0.0 used a different top-level shape. Both fields carry identical semantics; only the names (and the addition of the two mode switches) changed:

| Legacy (AAP 0.5.0 and earlier) | Unified (AAP 2.0.0 and later) |
| - | - |
| `aap_version` | `card_version` (now date-anchored: `"unified/2026-04-26"`) |
| `autonomy_envelope` | `autonomy` |
| `audit_commitment` | `audit` (its `storage` sub-object was dropped) |
| *(none)* | `autonomy_mode`, `integrity_mode` -- now REQUIRED |

Both the Python and TypeScript SDKs still read the legacy field names for backward compatibility when validating an old card, but `AlignmentCard.model_dump()` / `aap init` always emit the unified shape. New cards SHOULD use the unified shape directly.

***

## 5. AP-Trace

### 5.1 Overview

An AP-Trace (Alignment Protocol Trace) is an audit log entry recording an agent's decision process. AP-Traces enable verification that observed behavior is consistent with declared alignment.

### 5.2 Design principles

1. **Sampling, not completeness**: AP-Traces capture significant decisions, not every computation
2. **Structured reasoning**: Decision rationale is machine-parseable
3. **Verifiable references**: Traces reference the Alignment Card in effect
4. **Append-only**: Traces MUST NOT be modified after creation

### 5.3 Structure

An AP-Trace entry MUST contain:

| Field | Type | Required | Description |
| - | - | - | - |
| `trace_id` | string | REQUIRED | Unique identifier (UUID) |
| `agent_id` | string | REQUIRED | Agent that generated this trace |
| `card_id` | string | REQUIRED | Alignment Card in effect |
| `timestamp` | string | REQUIRED | ISO 8601 timestamp |
| `action` | object | REQUIRED | Action taken or considered |
| `decision` | object | REQUIRED | Decision process record |
| `escalation` | object | CONDITIONAL | Present if escalation evaluated |
| `context` | object | OPTIONAL | Additional context |

### 5.4 Action block

The `action` block describes what action was taken or considered.

```json theme={null}
{
  "action": {
    "type": "recommend | execute | escalate | deny",
    "name": "human_readable_action_name",
    "category": "bounded | escalation_trigger | forbidden",
    "target": {
      "type": "resource_type",
      "identifier": "resource_id"
    },
    "parameters": {}
  }
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `type` | enum | REQUIRED | Action type |
| `name` | string | REQUIRED | Human-readable action name |
| `category` | enum | REQUIRED | How this action relates to autonomy envelope |
| `target` | object | OPTIONAL | Resource affected |
| `parameters` | object | OPTIONAL | Action parameters |

### 5.5 Decision block

The `decision` block records the decision process.

```json theme={null}
{
  "decision": {
    "alternatives_considered": [
      {
        "option_id": "A",
        "description": "Option A description",
        "score": 0.85,
        "scoring_factors": {
          "principal_benefit": 0.9,
          "cost": 0.8,
          "risk": 0.1
        },
        "flags": []
      },
      {
        "option_id": "B",
        "description": "Option B description",
        "score": 0.72,
        "scoring_factors": {
          "principal_benefit": 0.7,
          "cost": 0.9,
          "risk": 0.2
        },
        "flags": ["sponsored_content"]
      }
    ],
    "selected": "A",
    "selection_reasoning": "Highest principal benefit score. Option B flagged as sponsored content and deprioritized per declared values.",
    "values_applied": ["principal_benefit", "transparency"],
    "confidence": 0.85
  }
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `alternatives_considered` | array | REQUIRED | Options evaluated (minimum 1) |
| `selected` | string | REQUIRED | Option ID selected |
| `selection_reasoning` | string | REQUIRED | Human-readable explanation |
| `values_applied` | array\[string] | REQUIRED | Values that influenced decision |
| `confidence` | number | OPTIONAL | Decision confidence (0.0-1.0) |
| `value_scores` | object | OPTIONAL | Per-declared-value score (SDK >= 1.3.0), keyed by value id: `{score: "on_track" \| "off_track" \| "not_applicable", rationale: string}`. When present, `values_applied` is derived from entries scored `on_track`. |

Each alternative MUST specify:

| Field | Type | Required | Description |
| - | - | - | - |
| `option_id` | string | REQUIRED | Unique identifier for this option |
| `description` | string | REQUIRED | Human-readable description |
| `score` | number | OPTIONAL | Computed score (0.0-1.0) |
| `scoring_factors` | object | OPTIONAL | Breakdown of score components |
| `flags` | array\[string] | OPTIONAL | Concerns or flags about this option |

### 5.6 Escalation block

The `escalation` block records escalation evaluation.

```json theme={null}
{
  "escalation": {
    "evaluated": true,
    "triggers_checked": [
      {
        "trigger": "purchase_value > 100",
        "matched": false,
        "value_observed": 45
      }
    ],
    "required": false,
    "reason": "No escalation triggers matched"
  }
}
```

When escalation IS required:

```json theme={null}
{
  "escalation": {
    "evaluated": true,
    "triggers_checked": [
      {
        "trigger": "action_type == \"purchase\"",
        "matched": true
      }
    ],
    "required": true,
    "reason": "Purchase action requires principal approval",
    "escalation_id": "esc-abc123",
    "escalation_status": "pending | approved | denied | timeout",
    "principal_response": {
      "decision": "approved",
      "timestamp": "2026-01-31T12:05:00Z",
      "conditions": ["max_price <= 50"]
    }
  }
}
```

### 5.7 Context block

The `context` block provides additional information.

```json theme={null}
{
  "context": {
    "session_id": "sess-abc123",
    "conversation_turn": 5,
    "prior_trace_ids": ["tr-prev1", "tr-prev2"],
    "environment": {
      "client": "web",
      "locale": "en-US"
    },
    "metadata": {}
  }
}
```

### 5.8 Complete example

```json theme={null}
{
  "trace_id": "tr-f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "agent_id": "did:web:shopping.agent.example.com",
  "card_id": "ac-f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "timestamp": "2026-01-31T12:30:00Z",

  "action": {
    "type": "recommend",
    "name": "product_recommendation",
    "category": "bounded",
    "target": {
      "type": "product_search",
      "identifier": "search-12345"
    }
  },

  "decision": {
    "alternatives_considered": [
      {
        "option_id": "prod-A",
        "description": "Product A - Best match for stated preferences",
        "score": 0.85,
        "scoring_factors": {
          "preference_match": 0.9,
          "price_value": 0.8,
          "reviews": 0.85
        },
        "flags": []
      },
      {
        "option_id": "prod-B",
        "description": "Product B - Lower price point",
        "score": 0.72,
        "scoring_factors": {
          "preference_match": 0.7,
          "price_value": 0.95,
          "reviews": 0.6
        },
        "flags": []
      },
      {
        "option_id": "prod-C",
        "description": "Product C - Sponsored listing",
        "score": 0.68,
        "scoring_factors": {
          "preference_match": 0.75,
          "price_value": 0.7,
          "reviews": 0.7
        },
        "flags": ["sponsored_content"]
      }
    ],
    "selected": "prod-A",
    "selection_reasoning": "Highest overall score based on preference match and reviews. Product C was flagged as sponsored and deprioritized per principal_benefit value.",
    "values_applied": ["principal_benefit", "transparency"],
    "confidence": 0.85
  },

  "escalation": {
    "evaluated": true,
    "triggers_checked": [
      {
        "trigger": "action_type == \"purchase\"",
        "matched": false
      }
    ],
    "required": false,
    "reason": "Recommendation only, no purchase action"
  },

  "context": {
    "session_id": "sess-789xyz",
    "conversation_turn": 3,
    "prior_trace_ids": ["tr-abc123", "tr-def456"]
  }
}
```

***

## 6. Value Coherence handshake

### 6.1 Overview

The Value Coherence Handshake is a pre-coordination protocol exchange that verifies whether two agents' declared values are compatible for a proposed task.

### 6.2 Protocol flow

```
Agent A (Initiator)                     Agent B (Responder)
       |                                       |
       |--- alignment_card_request ----------->|
       |    { request_id, task_context }       |
       |                                       |
       |<-- alignment_card_response -----------|
       |    { alignment_card, signature }      |
       |                                       |
       |--- value_coherence_check ------------>|
       |    { my_card, proposed_values,        |
       |      task_requirements }              |
       |                                       |
       |<-- coherence_result ------------------|
       |    { compatible, conflicts,           |
       |      proposed_resolution }            |
       |                                       |
       |    [If compatible: proceed]           |
       |    [If conflict: negotiate/escalate]  |
       |                                       |
```

### 6.3 Messages

#### 6.3.1 alignment\_card\_request

Sent by initiator to request responder's Alignment Card.

```json theme={null}
{
  "message_type": "alignment_card_request",
  "request_id": "req-abc123",
  "requester": {
    "agent_id": "did:web:agent-a.example.com",
    "card_id": "ac-initiator-card-id"
  },
  "task_context": {
    "task_type": "product_comparison",
    "values_required": ["principal_benefit", "transparency"],
    "data_categories": ["product_info", "pricing"]
  },
  "timestamp": "2026-01-31T12:00:00Z"
}
```

#### 6.3.2 alignment\_card\_response

Sent by responder with their Alignment Card.

```json theme={null}
{
  "message_type": "alignment_card_response",
  "request_id": "req-abc123",
  "alignment_card": { },
  "signature": {
    "algorithm": "Ed25519",
    "value": "base64-encoded-signature",
    "key_id": "key-identifier"
  },
  "timestamp": "2026-01-31T12:00:01Z"
}
```

The `signature` field is OPTIONAL but RECOMMENDED for high-stakes interactions.

#### 6.3.3 value\_coherence\_check

Sent by initiator to perform coherence check.

```json theme={null}
{
  "message_type": "value_coherence_check",
  "request_id": "req-abc123",
  "initiator_card_id": "ac-initiator-card-id",
  "responder_card_id": "ac-responder-card-id",
  "proposed_collaboration": {
    "task_type": "product_comparison",
    "values_intersection": ["principal_benefit", "transparency"],
    "data_sharing": {
      "from_initiator": ["search_criteria", "preferences"],
      "from_responder": ["product_catalog", "pricing"]
    },
    "autonomy_scope": {
      "initiator_actions": ["search", "compare"],
      "responder_actions": ["provide_data", "answer_queries"]
    }
  },
  "timestamp": "2026-01-31T12:00:02Z"
}
```

#### 6.3.4 coherence\_result

Sent by responder with coherence assessment.

```json theme={null}
{
  "message_type": "coherence_result",
  "request_id": "req-abc123",
  "coherence": {
    "compatible": true,
    "score": 0.85,
    "value_alignment": {
      "matched": ["principal_benefit", "transparency"],
      "unmatched": [],
      "conflicts": []
    }
  },
  "proceed": true,
  "conditions": [],
  "timestamp": "2026-01-31T12:00:03Z"
}
```

When conflicts exist:

```json theme={null}
{
  "message_type": "coherence_result",
  "request_id": "req-abc123",
  "coherence": {
    "compatible": false,
    "score": 0.45,
    "value_alignment": {
      "matched": ["transparency"],
      "unmatched": ["data_minimization"],
      "conflicts": [
        {
          "initiator_value": "minimal_data",
          "responder_value": "comprehensive_analytics",
          "conflict_type": "incompatible",
          "description": "Initiator requires minimal data collection; responder requires comprehensive tracking"
        }
      ]
    }
  },
  "proceed": false,
  "proposed_resolution": {
    "type": "escalate_to_principals",
    "reason": "Value conflict requires human decision",
    "alternative": {
      "type": "modified_scope",
      "description": "Proceed with limited data sharing (no analytics)",
      "modified_values": {
        "responder_concession": "disable_analytics_for_this_task"
      }
    }
  },
  "timestamp": "2026-01-31T12:00:03Z"
}
```

### 6.4 Coherence scoring

Value coherence score is computed as:

```
coherence_score = (matched_values / total_required_values) * (1 - conflict_penalty)

where:
  matched_values = count of values present in both cards (or in both cards
                    AND the task's required values, if task_values is given)
  total_required_values = count of values required for task (defaults to the
                           union of both cards' declared values if task_values
                           is not given)
  conflict_penalty = min(1.0, CONFLICT_PENALTY_MULTIPLIER * (conflicts_count / total_required_values))
  CONFLICT_PENALTY_MULTIPLIER = 0.50
```

The final score is clamped to `[0.0, 1.0]`. `compatible` is `true` only when there are **zero** value conflicts AND `score >= MIN_COHERENCE_FOR_PROCEED` (`0.70`); `proceed` mirrors `compatible`. Implementations MAY use more sophisticated scoring algorithms but MUST produce a score in the range \[0.0, 1.0].

### 6.5 Conflict resolution

When conflicts are detected, implementations SHOULD follow this resolution order:

1. **Automatic resolution**: If one value strictly subsumes another
2. **Negotiated resolution**: If agents can agree on modified scope
3. **Principal escalation**: If agents cannot resolve autonomously

***

## 7. Verification

### 7.1 Overview

Verification is the process of checking whether observed behavior (AP-Trace entries) is consistent with declared alignment (Alignment Card).

### 7.2 Verification scope

Verification operates at three levels:

1. **Trace verification**: Single AP-Trace against Alignment Card
2. **Session verification**: Collection of traces from one session
3. **Longitudinal verification**: Traces across multiple sessions (drift detection)

### 7.3 Verification algorithm

<Note>
  `verify_trace` provides **structural verification only**. It checks that a trace conforms to what an Alignment Card declares. It does NOT provide cryptographic integrity verification -- traces are not signed or hash-chained by the reference SDKs. A malicious agent can produce a structurally valid trace for arbitrary behavior. For an integrity guarantee over the agent's actual reasoning, pair AAP with [AIP](/protocols/aip/specification).
</Note>

The reference implementation performs these checks, in order, tracked in `verification_metadata.checks_performed`:

1. **`card_reference`**: Does `trace.card_id` match `card.card_id`?
2. **`card_expiration`**: Is the card still valid (not past `expires_at`)?
3. **`autonomy`**: Is `action.name` in `autonomy.bounded_actions` when `action.category == "bounded"`?
4. **`forbidden`**: Is `action.name` NOT in `autonomy.forbidden_actions`?
5. **`escalation`**: For every matched escalation trigger, was `escalation.required` set?
6. **`values`**: Is every value in `decision.values_applied` present in `values.declared`?
7. **`behavioral_similarity`**: Is the trace semantically similar to the card's declared alignment, per SSM analysis?

Steps 3-6 additionally emit `near_boundary` warnings when a decision's `confidence` or an alternative's `score` falls below `NEAR_BOUNDARY_THRESHOLD` (`0.35`), even when no violation is found.

```
function verify_trace(trace: APTrace, card: AlignmentCard) -> VerificationResult:

  violations = []
  warnings = []

  // Check autonomy compliance
  if trace.action.category == "bounded":
    if trace.action.name not in card.autonomy.bounded_actions:
      violations.append(ViolationType.UNBOUNDED_ACTION)

  // Check forbidden actions
  if trace.action.name in card.autonomy.forbidden_actions:
    violations.append(ViolationType.FORBIDDEN_ACTION)

  // Check escalation compliance
  for trigger in card.autonomy.escalation_triggers:
    if evaluate_condition(trigger.condition, trace.context):
      if not trace.escalation.required:
        violations.append(ViolationType.MISSED_ESCALATION)
      elif trace.escalation.escalation_status == "timeout":
        // Timeout is not a violation if escalation was attempted
        pass

  // Check value consistency
  for value in trace.decision.values_applied:
    if value not in card.values.declared:
      violations.append(ViolationType.UNDECLARED_VALUE)

  // Compute behavioral similarity using SSM analysis
  similarity_score = compute_alignment_similarity(trace, card)

  // Warn if structurally valid but behaviorally divergent
  if len(violations) == 0 and similarity_score < BEHAVIORAL_SIMILARITY_THRESHOLD:
    warnings.append(Warning(
      type = "low_behavioral_similarity",
      description = "Trace passes structural checks but behavioral similarity is below threshold"
    ))

  return VerificationResult(
    verified = len(violations) == 0,
    violations = violations,
    warnings = warnings,
    similarity_score = similarity_score,
    trace_id = trace.trace_id,
    card_id = card.card_id
  )
```

### 7.4 Verification result

A verification result MUST contain:

| Field | Type | Required | Description |
| - | - | - | - |
| `verified` | boolean | REQUIRED | True if no violations were found |
| `recommended_action` | enum | REQUIRED | `"proceed"` \| `"review"` \| `"deny"` -- derived from violations/warnings (see below) |
| `trace_id` | string | REQUIRED | ID of the verified trace |
| `card_id` | string | REQUIRED | ID of the Alignment Card used |
| `timestamp` | string | REQUIRED | ISO 8601 timestamp of verification (UTC) |
| `violations` | array | REQUIRED | List of violations found |
| `warnings` | array | REQUIRED | List of non-critical warnings |
| `similarity_score` | number | REQUIRED | Behavioral similarity (0.0-1.0) |
| `verification_metadata` | object | REQUIRED | Metadata about verification process |

`recommended_action` is derived mechanically: `"deny"` if any violation was found, else `"review"` if any warning was found, else `"proceed"`. Prefer branching on `recommended_action` over `verified` alone -- it distinguishes a clean pass from a warning-only pass.

The `similarity_score` measures semantic similarity between the trace behavior and declared alignment using SSM (Self-Similarity Matrix) analysis. A score of 1.0 indicates perfect alignment; lower scores indicate divergence.

**Threshold**: `BEHAVIORAL_SIMILARITY_THRESHOLD = 0.50`. If a trace passes all structural checks but has `similarity_score < 0.50`, a `low_behavioral_similarity` warning is generated.

```json theme={null}
{
  "verified": true,
  "recommended_action": "review",
  "trace_id": "tr-abc123",
  "card_id": "ac-def456",
  "timestamp": "2026-01-31T12:35:00Z",
  "similarity_score": 0.78,
  "violations": [],
  "warnings": [
    {
      "type": "near_boundary",
      "description": "Action score 0.31 near boundary threshold 0.35",
      "trace_field": "decision.alternatives_considered[2].score"
    }
  ],
  "verification_metadata": {
    "algorithm_version": "1.2.0",
    "checks_performed": ["card_reference", "card_expiration", "autonomy", "forbidden", "escalation", "values", "behavioral_similarity"],
    "duration_ms": 4.2,
    "similarity_details": {
      "similarity_score": 0.78,
      "method": "cosine",
      "algorithm_version": "1.2.0"
    }
  }
}
```

<Note>
  **`similarity_details` shape.** The TypeScript SDK emits the `{similarity_score, method, algorithm_version}` shape shown above. The published Python SDK (2.0.0 and earlier) still emits a different, Python-only shape (`{similarities, mean_similarity, trend}`). The SDK changelog's 2.0.1 entry aligns Python to the shape above, but no 2.0.1 package has been published to npm or PyPI yet. That change also alters the feature extractor, so similarity scores computed before it are not numerically comparable to scores computed after.
</Note>

### 7.5 Violation types

| Type | Severity | Description |
| - | - | - |
| `UNBOUNDED_ACTION` | HIGH | Action not in bounded\_actions list |
| `FORBIDDEN_ACTION` | CRITICAL | Action in forbidden\_actions list |
| `MISSED_ESCALATION` | HIGH | Escalation trigger matched but not escalated |
| `UNDECLARED_VALUE` | MEDIUM | Applied value not in declared values |
| `CARD_EXPIRED` | HIGH | Alignment Card has expired |
| `CARD_MISMATCH` | CRITICAL | Trace references different card than provided |

***

## 8. Drift detection

### 8.1 Overview

Drift detection identifies when an agent's behavior deviates from its declared alignment posture over time. Unlike single-trace verification, drift detection requires longitudinal analysis.

### 8.2 Detection methodology

Drift detection uses trace-to-baseline-centroid similarity to measure behavioral consistency (v1.2.0):

1. **Feature extraction**: Extract structural features from each trace (action types, values applied, escalation patterns, confidence)
2. **Chronological ordering**: Sort all traces by timestamp before processing
3. **Baseline computation**: Compute a baseline centroid from the first N traces, where N = `max(sustained_threshold, min(10, len(traces) // 4))`
4. **Similarity computation**: Compute cosine similarity between each subsequent trace's feature vector and the baseline centroid
5. **Divergence tracking**: Track similarity over time, alert on sustained divergence

The Alignment Card is still referenced for `card_id` in drift alerts and for inferring drift direction (Section 8.5), but is no longer used as the comparison target for similarity scoring.

**Important (v1.1.0, updated v1.2.0):** Drift detection uses only structural features -- not content features from reasoning text. Alignment Cards declare structural constraints (values, bounded actions, principal relationship) but contain no reasoning text. Including content tokens from trace reasoning dilutes cosine similarity without adding alignment signal. See [calibration](/protocols/aap/calibration) Section 3.5 for rationale.

Content features (TF-IDF from reasoning text) remain available for text-to-text comparison (e.g., SSM pairwise similarity between traces).

### 8.3 Calibration constants

The following thresholds are calibrated from empirical analysis:

| Constant | Value | Description |
| - | - | - |
| `DEFAULT_SIMILARITY_THRESHOLD` | 0.30 | Alert when drift similarity drops below |
| Sustained-traces threshold | 3 | Alert after N consecutive low-similarity traces |
| `BEHAVIORAL_SIMILARITY_THRESHOLD` | 0.50 | Warn on single-trace verification when below |
| `MIN_COHERENCE_FOR_PROCEED` | 0.70 | Minimum coherence score for automatic proceed |

The sustained-traces constant is named differently across the two SDKs: `DEFAULT_SUSTAINED_TURNS_THRESHOLD` in the Python SDK, `DEFAULT_SUSTAINED_CHECKS_THRESHOLD` in the TypeScript SDK. Both default to `3`.

**Feature Extraction for Drift Detection** (structural only):

| Feature | Source | Weight |
| - | - | - |
| `value:{v}` | Declared values (card) / Applied values (trace) | 1.0 |
| `action_name:{name}` | Bounded actions (card) / Action name (trace) | 1.0 |
| `action:{type}` | Action type (trace only) | 1.0 |
| `category:{cat}` | Principal type/relationship (card) / Action category (trace) | 1.0 |
| `escalation:*` | Escalation triggers (card) / Escalation state (trace) | 1.0 |
| `confidence` | Decision confidence (trace only) | 0.0-1.0 |

**60/30/10 TF-IDF Weighting** (for text-to-text similarity, NOT drift detection):

| Component | Weight | Description |
| - | - | - |
| Word TF-IDF | 60% | Semantic content from unigrams and bigrams |
| Character TF-IDF | 30% | Stylistic patterns from 3-5 character n-grams |
| Metadata features | 10% | Structural alignment (action types, values) |

These values were derived from analysis of approximately 50 multi-turn agent conversations totaling \~2,500 messages. See [calibration](/protocols/aap/calibration) for methodology and threshold derivation. Implementations MAY adjust thresholds based on their own calibration data but SHOULD document the methodology used.

### 8.4 Drift alert

When sustained divergence is detected:

```json theme={null}
{
  "alert_type": "drift_detected",
  "agent_id": "did:web:agent.example.com",
  "card_id": "ac-abc123",
  "detection_timestamp": "2026-01-31T14:00:00Z",
  "analysis": {
    "similarity_score": 0.25,
    "sustained_traces": 4,
    "threshold": 0.30,
    "drift_direction": "toward_autonomy_expansion",
    "specific_indicators": [
      {
        "indicator": "escalation_rate_decrease",
        "baseline": 0.15,
        "current": 0.05,
        "description": "Escalation rate decreased from 15% to 5% of decisions"
      }
    ]
  },
  "recommendation": "Review recent decisions for alignment drift",
  "trace_ids": ["tr-1", "tr-2", "tr-3", "tr-4"]
}
```

### 8.5 Drift categories

| Category | Description | Indicators |
| - | - | - |
| `autonomy_expansion` | Agent acting outside declared bounds | Decreased escalation rate, new action types |
| `value_drift` | Applied values diverging from declared | Different values appearing in traces |
| `principal_misalignment` | Decisions not serving principal | Declining principal-benefit scores |
| `communication_drift` | Explanations becoming inconsistent | Selection reasoning diverging from values |

***

## 9. Security considerations

AAP's threat model, trust boundaries, and cryptographic recommendations are specified in full on the dedicated [Security](/protocols/aap/security) page. In summary:

* **In scope**: agents misrepresenting their alignment, agents failing to log decisions accurately, agents gaming coherence checks, man-in-the-middle attacks on handshakes.
* **Out of scope**: compromised agent runtime, adversarial principals, collusion between agents and verifiers.
* The reference SDKs' `verify_trace` does **not** sign or hash-chain cards and traces -- that is a recommended practice for implementers (Ed25519 signatures, append-only storage, TLS for handshake transport), not something the SDK provides by default. See [Security](/protocols/aap/security) for the concrete recommendations.

### 9.1 Known limitations

AAP cannot protect against:

1. **Sophisticated deception**: An agent can produce compliant traces while acting misaligned
2. **Trace omission**: An agent can fail to log certain decisions
3. **Value gaming**: An agent can declare values it does not hold
4. **Runtime compromise**: If the agent runtime is compromised, all bets are off

These limitations are inherent to any transparency-based protocol. See Section 10 for full limitations disclosure.

***

## 10. Limitations

### 10.1 What AAP does not guarantee

This section is non-negotiable. Implementations MUST make these limitations clear to users. See [Limitations](/protocols/aap/limitations) for the full, worked-example treatment.

**1. AAP does NOT ensure alignment--it provides visibility.**

AAP makes agent decisions observable. It does not make them correct, safe, or aligned. An agent can produce perfect AP-Traces while acting against its principal's interests.

**2. Verified does NOT equal safe.**

A verified trace means the trace is consistent with the declared alignment. It does not mean the declared alignment is good, the agent followed it in practice, or the outcome was beneficial.

**3. AP-Trace is sampled, not complete.**

Traces capture decision points, not every computation. Significant reasoning may occur between traced decisions. The absence of a trace does not mean nothing happened.

**4. Value coherence is relative to declared values.**

The handshake checks whether declared values are compatible. It does not verify that agents hold these values, will act on them, or that the values themselves are good.

**5. Tested on transformer-based agents; unknown unknowns exist for other substrates.**

AAP was developed and tested with transformer-based language model agents. Agents built on different architectures (symbolic AI, neuromorphic computing, hybrid systems) may exhibit behaviors that AAP does not capture.

### 10.2 Appropriate use

AAP is appropriate for:

* Increasing observability of agent decisions
* Enabling audit and compliance workflows
* Facilitating agent coordination with transparency
* Detecting obvious misalignment or drift

AAP is NOT appropriate for:

* Certifying agents as "safe" or "trustworthy"
* Replacing human oversight for consequential decisions
* Providing security guarantees against adversarial agents
* Solving the general alignment problem

### 10.3 Recommendations

1. **Defense in depth**: Use AAP as one layer of a multi-layer oversight system
2. **Human-in-the-loop**: Maintain human oversight for consequential decisions
3. **Verification diversity**: Use multiple verification approaches, not just AAP
4. **Continuous monitoring**: Monitor for drift, don't rely on point-in-time verification

***

## 11. Well-known URI convention

An agent MAY serve its current Alignment Card at `/.well-known/alignment-card.json`. This is a convention, not a registered media type or IANA well-known URI -- there is no dedicated `application/aap-*+json` content type; implementations serve the card as plain `application/json`. Mnemom follows this convention for its own platform-scope card at `https://www.mnemom.ai/.well-known/alignment-card.json`.

***

## 12. References

### 12.1 Normative references

* \[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
* \[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, May 2017.
* \[RFC8259] Bray, T., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 8259, December 2017.
* \[RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, July 2002.

### 12.2 Informative references

* A2A (Agent-to-Agent Protocol): [https://google.github.io/A2A/](https://google.github.io/A2A/)
* MCP (Model Context Protocol): [https://modelcontextprotocol.io/](https://modelcontextprotocol.io/)
* DID (Decentralized Identifiers): [https://www.w3.org/TR/did-core/](https://www.w3.org/TR/did-core/)

### 12.3 Standards and regulatory references

* \[ISO/IEC 42001:2023] ISO/IEC, "Information technology -- Artificial Intelligence Management System", 2023. [https://www.iso.org/standard/42001](https://www.iso.org/standard/42001)
* \[ISO/IEC 42005:2025] ISO/IEC, "Information technology -- Artificial intelligence -- AI system impact assessment", 2025. [https://www.iso.org/standard/42005](https://www.iso.org/standard/42005)
* \[IEEE 7001-2021] IEEE, "Standard for Transparency of Autonomous Systems", 2021. [https://standards.ieee.org/ieee/7001/6929/](https://standards.ieee.org/ieee/7001/6929/)
* \[IEEE 3152-2024] IEEE, "Standard for Transparent Human and Machine Agency Identification", 2024. [https://standards.ieee.org/ieee/3152/11718/](https://standards.ieee.org/ieee/3152/11718/)
* \[IMDA MGF] IMDA Singapore, "Model AI Governance Framework for Agentic AI", January 2026. [https://www.imda.gov.sg/-/media/imda/files/about/emerging-tech-and-research/artificial-intelligence/mgf-for-agentic-ai.pdf](https://www.imda.gov.sg/-/media/imda/files/about/emerging-tech-and-research/artificial-intelligence/mgf-for-agentic-ai.pdf)
* \[EU AI Act] European Union, "Regulation (EU) 2024/1689 -- Artificial Intelligence Act", Article 50 (Transparency obligations), enforcement August 2026. [https://artificialintelligenceact.eu/article/50/](https://artificialintelligenceact.eu/article/50/)

***

## Appendix a: JSON schemas

### A.1 Alignment Card schema

See [`schemas/alignment-card.schema.json`](https://github.com/mnemom/aap/blob/main/schemas/alignment-card.schema.json) for the complete, canonical unified JSON Schema.

### A.2 AP-Trace schema

See [`schemas/ap-trace.schema.json`](https://github.com/mnemom/aap/blob/main/schemas/ap-trace.schema.json) for the complete JSON Schema.

### A.3 Value Coherence messages schema

See [`schemas/value-coherence.schema.json`](https://github.com/mnemom/aap/blob/main/schemas/value-coherence.schema.json) for the complete JSON Schema.

***

## Appendix b: Verification algorithm

### B.1 Reference implementation

```python theme={null}
from dataclasses import dataclass
from enum import Enum
from typing import List, Optional

class ViolationType(Enum):
    UNBOUNDED_ACTION = "unbounded_action"
    FORBIDDEN_ACTION = "forbidden_action"
    MISSED_ESCALATION = "missed_escalation"
    UNDECLARED_VALUE = "undeclared_value"
    CARD_EXPIRED = "card_expired"
    CARD_MISMATCH = "card_mismatch"

@dataclass
class Violation:
    type: ViolationType
    severity: str
    description: str
    trace_field: Optional[str] = None

BEHAVIORAL_SIMILARITY_THRESHOLD = 0.50

@dataclass
class VerificationResult:
    verified: bool
    recommended_action: str  # "proceed" | "review" | "deny"
    trace_id: str
    card_id: str
    violations: List[Violation]
    warnings: List[dict]
    similarity_score: float

def verify_trace(trace: dict, card: dict) -> VerificationResult:
    """
    Verify a single AP-Trace against an Alignment Card.

    Performs structural validation AND behavioral similarity analysis:
    1. Structural checks (autonomy, escalation, values, forbidden)
    2. SSM-based similarity scoring (trace vs card behavioral fingerprint)

    Args:
        trace: AP-Trace dictionary
        card: Alignment Card dictionary

    Returns:
        VerificationResult with violations, warnings, and similarity_score
    """
    violations = []
    warnings = []

    # Check card reference
    if trace.get("card_id") != card.get("card_id"):
        violations.append(Violation(
            type=ViolationType.CARD_MISMATCH,
            severity="CRITICAL",
            description="Trace references different Alignment Card"
        ))

    # Check card expiration
    # ... (datetime comparison logic)

    # Check autonomy compliance
    action = trace.get("action", {})
    envelope = card.get("autonomy") or card.get("autonomy_envelope", {})  # unified key, legacy fallback

    if action.get("category") == "bounded":
        if action.get("name") not in envelope.get("bounded_actions", []):
            violations.append(Violation(
                type=ViolationType.UNBOUNDED_ACTION,
                severity="HIGH",
                description=f"Action '{action.get('name')}' not in bounded_actions",
                trace_field="action.name"
            ))

    # Check forbidden actions
    if action.get("name") in envelope.get("forbidden_actions", []):
        violations.append(Violation(
            type=ViolationType.FORBIDDEN_ACTION,
            severity="CRITICAL",
            description=f"Action '{action.get('name')}' is forbidden",
            trace_field="action.name"
        ))

    # Check escalation compliance
    escalation = trace.get("escalation", {})
    for trigger in envelope.get("escalation_triggers", []):
        if _evaluate_condition(trigger.get("condition"), trace):
            if not escalation.get("required"):
                violations.append(Violation(
                    type=ViolationType.MISSED_ESCALATION,
                    severity="HIGH",
                    description=f"Trigger '{trigger.get('condition')}' matched but not escalated",
                    trace_field="escalation.required"
                ))

    # Check value consistency
    decision = trace.get("decision", {})
    declared_values = card.get("values", {}).get("declared", [])

    for value in decision.get("values_applied", []):
        if value not in declared_values:
            violations.append(Violation(
                type=ViolationType.UNDECLARED_VALUE,
                severity="MEDIUM",
                description=f"Value '{value}' applied but not declared",
                trace_field="decision.values_applied"
            ))

    # Compute behavioral similarity using SSM analysis
    similarity_score = _compute_alignment_similarity(trace, card)

    # Warn if structurally valid but behaviorally divergent
    if len(violations) == 0 and similarity_score < BEHAVIORAL_SIMILARITY_THRESHOLD:
        warnings.append({
            "type": "low_behavioral_similarity",
            "description": f"Trace passes structural checks but similarity ({similarity_score:.2f}) is below threshold ({BEHAVIORAL_SIMILARITY_THRESHOLD})",
            "trace_field": "(computed)"
        })

    recommended_action = "deny" if violations else "review" if warnings else "proceed"

    return VerificationResult(
        verified=len(violations) == 0,
        recommended_action=recommended_action,
        trace_id=trace.get("trace_id", ""),
        card_id=card.get("card_id", ""),
        violations=violations,
        warnings=warnings,
        similarity_score=similarity_score
    )

def _evaluate_condition(condition: str, trace: dict) -> bool:
    """
    Evaluate a condition expression against trace context.

    This is a simplified implementation. Production implementations
    should use a proper expression parser.
    """
    # Implementation details omitted for brevity
    # See full reference implementation in SDK
    pass
```

### B.2 Drift detection algorithm

```python theme={null}
from dataclasses import dataclass
from typing import List, Tuple

DEFAULT_SIMILARITY_THRESHOLD = 0.30
DEFAULT_SUSTAINED_TURNS_THRESHOLD = 3

@dataclass
class DriftAlert:
    agent_id: str
    card_id: str
    similarity_score: float
    sustained_traces: int
    drift_direction: str
    trace_ids: List[str]

def detect_drift(
    traces: List[dict],
    card: dict,
    similarity_threshold: float = DEFAULT_SIMILARITY_THRESHOLD,
    sustained_threshold: int = DEFAULT_SUSTAINED_TURNS_THRESHOLD
) -> List[DriftAlert]:
    """
    Detect behavioral drift from declared alignment.

    Args:
        traces: List of AP-Trace dictionaries (chronological order)
        card: Alignment Card dictionary
        similarity_threshold: Alert when similarity drops below
        sustained_threshold: Alert after N consecutive low-similarity traces

    Returns:
        List of DriftAlert objects
    """
    if len(traces) < sustained_threshold:
        return []

    alerts = []
    low_similarity_streak = []

    for trace in traces:
        similarity = _compute_alignment_similarity(trace, card)

        if similarity < similarity_threshold:
            low_similarity_streak.append((trace, similarity))
        else:
            low_similarity_streak = []

        if len(low_similarity_streak) >= sustained_threshold:
            alerts.append(DriftAlert(
                agent_id=trace.get("agent_id", ""),
                card_id=card.get("card_id", ""),
                similarity_score=similarity,
                sustained_traces=len(low_similarity_streak),
                drift_direction=_infer_drift_direction(low_similarity_streak, card),
                trace_ids=[t[0].get("trace_id") for t in low_similarity_streak]
            ))

    return alerts

def _compute_alignment_similarity(trace: dict, card: dict) -> float:
    """
    Compute similarity between trace behavior and declared alignment.

    Uses feature extraction and cosine similarity.
    """
    trace_features = _extract_trace_features(trace)
    card_features = _extract_card_features(card)
    return _cosine_similarity(trace_features, card_features)

def _extract_trace_features(trace: dict) -> dict:
    """Extract feature vector from AP-Trace."""
    features = {}

    # Action type features
    action = trace.get("action", {})
    features[f"action:{action.get('type', 'unknown')}"] = 1.0
    features[f"category:{action.get('category', 'unknown')}"] = 1.0

    # Value features
    decision = trace.get("decision", {})
    for value in decision.get("values_applied", []):
        features[f"value:{value}"] = 1.0

    # Escalation features
    escalation = trace.get("escalation", {})
    features["escalation:required"] = 1.0 if escalation.get("required") else 0.0

    return features

def _extract_card_features(card: dict) -> dict:
    """Extract feature vector from Alignment Card."""
    features = {}

    # Bounded action features
    envelope = card.get("autonomy") or card.get("autonomy_envelope", {})  # unified key, legacy fallback
    for action in envelope.get("bounded_actions", []):
        features[f"action:{action}"] = 1.0

    # Value features
    values = card.get("values", {})
    for value in values.get("declared", []):
        features[f"value:{value}"] = 1.0

    return features

def _cosine_similarity(a: dict, b: dict) -> float:
    """Compute cosine similarity between two feature dictionaries."""
    if not a or not b:
        return 0.0

    common_keys = set(a.keys()) & set(b.keys())
    dot_product = sum(a[k] * b[k] for k in common_keys)

    mag_a = sum(v * v for v in a.values()) ** 0.5
    mag_b = sum(v * v for v in b.values()) ** 0.5

    if mag_a == 0 or mag_b == 0:
        return 0.0

    return dot_product / (mag_a * mag_b)

def _infer_drift_direction(
    streak: List[Tuple[dict, float]],
    card: dict
) -> str:
    """Infer the direction of drift from the pattern."""
    # Analysis logic to categorize drift
    # Returns: "autonomy_expansion", "value_drift", "principal_misalignment", etc.
    pass
```

***

## Appendix c: SDK version notes

This page describes the card shape and verification behavior shipped in **SDK 2.0.0** (`agent-alignment-protocol` on PyPI, `@mnemom/agent-alignment-protocol` on npm). The headline change from 1.x is the migration to the unified card shape (Section 4.10). Other notable behavior changes:

* **2.0.1 (in the SDK changelog, not yet published to npm or PyPI)** -- `similarity_details` shape unified across both SDKs (Section 7.4); Python's card/trace feature extractor gains features to match TypeScript's, so `similarity_score` becomes identical across languages for the same inputs. Scores computed before this change are not comparable to scores computed after.
* **2.0.0** -- Card shape migrated to unified (Section 4). `AutonomyEnvelope`/`AuditCommitment` SDK types renamed to `Autonomy`/`Audit`; `AuditStorage`/`StorageType` removed; `AlignmentMode` (and the `autonomy_mode`/`integrity_mode` card fields) added.
* **1.3.0** -- `Decision.value_scores` added: an optional, per-declared-value score (`on_track` / `off_track` / `not_applicable`) against a card's catalog `observer_signals`, keyed by value id. When present, `values_applied` is derived from the entries scored `on_track`.
* **1.0.0** -- Public API locked for stability; breaking changes now require a major version bump.

See the [full changelog](https://github.com/mnemom/aap/blob/main/typescript/CHANGELOG.md) for the complete history.

***

*Agent Alignment Protocol Specification*
*This document is released under CC BY 4.0*


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.