Skip to main content
Status: Draft
Version: 1.1.1
Date: 2026-04-06
Extends: QWED-SPEC v1.0, QWED-Attestation v1.0

Table of Contents

  1. Introduction
  2. Agent Verification Model
  3. Agent Registration
  4. Verification Requests
  5. Tool Verification
  6. Budget & Limits
  7. Audit Trail
  8. Trust Levels
  9. Runtime Hardening
  10. Implementation Guidelines

1. Introduction

1.1 Purpose

QWED-Agent defines a protocol for AI agents to verify their actions before execution. As agentic AI systems become more autonomous, QWED-Agent provides guardrails ensuring agents operate within defined boundaries.

1.2 Problem Statement

ProblemRisk
Agents execute unverified codeSecurity vulnerabilities
Agents make unverified calculationsFinancial errors
Agents generate unverified SQLData corruption
Agents exceed resource limitsCost overruns
No audit trail of agent actionsCompliance violations

1.3 Solution

QWED-Agent establishes:
  • Pre-execution verification of agent outputs
  • Tool call approval workflow
  • Budget enforcement
  • Complete audit trail
  • Trust level management

1.4 Terminology

TermDefinition
AgentAutonomous AI system performing tasks
PrincipalEntity that owns/controls the agent
ToolExternal capability an agent can invoke
ActionAny operation an agent wants to perform
Verification GateCheck before action execution
BudgetResource limits for the agent

2. Agent Verification Model

2.1 Verification Flow

2.2 Verification Types for Agents

Action TypeVerification EngineRisk Level
Math calculationMath EngineLow
Database querySQL EngineHigh
Code executionCode EngineCritical
External API callTool VerificationMedium
File operationsSecurity CheckHigh
Network requestsPolicy CheckMedium

2.3 Decision Matrix

VerificationRisk levelAction
VERIFIEDLowExecute immediately
VERIFIEDHighExecute with attestation
FAILEDAnyBlock and notify principal
CORRECTEDLowExecute corrected version
CORRECTEDHighRequest principal approval
UNCERTAINAnyRequest principal approval

3. Agent Registration

3.1 Registration Request

Agents MUST register with QWED before use:
{
  "agent": {
    "name": "CustomerSupportBot",
    "type": "autonomous",
    "description": "Handles customer inquiries",
    "principal_id": "org_abc123",
    "framework": "langchain",
    "model": "claude-3.5-sonnet"
  },
  "permissions": {
    "allowed_engines": ["math", "fact", "sql"],
    "allowed_tools": ["database_read", "send_email"],
    "blocked_tools": ["database_write", "file_delete"]
  },
  "budget": {
    "max_daily_cost_usd": 100.00,
    "max_requests_per_hour": 1000,
    "max_tokens_per_request": 4096
  },
  "trust_level": "supervised"
}

3.2 Registration Response

{
  "agent_id": "agent_xyz789",
  "agent_token": "qwed_agent_...",
  "status": "active",
  "created_at": "2025-12-20T00:30:00Z",
  "permissions": { ... },
  "budget": { ... }
}

3.3 Agent Types

TypeDescriptionTrust Level
supervisedHuman approval for high-risk actionsLow
autonomousSelf-executing within limitsMedium
trustedFull autonomy (enterprise only)High

3.4 Agent Identity

Agents receive a DID-based identity:
did:qwed:agent:<agent_id>

4. Verification Requests

4.1 Agent Verification Request

The context object with conversation_id and step_number is required. The step_number must be a positive integer that increases monotonically within a conversation. QWED uses these fields to enforce replay protection, loop detection, and conversation length limits. See conversation controls for details.
{
  "agent_id": "agent_xyz789",
  "agent_token": "qwed_agent_...",
  "action": {
    "type": "execute_sql",
    "query": "SELECT * FROM customers WHERE status = 'active'",
    "target": "production_db"
  },
  "context": {
    "conversation_id": "conv_123",
    "step_number": 5,
    "user_intent": "Get list of active customers",
    "pre_action_state_hash": "a1b2c3d4e5f6...64-char-sha256-hex-digest",
    "state_source": "db_snapshot"
  },
  "options": {
    "require_attestation": true,
    "risk_threshold": "medium"
  }
}

4.2 Verification Response

{
  "decision": "APPROVED",
  "verification": {
    "status": "VERIFIED",
    "engine": "sql",
    "risk_level": "low",
    "checks_passed": [
      "no_destructive_operations",
      "no_sensitive_columns",
      "schema_valid"
    ]
  },
  "attestation": "eyJhbGciOiJFUzI1NiIs...",
  "budget_remaining": {
    "daily_cost_usd": 89.50,
    "hourly_requests": 42
  }
}

4.3 Decision Types

DecisionMeaningAgent Action
APPROVEDSafe to executeProceed
DENIEDVerification failedAbort + log
CORRECTEDFixed version availableUse corrected
PENDINGRequires human approvalWait
BUDGET_EXCEEDEDLimits reachedAbort

5. Tool Verification

5.1 Tool Call Request

Before an agent calls an external tool:
{
  "agent_id": "agent_xyz789",
  "tool_call": {
    "tool_name": "send_email",
    "parameters": {
      "to": "user@example.com",
      "subject": "Your order status",
      "body": "Your order #12345 has shipped..."
    }
  },
  "justification": "User requested order status update"
}

5.2 Tool Risk Assessment

{
  "tool_name": "send_email",
  "risk_assessment": {
    "base_risk": "medium",
    "factors": [
      {"factor": "external_communication", "weight": 0.3},
      {"factor": "pii_in_content", "weight": 0.5}
    ],
    "final_risk": "medium",
    "requires_approval": false
  },
  "policy_checks": [
    {"policy": "no_pii_leakage", "passed": true},
    {"policy": "rate_limit", "passed": true}
  ]
}

5.3 Tool Registry

{
  "tools": [
    {
      "name": "database_read",
      "risk_level": "low",
      "requires_verification": true,
      "verification_engine": "sql"
    },
    {
      "name": "database_write",
      "risk_level": "critical",
      "requires_verification": true,
      "requires_approval": true,
      "verification_engine": "sql"
    },
    {
      "name": "execute_code",
      "risk_level": "critical",
      "requires_verification": true,
      "verification_engine": "code",
      "sandbox_required": true
    }
  ]
}

6. Budget & Limits

6.1 Budget Schema

{
  "budget": {
    "cost": {
      "max_daily_usd": 100.00,
      "max_per_request_usd": 1.00,
      "current_daily_usd": 10.50
    },
    "requests": {
      "max_per_hour": 1000,
      "max_per_day": 10000,
      "current_hour": 42,
      "current_day": 350
    },
    "tokens": {
      "max_per_request": 4096,
      "max_daily": 1000000,
      "current_daily": 50000
    },
    "tools": {
      "max_calls_per_hour": 100,
      "high_risk_calls_remaining": 5
    }
  }
}

6.2 Budget Enforcement

┌─────────────────────────────────────────────────────────────┐
│                  BUDGET CHECK FLOW                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Request ──▶ [Check Cost] ──▶ [Check Rate] ──▶ [Execute]   │
│                   │                │                        │
│                   ▼                ▼                        │
│              Exceeded?         Exceeded?                    │
│                   │                │                        │
│              ┌────┴────┐     ┌────┴────┐                   │
│              │  DENY   │     │  DENY   │                   │
│              │  +429   │     │  +429   │                   │
│              └─────────┘     └─────────┘                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6.3 Budget Response

{
  "decision": "BUDGET_EXCEEDED",
  "error": {
    "code": "QWED-AGENT-BUDGET-001",
    "message": "Daily cost limit exceeded",
    "details": {
      "limit": 100.00,
      "current": 102.50,
      "reset_at": "2025-12-21T00:00:00Z"
    }
  }
}

7. Audit Trail

7.1 Activity Log Schema

Every agent action is logged:
{
  "activity_id": "act_abc123",
  "agent_id": "agent_xyz789",
  "timestamp": "2025-12-20T00:30:00Z",
  "action": {
    "type": "tool_call",
    "tool": "database_read",
    "parameters": { ... }
  },
  "verification": {
    "status": "VERIFIED",
    "engine": "sql",
    "latency_ms": 45
  },
  "decision": "APPROVED",
  "execution": {
    "success": true,
    "result_hash": "sha256:..."
  },
  "cost": {
    "usd": 0.05,
    "tokens": 150
  },
  "attestation_id": "att_xyz789"
}

7.2 Audit Query API

GET /agents/:agent_id/activity?from=2025-12-01&to=2025-12-20
Response:
{
  "agent_id": "agent_xyz789",
  "period": {
    "from": "2025-12-01T00:00:00Z",
    "to": "2025-12-20T00:00:00Z"
  },
  "summary": {
    "total_actions": 15420,
    "approved": 15200,
    "denied": 180,
    "corrected": 40,
    "total_cost_usd": 850.00
  },
  "activities": [ ... ]
}

7.3 Compliance Export

GET /agents/:agent_id/compliance-report?format=pdf

8. Trust Levels

8.1 Trust Level Definitions

LevelDescriptionVerificationApproval
0: UntrustedNo autonomous actionsAllAll
1: SupervisedLow-risk autonomousHigh-riskHigh-risk
2: AutonomousMost actions autonomousCritical onlyCritical only
3: TrustedFull autonomyNoneNone

8.2 Trust Elevation

Agents can request trust elevation:
{
  "agent_id": "agent_xyz789",
  "request": "trust_elevation",
  "from_level": 1,
  "to_level": 2,
  "justification": "30 days of safe operation",
  "evidence": {
    "days_active": 30,
    "total_actions": 50000,
    "denied_actions": 50,
    "denial_rate": 0.001,
    "attestations": 50000
  }
}

8.3 Trust Degradation

Automatic trust reduction on violations:
ViolationPenalty
Security policy violation-2 levels
Repeated denials (>10%)-1 level
Budget abuse-1 level
Principal complaintSuspend

9. Runtime Hardening

New in v1.1.0

9.1 Action Context Requirements

All verification requests MUST include a context with:
FieldTypeRequiredConstraints
conversation_idstringYesNon-empty identifier for the conversation session
step_numberintegerYesMust be >= 1 and monotonically increasing within a conversation
user_intentstringNoHuman-readable description of intent
pre_action_state_hashstringConditionalSHA-256 hex digest (64 lowercase hex characters) of the world state before the action. Required when state_source is provided
state_sourcestringConditionalDeclares how pre_action_state_hash was derived. Required when pre_action_state_hash is provided. One of: file_tree, db_snapshot, conversation_digest, git_tree, custom
The maximum number of steps per conversation is 50. Exceeding this limit triggers QWED-AGENT-LOOP-001.

9.2 Replay Detection

The runtime tracks the highest committed step number per (agent_id, conversation_id) pair. A verification request with a step_number less than or equal to the last committed step is rejected as a replay (QWED-AGENT-LOOP-002). Step numbers are only committed when the action decision is APPROVED or PENDING. Denied actions do not advance the conversation state, allowing the agent to retry the same step number with a different action.

9.3 Repetitive Loop Detection

Actions are fingerprinted using a deterministic JSON serialization of:
  • action_type
  • query
  • code
  • target
  • parameters
If the same fingerprint appears more than 2 consecutive times, the action is blocked with QWED-AGENT-LOOP-003. The repeat counter resets when a different action is submitted. Action parameters MUST be deterministic JSON-compatible values (strings, numbers, booleans, nulls, arrays, and objects with string keys). Non-finite floats (NaN, Infinity) and non-string dictionary keys are rejected.

9.4 Progress-aware doom loop detection (LOOP-004)

New in v1.1.1
LOOP-003 detects repeated actions but cannot detect an agent that retries the same action on an unchanged world state. LOOP-004 closes this gap by binding each action fingerprint to the state of the environment at the time it was proposed. When pre_action_state_hash and state_source are provided in the action context, the guard computes a combined fingerprint:
fingerprint = SHA-256( canonical_json(action) | "STATE:" | pre_action_state_hash )
The combined fingerprint is tracked in a per-conversation sliding window of the last 20 entries. If the same combined fingerprint appears 3 or more times (including the current request), the action is blocked with QWED-AGENT-LOOP-004. Key design properties:
PropertyDetail
Hash algorithmSHA-256 (lowercase hex, 64 characters)
Sliding window size20 entries per (agent_id, conversation_id) pair
No-progress threshold3 identical action + state fingerprints
State source provenanceCaller must declare how the hash was derived (file_tree, db_snapshot, conversation_digest, git_tree, or custom)
Commit semanticsFingerprints are only recorded after the action is APPROVED. Denied and pending actions do not pollute the history
Gradual rollout: The server-side flag DOOM_LOOP_GUARD_REQUIRED controls whether pre_action_state_hash and state_source are mandatory. When set to false (the default during rollout), requests without these fields skip LOOP-004 checks. When set to true, requests without both fields are rejected with QWED-AGENT-STATE-001. Both fields must be provided together. Supplying only one triggers QWED-AGENT-STATE-001.

9.5 In-Flight Reservations

To prevent race conditions in concurrent environments, the runtime uses a reservation system:
  1. When a verification request begins processing, the step number is reserved
  2. Concurrent requests for the same step are rejected with QWED-AGENT-LOOP-002
  3. If the action is denied, the reservation is released — the step can be retried
  4. If the action is approved or pending, the reservation is committed — the step is permanently consumed

9.6 Budget Denial Semantics

Budget check failures (QWED-AGENT-BUDGET-001, QWED-AGENT-BUDGET-002) do not consume the conversation step. The in-flight reservation is released so the agent can retry the same step number after the budget resets.

9.7 Fail-Closed Rate Limiting

When the Redis backend is unavailable, the sliding window rate limiter fails closed (denies all requests) rather than failing open. This prevents uncontrolled access during infrastructure failures. When Redis is entirely absent at process startup, a local in-memory fallback limiter is used.

9.8 Environment Integrity

On server startup, the runtime MUST verify environment integrity (via StartupHookGuard) before initializing the database. A compromised environment causes the server to abort startup with a RuntimeError.

9.9 Timing-Safe Authentication

Agent token verification MUST use constant-time comparison (hmac.compare_digest) to prevent timing side-channel attacks.

10. Implementation Guidelines

9.1 SDK Integration

from qwed_sdk import QWEDAgentClient

# Register agent
agent = QWEDAgentClient.register(
    name="MyAgent",
    principal_id="org_123",
    permissions={
        "allowed_engines": ["math", "sql"],
        "allowed_tools": ["database_read"]
    },
    budget={
        "max_daily_cost_usd": 50.00
    }
)

# Before executing any action
result = agent.verify_action({
    "type": "execute_sql",
    "query": "SELECT * FROM users"
})

if result.decision == "APPROVED":
    # Safe to execute
    execute_query(result.verified_query)
    
    # Log with attestation
    agent.log_execution(
        action_id=result.action_id,
        success=True,
        attestation=result.attestation
    )

9.2 LangChain Integration

from langchain.agents import AgentExecutor
from qwed_sdk.langchain import QWEDVerificationCallback

# Wrap agent with QWED verification
agent_executor = AgentExecutor(
    agent=my_agent,
    tools=my_tools,
    callbacks=[QWEDVerificationCallback(
        agent_id="agent_xyz789",
        agent_token="qwed_agent_..."
    )]
)

# All tool calls automatically verified
result = agent_executor.run("Get customer data")

9.3 CrewAI Integration

from crewai import Agent, Task, Crew
from qwed_sdk.crewai import QWEDVerifiedAgent

# Wrap agents with QWED
verified_agent = QWEDVerifiedAgent(
    agent=researcher,
    qwed_settings={
        "verify_all_tools": True,
        "require_attestation": True
    }
)

Appendix A: Error Codes

CodeDescription
QWED-AGENT-001Agent not registered
QWED-AGENT-002Invalid agent token
QWED-AGENT-003Agent suspended
QWED-AGENT-004Tool not allowed
QWED-AGENT-005Verification failed
QWED-AGENT-CTX-001Missing required action context (conversation_id and step_number)
QWED-AGENT-CTX-002Invalid step_number (must be >= 1)
QWED-AGENT-LOOP-001Conversation step limit exceeded (max 50 steps)
QWED-AGENT-LOOP-002Replay or out-of-order action step detected
QWED-AGENT-LOOP-003Repetitive action loop detected (max 2 consecutive identical actions)
QWED-AGENT-LOOP-004No-progress doom loop detected (same action on unchanged state ≥ 3 times)
QWED-AGENT-STATE-001Missing or incomplete state hash fields (pre_action_state_hash and state_source must be provided together)
QWED-AGENT-STATE-002Invalid pre_action_state_hash format (must be 64-character lowercase hex SHA-256)
QWED-AGENT-STATE-003Invalid state_source value
QWED-AGENT-STATE-004Action parameters contain non-deterministic values
QWED-AGENT-BUDGET-001Daily cost exceeded
QWED-AGENT-BUDGET-002Hourly rate exceeded
QWED-AGENT-BUDGET-003Token limit exceeded
QWED-AGENT-TRUST-001Insufficient trust level
QWED-AGENT-TRUST-002Action requires approval

Appendix B: HTTP Endpoints

EndpointMethodDescription
/agents/registerPOSTRegister new agent
/agents/:idGETGet agent details
/agents/:id/verifyPOSTVerify agent action
/agents/:id/tools/:toolPOSTVerify tool call
/agents/:id/activityGETGet activity log
/agents/:id/budgetGETGet budget status
/agents/:id/trustPOSTRequest trust change

© 2025 QWED-AI. This specification is released under Apache 2.0 License.