Messages & Wire Protocol

Status: Standard-only Alpha (v1.0.0-alpha.2)
Last Updated: 2026-03-12
Spec ID: ACGP-2
Normative Keywords: MUST, SHOULD, MAY (per RFC 2119 and RFC 8174)

Abstract

This specification defines the message formats, security envelope, transport protocol, version negotiation, retry semantics, batch processing, and error handling for ACGP. It is the authoritative source for ACGP wire protocol versioning.

Requirements Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD 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.

⚠️ Security Notice (Alpha): This specification does not define key lifecycle management (rotation, revocation, distribution) or identity provider binding. Implementations MUST supply their own key management and identity verification. See Known Limitations.

1. Scope [NORMATIVE]

ACGP-2 defines how messages are exchanged between Operating Agents, Governance Stewards, and supporting infrastructure.

ACGP-2 does not define:

  • Blueprint inheritance semantics (→ ACGP-3)
  • Tripwire policy semantics (→ ACGP-4)
  • CTQ scoring logic (→ ACGP-3)
  • Trust debt algorithm semantics (→ ACGP-3)
  • Audit durability requirements (→ ACGP-5)

2. Transport and Serialization [NORMATIVE]

  • Serialization: All message payloads MUST be serialized as JSON.
  • Transport: The primary transport protocol MUST be HTTPS. HTTP/2 is RECOMMENDED for improved performance.
  • Authentication: Communication channels MUST be authenticated. Implementations SHOULD use either OAuth 2.0 Bearer Tokens or mutual TLS (mTLS) for service-to-service authentication.
  • Connection Management: Implementations SHOULD use persistent connections and connection pooling to minimize overhead.

2.1 HTTP Binding [NORMATIVE]

Parameter Value
Method POST
Path /acgp/v1/messages
Content-Type application/json; charset=utf-8
Request Body Single ACGP envelope (§4)
Success HTTP 200 + ACGP envelope response
Client Error HTTP 400 + error object (§8)
Auth Error HTTP 401 / 403
Conflict HTTP 409 (idempotency, §7.4)
Server Error HTTP 500 / 503 + error object (§8)

Batch submissions (§6) use the same endpoint.

Compression [NORMATIVE]: Compression is a capability hint for future versions. v1.0 implementations MUST NOT require compression support for conformance. If both peers negotiate a common compression algorithm, implementations SHOULD apply it as HTTP Content-Encoding. Receivers MUST reject unsupported encodings with HTTP 415 (Unsupported Media Type).

3. Version and Capability Negotiation [NORMATIVE]

Before any message exchange, implementations MUST negotiate the protocol version to ensure interoperable behavior.

3.1 Negotiation Process

  1. Select highest common semantic version.
  2. If no common version exists, reject the session with ProtocolVersionMismatch.
  3. Capability announcements MAY include optional features (batching, compression, extensions).
  4. If a peer requires an extension marked required, negotiation or activation MUST follow the descriptor's authoritative-enforcer semantics: local requires local enforcement support, remote requires descriptor preservation plus remote authoritative enforcement and MUST NOT by itself block local activation, and both requires support on both sides. When a required authoritative enforcer is unavailable, the descriptor's fail_mode MUST apply.
  5. Implementations that advertise intervention execution support MUST use the canonical enumerated capability field intervention_execution_modes, for example "intervention_execution_modes": ["passive", "active"]. Boolean capability aliases MUST NOT be used for this surface.

3.2 Version Negotiation Messages

Client Request:

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "VERSION_NEGOTIATION",
  "message_id": "01924a8c-e7f0-7000-8000-000000000000",
  "timestamp": "2026-01-15T08:59:59.000Z",
  "sender_id": "agent-xyz-123",
  "receiver_id": "steward-abc-456",
  "payload": {
    "client_versions": ["1.0.0", "1.1.0"],
    "capabilities": {
      "batch_processing": true,
      "streaming": false,
      "compression": ["gzip"],
      "governance_contracts": false,
      "intervention_execution_modes": ["passive", "active"],
      "extension_support": {
        "supports_private_extensions": true,
        "rejects_unsupported_required_extensions": true,
        "supported_extensions": [
          {
            "id": "urn:acgp:ext:source-catalog-private@1",
            "visibility": "private",
            "versions": ["1"]
          },
          {
            "id": "urn:acgp:ext:contracts@1",
            "visibility": "public",
            "versions": ["1"]
          }
        ]
      }
    }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "..."
  }
}

Server Response:

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "VERSION_SELECTED",
  "message_id": "01924a8c-e7f1-7000-8000-000000000001",
  "timestamp": "2026-01-15T09:00:00.000Z",
  "sender_id": "steward-abc-456",
  "receiver_id": "agent-xyz-123",
  "payload": {
    "selected_version": "1.0.0",
    "server_capabilities": {
      "batch_processing": true,
      "max_batch_size": 100,
      "streaming": false,
      "compression": ["gzip"],
      "governance_contracts": false,
      "intervention_execution_modes": ["passive", "active"],
      "extension_support": {
        "supports_private_extensions": true,
        "rejects_unsupported_required_extensions": true,
        "supported_extensions": [
          {
            "id": "urn:acgp:ext:source-catalog-private@1",
            "visibility": "private",
            "versions": ["1"]
          },
          {
            "id": "urn:acgp:ext:contracts@1",
            "visibility": "public",
            "versions": ["1"]
          }
        ]
      }
    }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "..."
  }
}

3.3 Version Negotiation Rules

Client ↓ / Server → Same Major.Minor Same Major, diff Minor Different Major
Behavior Full interoperability Same-major peer handling REQUIRED MUST reject (error 426)
  • PATCH version differences: always interoperable
  • MINOR version difference: same-major peer handling required
  • MAJOR version difference: MUST reject with ProtocolVersionMismatch error

4. Message Envelope [NORMATIVE]

All ACGP messages MUST be encapsulated within a common JSON envelope providing metadata, routing, and security assurances.

4.1 Envelope Structure

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "TRACE | EVAL | INTERVENTION | HITL | SESSION_INIT | BUNDLE_UPDATE | VERSION_NEGOTIATION | VERSION_SELECTED",
  "message_id": "uuid-v7-string",
  "timestamp": "ISO8601-UTC-string",
  "sender_id": "unique-identifier-string",
  "receiver_id": "unique-identifier-string",
  "payload": { },
  "security": {
    "signature": "jws-compact-serialization-string",
    "checksum_alg": "sha256",
    "checksum": "hex-encoded-checksum-of-canonicalized-envelope-excluding-security"
  }
}

4.2 Envelope Field Requirements

Field Type Required Description
protocol string REQUIRED MUST be "acgp"
protocol_version string REQUIRED Semantic version (e.g., "1.0.0")
message_type enum REQUIRED One of: VERSION_NEGOTIATION, VERSION_SELECTED, TRACE, EVAL, INTERVENTION, HITL, SESSION_INIT, BUNDLE_UPDATE.
message_id string REQUIRED UUIDv7 RECOMMENDED for time-ordered idempotency
timestamp string REQUIRED RFC 3339 timestamp in UTC
sender_id string REQUIRED Identifier of the transport or runtime sender
receiver_id string REQUIRED Unique identifier of receiver
payload object REQUIRED Message-specific data
security.signature string Profile/Governance-Tier-dependent (see §4.4 Signature Requirements Matrix) JWS compact serialization using ES256
security.checksum_alg string MUST for Safety-Critical; SHOULD for Standard MUST be "sha256"
security.checksum string MUST for Safety-Critical; SHOULD for Standard Hex-encoded SHA-256 of canonicalized JSON envelope excluding security

Envelope field semantics [NORMATIVE]:

  • sender_id identifies the transport or runtime sender of the message.
  • sender_id is not necessarily the same as TRACE agent_id.
  • Implementations MUST NOT reject an otherwise valid message solely because envelope sender_id and TRACE agent_id differ.

Message types are grouped into three normative categories:

Category Message Types Required For
Handshake VERSION_NEGOTIATION, VERSION_SELECTED All profiles
Core Runtime TRACE, EVAL, INTERVENTION, HITL All profiles
Sync / Control SESSION_INIT, BUNDLE_UPDATE All profiles

4.3 Canonicalization and Integrity [NORMATIVE]

This section is the single normative source for canonicalization rules in ACGP.

All ACGP message fields and blueprint properties MUST use snake_case on the wire and in persisted artifacts. Language SDKs MAY expose idiomatic casing but MUST serialize to/from snake_case.

Implementations MUST use RFC 8785 (JSON Canonicalization Scheme, JCS) as the canonicalization algorithm for all checksum and signature operations.

For security.checksum, the input byte sequence MUST be:

  1. Construct integrity_envelope as the full message envelope excluding the security object.
  2. Canonicalize integrity_envelope with RFC 8785 JCS.
  3. Compute SHA-256 over the canonicalized bytes.

This is normative Option B semantics (JCS(envelope excluding security)), and it protects routing metadata (sender_id, receiver_id, message_type) in addition to payload.

If a JWS signature is present, it MUST sign the exact same canonicalized byte sequence used for the checksum.

Worked example (illustrative):

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "TRACE",
  "message_id": "01924b1a-a001-7000-8000-000000000101",
  "timestamp": "2026-01-15T09:00:01.000Z",
  "sender_id": "agent-xyz-123",
  "receiver_id": "steward-abc-456",
  "payload": {
    "trace_id": "uuid-v4-string",
    "agent_id": "agent-xyz-123",
    "session_id": "session-01924b1a",
    "hook": "tool_call",
    "context": {},
    "governance_tier": "GT-2",
    "action": {
      "name": "purchase",
      "parameters": {
        "amount": 42
      }
    }
  }
}

Canonicalized form (single-line JCS form, abridged for readability):

{"message_id":"01924b1a-a001-7000-8000-000000000101","message_type":"TRACE","payload":{"action":{"name":"purchase","parameters":{"amount":42}},"agent_id":"agent-xyz-123","context":{},"governance_tier":"GT-2","hook":"tool_call","session_id":"session-01924b1a","trace_id":"uuid-v4-string"},"protocol":"acgp","protocol_version":"1.0.0","receiver_id":"steward-abc-456","sender_id":"agent-xyz-123","timestamp":"2026-01-15T09:00:01.000Z"}

checksum = SHA-256(canonical_bytes) and any JWS signature signs canonical_bytes.

4.4 Signature Requirements [NORMATIVE]

When security.signature is present, it MUST be a JWS Compact Serialization.

Required JWS header fields:

  • alg MUST be ES256
  • kid MUST be present and identify the signing key version

Recommended JWS header fields:

  • typ SHOULD be acgp+jwt

Key rotation requirements:

  • Implementations MUST support signing key rotation without session restart.
  • Implementations SHOULD support overlapping key validity windows of at least 24 hours.

Replay and clock skew requirements:

  • Implementations MUST reject messages with timestamp more than 5 minutes in the past or future relative to verifier time.
  • The tolerance window MUST be configurable; default MUST be 5 minutes.

JWS Payload Construction [NORMATIVE]:

The JWS MUST use Compact Serialization (header.payload.signature).

The JWS payload bytes MUST be the RFC 8785 JCS canonical UTF-8 byte sequence of the envelope with the security object removed. In Compact Serialization, the payload segment is the base64url encoding of those bytes (per RFC 7515 §3). This is the same byte sequence used for security.checksum (§4.3).

The security.signature field MUST contain the complete JWS Compact Serialization string. Detached payloads MUST NOT be used.

Step-by-step construction: 1. Build envelope (all fields except security). 2. RFC 8785 JCS canonicalize → UTF-8 bytes C. 3. checksum = hex(SHA-256(C))security.checksum. 4. JWS: header = {"alg":"ES256","kid":"...","typ":"acgp+jwt"}, payload = C (raw bytes — base64url encoding is part of JWS serialization, not a pre-processing step). Sign per RFC 7515. 5. Compact Serialization string → security.signature.

Verification: 1. Extract security.signature, decode JWS payload segment → bytes C'. 2. Remove security, canonicalize → bytes C. 3. Assert C' == C (byte-identical). 4. Verify JWS signature with public key from kid.

Signature Requirements Matrix [NORMATIVE]:

Standard Profile Safety-Critical Profile
GT-0 to GT-2 Checksum SHOULD; Signature MAY Checksum MUST; Signature MUST
GT-3 to GT-4 Checksum MUST; Signature MUST Checksum MUST; Signature MUST; HSM MUST
GT-5 Checksum MUST; Signature MUST Checksum MUST; Signature MUST; HSM MUST; Cert pinning MUST

All profiles/tiers: TLS 1.3+ MUST. RFC 8785 JCS MUST.


5. Message Payloads [NORMATIVE]

Note: The examples below show the payload object only. In transit, every payload MUST be wrapped in the standard envelope. See Section 10 for complete envelope-wrapped examples.

5.1 TRACE

Agent → Steward telemetry message for a governed action.

Payload object (sits inside the envelope's payload field):

{
  "trace_id": "uuid-v4-string",
  "parent_trace_id": "uuid-v4-string",
  "agent_id": "urn:acgp:agent:financeops:prod:7f4c9d2a",
  "session_id": "uuid-v4-string",
  "hook": "tool_call",
  "governance_tier": "GT-2",
  "step": 12,
  "inputs": {
    "user_prompt": "Summarize Q3 earnings for ACME.",
    "context": {}
  },
  "reasoning": "Customer reported defective product with photographic evidence.",
  "action": {
    "name": "issue_refund",
    "parameters": { "order_id": "12345", "amount": 250.00 }
  },
  "tool_calls": [
    { "name": "search", "args": { "query": "ACME Q3 2025 earnings" } }
  ],
  "tools_used": ["payment_api", "order_database"],
  "outputs": { "text": "ACME's Q3 earnings showed a 10% YoY growth." },
  "source_refs": ["reg:sec:10K:2025"],
  "confidence": 0.92,
  "meta": {
    "agent_label": "FinanceOps-Agent",
    "model": "gpt-5-pro",
    "latency_ms": 450
  },
  "local_eval_results": {
    "bundle_version_hash": "sha256:abc123...",
    "tripwires_checked": ["no_secrets", "no_pii"],
    "scorers_executed": ["rule-based", "pattern-match"],
    "local_ctq_partial": 0.84,
    "local_risk_partial": 0.16,
    "local_decision": "ok"
  }
}

Required fields: trace_id, agent_id, action, session_id, hook, context, governance_tier

The envelope timestamp (§4.2) is authoritative. TRACE payloads MUST NOT include a separate timestamp. The context field contains execution/environment context. User-provided conversation context belongs in inputs.context if present.

TRACE identity semantics [NORMATIVE]:

This section is a summary only. The authoritative normative definition is in ACGP-7 §4.

For normative identity semantics, including agent_id, agent_label, and sender_id distinctions, see ACGP-7.

Recommended fields: reasoning (RECOMMENDED per ACGP-3 §4.1)

Optional fields: parent_trace_id, step, inputs, tool_calls, tools_used, outputs, source_refs, confidence, meta, local_eval_results

Hook values: The hook field MUST be one of:

Hook Value Trigger Point
pre_action Before agent executes an action
tool_call Agent invokes an external tool
tool_result Agent receives tool execution result
post_action After agent completes an action
session_start Session initialization
session_end Session termination

Implementations MUST reject unrecognized hook values with error code InvalidTraceHookValue. There is no "any" hook value on the wire.

Implementations MAY emit a final TRACE with hook: "session_end" to record intentional termination. Termination reason SHOULD appear in context or meta. Unclean termination is detected through timeout or disconnect semantics rather than a distinct wire message.

Cross-reference: The complete normative trace model is defined in ACGP-3 §4.1. ACGP-2 defines the wire shape; ACGP-3 defines evaluation expectations.

local_eval_results is advisory. Steward remains authoritative for all decisions.

Steward implementations SHOULD use local_eval_results as a hint to skip redundant Tier-0 re-evaluation when the local bundle hash matches the current authoritative bundle. Stewards MUST NOT skip Tier-1+ evaluation based on local results. When local and remote decisions conflict, the remote (Steward) decision is authoritative.

5.2 EVAL

Steward evaluation record for a TRACE. Logged to the Governance Store; a copy MAY be sent to the Operating Agent as evidence. EVAL is the canonical governance outcome artifact on the wire.

Payload object (sits inside the envelope's payload field):

{
  "trace_id": "uuid-v4-string",
  "blueprint_id": "finance_qa@2.1",
  "governance_tier": "GT-2",
  "ctq_dimensions": {
    "reasoning_quality": {
      "score": 0.90,
      "weight": 0.25,
      "status": "evaluated",
      "contributors": ["rationale_clarity", "plan_completeness"],
      "confidence": 0.82
    },
    "knowledge_grounding": {
      "score": 0.88,
      "weight": 0.20,
      "status": "evaluated",
      "contributors": ["citation_coverage"]
    },
    "ethical_alignment": {
      "score": 0.95,
      "weight": 0.20,
      "status": "evaluated",
      "contributors": ["fairness_review"]
    },
    "tool_safety": {
      "score": 0.92,
      "weight": 0.20,
      "status": "evaluated",
      "contributors": ["permission_check"]
    },
    "context_awareness": {
      "score": 0.89,
      "weight": 0.15,
      "status": "evaluated",
      "contributors": ["situational_fit"]
    }
  },
  "ctq_score": 0.908,
  "risk_score": 0.092,
  "effective_thresholds": {
    "ok": 0.25, "nudge": 0.40, "escalate": 0.55
  },
  "tripwires_triggered": [],
  "intervention": "ok",
  "flagged": false,
  "runtime_posture": "normal",
  "review_required": false,
  "trust_debt": {
    "provider_id": "acgp.core.default@1",
    "pre": 0.0,
    "delta": 0.0,
    "post": 0.0,
    "thresholds_crossed": []
  },
  "explanations": "Risk score within OK threshold for GT-2.",
  "evidence_result": {
    "certified_sources_found": ["reg:sec:10K:2025"],
    "penalties": []
  },
  "evaluation_metadata": {
    "policy_engine_version": "1.2.3",
    "evaluation_duration_ms": 145
  },
  "cost": { "estimate_usd": 0.0021, "meter": "tokens_usd" }
}

Required fields: trace_id, blueprint_id, governance_tier, ctq_dimensions, ctq_score, risk_score, tripwires_triggered, intervention, flagged, runtime_posture, review_required

ctq_dimensions MUST contain the five canonical CTQ dimensions: reasoning_quality, knowledge_grounding, ethical_alignment, tool_safety, and context_awareness.

Each dimension result MUST include score, weight, status, and contributors. status MUST be one of evaluated, degraded, unavailable, error, or failed_evidence_policy. Optional per-dimension fields include confidence, latency_ms, notes, and evidence_handles.

Contributor visibility is part of the wire contract: failed_evidence_policy and unavailable use empty contributors; error and degraded preserve attempted contributors.

When trust debt is enabled, trust_debt MUST be an object containing provider_id, pre, delta, post, and cumulative current-state thresholds_crossed.

The top-level intervention field MUST be the final post-floor outcome. Implementations MAY preserve the pre-posture value only in subordinate metadata such as evaluation_metadata.pre_posture_intervention and MUST NOT emit two peer top-level intervention fields.

Implementations MUST preserve evaluator state separately from the serialized quality score. A missing scorer, timeout, unavailable extension, evidence-system outage, or evaluator failure MUST NOT be silently represented as an ordinary low-quality result in the public EVAL payload.

Example degraded/unavailable dimension reporting:

{
  "trace_id": "uuid-v4-string",
  "blueprint_id": "finance_qa@2.1",
  "governance_tier": "GT-2",
  "ctq_dimensions": {
    "reasoning_quality": {
      "score": 0.91,
      "weight": 0.25,
      "status": "evaluated",
      "contributors": ["rationale_clarity", "plan_completeness"]
    },
    "knowledge_grounding": {
      "score": 0.0,
      "weight": 0.20,
      "status": "failed_evidence_policy",
      "contributors": [],
      "notes": "Evidence gate failed before knowledge-grounding scorers executed."
    },
    "ethical_alignment": {
      "score": 0.94,
      "weight": 0.20,
      "status": "evaluated",
      "contributors": ["fairness_review"]
    },
    "tool_safety": {
      "score": 0.76,
      "weight": 0.20,
      "status": "degraded",
      "contributors": ["permission_check"],
      "notes": "Fallback rule used after tool-sandbox timeout."
    },
    "context_awareness": {
      "score": 0.0,
      "weight": 0.15,
      "status": "unavailable",
      "contributors": [],
      "notes": "Optional context adapter unavailable; aggregate redistributed across available dimensions."
    }
  },
  "ctq_score": 0.7080,
  "risk_score": 0.2920,
  "effective_thresholds": {
    "ok": 0.25, "nudge": 0.40, "escalate": 0.55
  },
  "tripwires_triggered": [],
  "intervention": "nudge",
  "flagged": true,
  "runtime_posture": "elevated_monitoring",
  "review_required": false,
  "trust_debt": {
    "provider_id": "acgp.core.default@1",
    "pre": 2.90,
    "delta": 0.60,
    "post": 3.50,
    "thresholds_crossed": ["elevated_monitoring"]
  },
  "evaluation_metadata": {
    "fallback_policy": "mixed_declared_policies"
  }
}

5.3 INTERVENTION

Steward intervention decision sent to agent.

Payload object (sits inside the envelope's payload field):

{
  "trace_id": "uuid-v4-string",
  "decision": "ok",
  "flags": { "flagged": false, "severity": null },
  "message": "Action approved within policy bounds. CTQ 0.908 exceeds GT-2 threshold.",
  "risk_score": 0.092,
  "ctq_score": 0.908,
  "modifications": [],
  "trust_debt_delta": 0.0,
  "requires_human_review": false,
  "evidence": {
    "ctq_final": 0.908,
    "risk_score": 0.092,
    "effective_thresholds": { "ok": 0.25, "nudge": 0.40 },
    "tripwires_triggered": []
  }
}

Required fields: trace_id, decision, flags, message

decision MUST be one of: ok, nudge, escalate, block, halt.

Decision values on the wire MUST use canonical lowercase and MUST be compared case-sensitively (see ACGP-1 Section 3.3).

If modifications is present, each entry MUST be an object with:

  • field: string identifying the field or path being adjusted
  • suggested_value: replacement value proposed by the Steward or human reviewer
  • reason: string explaining why the change is requested

5.4 State Synchronization

Out-of-band state synchronization for policy and configuration updates uses SESSION_INIT for initial activation and BUNDLE_UPDATE for subsequent bundle changes.

Payload object (sits inside the envelope's payload field):

{
  "sync_type": "blueprint_update",
  "resource_id": "finance_qa@2.2",
  "action": "update",
  "blueprint_signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InN0ZXdhcmQta2V5LTIwMjYtMDEifQ...",
  "data": {
    "blueprint": { },
    "effective_at": "2026-01-20T00:00:00Z"
  },
  "checksum": "sha256-hash-of-data"
}

5.5 HITL

Human-in-the-loop escalation payload for routing decisions to human operators.

Payload object (sits inside the envelope's payload field):

{
  "request_id": "uuid-v4-string",
  "escalation_id": "uuid-v4-string",
  "trace_id": "uuid-v4-string",
  "deadline": "2026-01-15T09:05:00.000Z",
  "fallback_on_timeout": "block",
  "priority": "high",
  "reason": "Risk score in escalate range",
  "context": {
    "agent_id": "urn:acgp:agent:financeops:prod:7f4c9d2a",
    "agent_governance_tier": "GT-3",
    "session_id": "uuid",
    "original_trace": { },
    "evaluation": { }
  },
  "suggested_actions": ["approve", "modify_and_approve", "deny"],
  "timeout_seconds": 300
}

HITL Completion [NORMATIVE]: The HITL payload MUST include request_id, trace_id, deadline, and fallback_on_timeout. Before deadline, the Steward MUST issue either a final INTERVENTION or a signed HITL_RESULT artifact that is auditable and linked to trace_id. After deadline, the Steward MUST issue an INTERVENTION derived from fallback_on_timeout. The HITL message itself remains one-way (Steward → Human Queue).

Human-review transport, reviewer UI, queueing, and callback mechanics remain deployment-defined. HITL_RESULT standardizes the completion artifact consumed by the Steward, not the transport path used to collect the human decision.

This HITL deadline fallback governs expiration of an already-issued human review request. It is distinct from ACGP-1 profile failure fallback for Steward/session-path unavailability and from Runtime Governance Contracts preview evaluation-timeout policy.

HITL_RESULT is a normative artifact, not a ninth wire message type. It is consumed by the Steward and converted into the final agent-visible INTERVENTION.

When HITL_RESULT.outcome is modify_and_approve, the Steward MAY preserve the modification list in metadata or recourse artifacts. The resulting final intervention remains nudge with modifications, and its execution behavior MUST follow the synchronized nudge_behavior and allow_local_auto_apply rules defined in ACGP-1 §3.5.

HITL_RESULT fields:

  • outcome: one of approve, deny, modify_and_approve
  • operator_id: human reviewer identifier
  • justification: reviewer rationale
  • modifications: optional array, allowed only for modify_and_approve, using the same object shape as INTERVENTION.modifications
  • request_id: HITL request identifier
  • trace_id: associated trace identifier
  • timestamp: RFC 3339 UTC completion time

Illustrative HITL_RESULT artifact:

{
  "request_id": "uuid-v4-string",
  "trace_id": "uuid-v4-string",
  "outcome": "modify_and_approve",
  "operator_id": "reviewer-42",
  "justification": "Trade may proceed after reducing amount and adding account note.",
  "modifications": [
    {
      "field": "action.parameters.amount",
      "suggested_value": 50000,
      "reason": "Amount exceeds delegated approval limit."
    }
  ],
  "timestamp": "2026-01-15T09:04:30.000Z"
}

5.6 SESSION_INIT

Steward → SDK initialization message containing the local evaluation bundle for Stage 1 checks.

SESSION_INIT payload MUST include blueprint_signature alongside bundle_hash.

SESSION_INIT payload MUST include a monotonically increasing bundle_epoch.

SESSION_INIT MAY include intervention_execution, which MUST validate against the narrow v1 surface defined in schemas/intervention-execution.schema.json. Unknown mode or nudge_behavior values, malformed execution-policy payloads, and unsupported advertised execution-mode claims MUST be rejected fail-closed.

Each descriptor in extensions.required[] MUST declare enforcement_scope as local, remote, or both. ignore is not a valid behavior for extensions.required[].

See ACGP-3 §2.2.1 for the consolidated local / remote / both activation and enforcement truth table.

Required extension handling for SESSION_INIT MUST follow the authoritative enforcer defined in ACGP-1 §3.2:

  • local: the SDK is the authoritative enforcer and MUST enforce the extension locally; if it cannot, it MUST apply the descriptor's fail_mode before applying the bundle.
  • remote: the Governance Steward or remote authoritative runtime is the authoritative enforcer. The SDK MUST preserve the descriptor and negotiated metadata locally and MUST NOT reject activation solely because enforcement occurs remotely.
  • both: the SDK and Governance Steward are both authoritative enforcers. If either side lacks support for the required extension, the SDK MUST apply the descriptor's fail_mode before applying the bundle.

Payload object (sits inside the envelope's payload field):

{
  "bundle_epoch": 42,
  "bundle_hash": "sha256:a1b2c3d4e5f6...",
  "blueprint_signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InN0ZXdhcmQta2V5LTIwMjYtMDEifQ...",
  "effective_at": "2026-01-15T09:00:00.000Z",
  "intervention_execution": {
    "mode": "active",
    "nudge_behavior": "acknowledge_and_proceed",
    "allow_local_auto_apply": false
  },
  "extensions": {
    "required": [
      {
        "id": "urn:acgp:ext:source-catalog-private@1",
        "visibility": "private",
        "enforcement_scope": "remote",
        "fail_mode": "reject_activation",
        "attestation": {
          "digest": "sha256:...",
          "issued_by": "did:example:steward"
        }
      }
    ],
    "optional": [
      {
        "id": "urn:acgp:ext:contracts@1",
        "visibility": "public"
      }
    ]
  },
  "bundle": {
    "tier0_tripwires": [
      {
        "id": "max_refund",
        "condition": "action.parameters.amount > 500",
        "severity": "critical",
        "on_fail": { "decision": "block", "reason": "Refund exceeds limit" }
      }
    ],
    "rule_based_scorers": [],
    "pattern_match_scorers": [
      {
        "id": "pii_check",
        "pattern": "\\b\\d{3}-\\d{2}-\\d{4}\\b",
        "mode": "reject_on_match"
      }
    ],
    "thresholds": { "ok": 0.25, "nudge": 0.40, "escalate": 0.55 },
    "governance_tier_overrides": {},
    "fallback_on_timeout": "deny",
    "blueprint_version_hash": "sha256:a1b2c3d4e5f6..."
  }
}

If present in bundle examples, fallback_on_timeout represents optional Runtime Governance Contracts metadata preserved on the wire when that preview extension is active. It is not part of the mandatory v1.0 Standard conformance surface.

5.7 BUNDLE_UPDATE

Steward → SDK incremental bundle refresh when local evaluation bundle changes.

BUNDLE_UPDATE payload MUST include blueprint_signature alongside new_bundle_hash.

BUNDLE_UPDATE payload MUST include a monotonically increasing bundle_epoch.

BUNDLE_UPDATE MAY add, remove, or replace intervention_execution. If absent, the previously accepted execution mode remains in force. If present with mode: passive after an active session, the downgrade MUST be audit-visible and MUST carry a transition reason.

If a BUNDLE_UPDATE introduces or changes a required extension, the receiver MUST evaluate it using the authoritative enforcer defined in ACGP-1 §3.2 and retain the previously active bundle when rejection is required.

See ACGP-3 §2.2.1 for the consolidated local / remote / both activation and enforcement truth table.

A BUNDLE_UPDATE MUST NOT affect an evaluation already in progress. The newly accepted bundle applies starting with the next evaluation begun after update application.

If a runtime accepts intervention_execution.mode: active, conclusive local signed-bundle decisions are execution-authoritative within the bounds defined by ACGP-1 §3.6. Remote-verification-required paths remain distinct from conclusive local fast-path decisions.

Required extension handling for BUNDLE_UPDATE MUST follow these rules:

  • local: the receiver SDK is the authoritative enforcer and MUST enforce the extension locally; if it cannot, it MUST apply the descriptor's fail_mode and retain the previously active bundle when rejection is required.
  • remote: the Governance Steward or remote authoritative runtime is the authoritative enforcer. The receiver SDK MUST preserve the descriptor and negotiated metadata locally and MUST NOT reject the update solely because enforcement occurs remotely.
  • both: the receiver SDK and the Governance Steward are both authoritative enforcers. If either side lacks support for the required extension, the receiver MUST apply the descriptor's fail_mode and retain the previously active bundle when rejection is required.

Receiver application rule [NORMATIVE]:

  • SDK MUST apply the update only if previous_bundle_hash matches the currently active bundle hash.
  • SDK MUST apply the update only if bundle_epoch is greater than the active epoch and previous_bundle_hash matches the currently active bundle hash.
  • If the hash does not match, the SDK MUST reject the update with BundleHashMismatch and request SESSION_INIT to re-synchronize state.

Payload object (sits inside the envelope's payload field):

{
  "bundle_epoch": 43,
  "previous_bundle_hash": "sha256:a1b2c3d4e5f6...",
  "new_bundle_hash": "sha256:f6e5d4c3b2a1...",
  "blueprint_signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InN0ZXdhcmQta2V5LTIwMjYtMDEifQ...",
  "effective_at": "2026-01-15T10:30:00.000Z",
  "intervention_execution": {
    "mode": "passive"
  },
  "transition_reason": "operator_downgrade",
  "changes": {
    "tier0_tripwires": {
      "added": [],
      "removed": [],
      "modified": [
        {
          "id": "max_refund",
          "condition": "action.parameters.amount > 1000",
          "severity": "critical",
          "on_fail": { "decision": "block", "reason": "Refund exceeds updated limit" }
        }
      ]
    },
    "thresholds": {
      "ok": 0.20,
      "nudge": 0.35,
      "escalate": 0.50
    }
  }
}

6. Batch Processing [NORMATIVE]

Batch processing for TRACE submissions is part of the ACGP v1.0 alpha wire-interoperability surface when both peers advertise batch_processing: true during version negotiation.

This section standardizes batch exchange at the evaluator boundary only. It does not guarantee rollback of downstream business side effects outside ACGP.

6.1 Batch TRACE Submission

Batch submission uses the normal ACGP envelope with a batch payload:

{
  "batch_id": "uuid-v4-string",
  "traces": [
    { "trace_id": "uuid-1", "action": "issue_refund", "...": "..." },
    { "trace_id": "uuid-2", "action": "issue_refund", "...": "..." }
  ],
  "batch_size": 2,
  "processing_mode": "parallel",
  "failure_mode": "best_effort"
}

Normative requirements:

  • payload.batch_id MUST be present.
  • payload.traces MUST be a non-empty array of TRACE payload objects.
  • Every trace in a batch MUST include a unique trace_id within that batch.
  • payload.batch_size MUST equal len(payload.traces).
  • payload.processing_mode MUST be parallel or sequential.
  • payload.failure_mode MUST be best_effort or atomic. If omitted, receivers MUST treat it as best_effort.

processing_mode controls execution scheduling only. It MUST NOT change response ordering.

6.2 Batch Constraints

  • Maximum batch size: 100 traces per batch (configurable)
  • Processing mode: parallel (default) or sequential
  • Failure mode: best_effort (default) or atomic
  • Timeout: Receivers SHOULD apply per-entry timeout budgets and return one batch response after all entries resolve or the batch is rejected
  • Response ordering: results[] MUST preserve the same order as traces[], regardless of internal execution order

Failure-mode semantics:

  • best_effort: invalid or failed entries MUST NOT prevent remaining valid entries from being evaluated.
  • atomic: the batch is admission-atomic at the evaluator boundary. Receivers MUST validate the full batch before executing it. If any entry is invalid at admission time, receivers MUST reject execution for the entire batch and return not_executed or equivalent failure results for every non-invalid entry.

atomic in v1.0 does not imply automatic rollback of downstream side effects outside the ACGP evaluator boundary.

6.3 Batch Response

{
  "batch_id": "uuid-v4-string",
  "results": [
    {
      "entry_index": 0,
      "trace_id": "uuid-1",
      "status": "success",
      "intervention": { }
    },
    {
      "entry_index": 1,
      "trace_id": "uuid-2",
      "status": "invalid",
      "error": { "code": "InvalidTrace", "message": "action is required" }
    }
  ],
  "summary": { "total": 2, "succeeded": 1, "failed": 1 }
}

Normative requirements:

  • results[] MUST be in the same order as the input traces[].
  • Every result entry MUST include entry_index, trace_id, and status.
  • status MUST be one of success, invalid, error, duplicate, or not_executed.
  • Mixed-success batches MUST include failure details for each non-success entry.

6.4 Retry, Idempotency, and Replay

Batch submissions use the same envelope message_id idempotency rules defined in §7.4.

Normative requirements:

  • Clients retrying the exact same batch MUST reuse the same envelope message_id.
  • Receivers MUST treat exact replay of the same batch message_id as idempotent and MUST return a semantically identical batch response.
  • Receivers MUST NOT reprocess already accepted entries on an exact replay.
  • Duplicate trace_id values within one batch MUST be rejected as invalid batch input.

6.5 Audit Requirements For Batches

Receivers MUST emit:

  • one batch-level audit artifact keyed by batch_id
  • one per-entry audit artifact keyed by (batch_id, entry_index, trace_id)

For mixed-success batches, per-entry audit artifacts MUST record the final status and any failure reason.


7. Retry and Timeout Behavior [NORMATIVE]

7.1 Standard Retry Policy

All implementations MUST implement retry with bounded exponential backoff:

retry_policy:
  max_attempts: 3
  backoff: exponential
  backoff_multiplier: 2
  initial_delay_ms: 100
  max_delay_ms: 5000
  timeout_ms: 500
  jitter: true        # ±10% of delay
  failure_action: escalate

7.2 Timeout Specifications

Message Type Default Timeout Max Timeout On Timeout
TRACE 500ms 1000ms Retry with backoff
EVAL 200ms 500ms Use cached policy
INTERVENTION 100ms 200ms Retry with backoff
HITL 300000ms (5min) User-defined Deny by default
SESSION_INIT 5000ms 10000ms Use cached bundle
BUNDLE_UPDATE 2000ms 5000ms Keep current bundle

The HITL timeout row covers review-deadline expiration for an active HITL request. It does not redefine ACGP-1 profile failure fallback or Runtime Governance Contracts preview evaluation-timeout policy.

7.3 Failure Actions

Failure Type Action Retryable
Network timeout Retry with backoff Yes
Service unavailable Retry with backoff Yes
Rate limit exceeded Retry with backoff Yes
Invalid message Reject immediately No
Authentication failure Reject immediately No
Final retry exhausted Escalate to human review

After final retry exhaustion, implementations MUST apply profile fallback defaults (see ACGP-1 Section 7). Profile fallback ownership is defined in ACGP-1. Runtime Governance Contracts timeout policy is preview extension behavior and is distinct from core disconnect fallback:

Profile Required Fallback After Final Retry
Standard block by default; MAY use explicitly declared override (escalate or stricter) with audit log
Safety-Critical halt (fail-closed, non-relaxable)
Dev Mode allow_and_log or observe_only (non-conformant mode)

If a request includes action-level fallback behavior (for example via Runtime Governance Contracts), that behavior MAY be used only when it is not weaker than the profile minimum.

7.4 Idempotency [NORMATIVE]

Receivers MUST treat message_id as idempotency key scoped to (sender_id, receiver_id).

Condition Behavior HTTP Status
Same message_id, identical canonical bytes Return cached response 200
Same message_id, different canonical bytes Reject MessageIdReplayMismatch 409
New message_id Process normally 200/4xx/5xx

Cache: retain ≥ 24 hours. Never evict early for INTERVENTION or HITL. Offline replay: wrap in signed replay container (§9.3); freshness checks apply to container received_at.


8. Error Handling [NORMATIVE]

8.1 Error Response Format

{
  "error": {
    "code": "InvalidTraceMessage",
    "message": "TRACE message is missing required 'action' field.",
    "details": {
      "trace_id": "uuid-of-failed-trace",
      "missing_fields": ["action"]
    },
    "timestamp": "2026-01-15T10:00:00Z",
    "request_id": "uuid-v4"
  }
}

8.2 Standard Error Codes

Error Code HTTP Status Description Retryable
InvalidMessage 400 Malformed message structure No
InvalidVersion 400 Unsupported protocol version No
MissingField 400 Required field missing No
InvalidBlueprintHaltInRule 400 Blueprint has halt in rule-based on_fail.decision No
InvalidTraceHookValue 400 Unrecognized hook value No
InvalidBlueprintWeights 400 CTQ weights don't sum to 1.0 (±0.001) No
TripwireRegexTooLong 400 Regex pattern > 1024 chars No
TripwireRegexInvalidFlag 400 Unsupported regex flag No
TrustDebtThresholdExceeded 400 Trust debt threshold > 2× Clarity Baseline No
BundleHashMismatch 409 BUNDLE_UPDATE.previous_bundle_hash does not match current bundle hash No
IntegrityCheckFailed 401 Checksum, message signature, or blueprint signature verification failed No
Unauthorized 401 Authentication failed No
Forbidden 403 Insufficient permissions No
NotFound 404 Resource not found No
Timeout 408 Request timeout Yes
MessageIdReplayMismatch 409 Duplicate message_id, different bytes No
RateLimitExceeded 429 Too many requests Yes
InternalError 500 Server error Yes
ServiceUnavailable 503 Service temporarily unavailable Yes

9. Security and Integrity [NORMATIVE]

9.1 Transport Security

All communication MUST occur over TLS 1.3 or higher.

Requirements:

  • Perfect forward secrecy
  • Certificate validation
  • Strong cipher suites only
  • Mutual TLS (mTLS) RECOMMENDED for service-to-service

9.2 Message Integrity

Recipients MUST validate the checksum in the security envelope:

def validate_message_integrity(envelope):
    # Step 1: Remove security block (shallow copy)
    integrity_envelope = {k: v for k, v in envelope.items() if k != 'security'}
    # Step 2: Canonicalize via RFC 8785 JCS → UTF-8 bytes
    canonical_bytes = jcs.canonicalize(integrity_envelope)
    # Step 3: SHA-256 over UTF-8 bytes
    calculated = hashlib.sha256(canonical_bytes).hexdigest()
    # Step 4: Compare hex-encoded checksum
    if calculated != envelope['security']['checksum']:
      raise IntegrityError("IntegrityCheckFailed")
Messages that fail checksum or signature verification MUST be rejected with error code `IntegrityCheckFailed` and MUST NOT be applied. Persistent integrity failures SHOULD trigger a security alert.

9.3 Non-Repudiation

For GT-3+ actions, the signature field MUST be populated:

  • Operating Agent signs canonicalized TRACE envelope (excluding security)
  • Governance Steward signs canonicalized INTERVENTION envelope (excluding security)
  • All signatures use ES256 (ECDSA with P-256 and SHA-256)

For SESSION_INIT and BUNDLE_UPDATE messages carrying blueprint material, the payload MUST include blueprint_signature, which is a JWS Compact Serialization over the canonicalized blueprint content. SDKs MUST verify blueprint_signature before applying a bundle update. Verification failure MUST trigger reject + alert (no silent fallback).

Blueprint signing profile requirements:

  • GT-3 through GT-5: REQUIRED
  • GT-0 through GT-2: RECOMMENDED

The signing key for blueprint_signature MUST be the Steward governance key.

9.4 Data Redaction

Sensitive information (PII, secrets) SHOULD be redacted before transmission:

{
  "outputs": {
    "text": "User SSN: [REDACTED:SSN]",
    "redacted_fields": ["ssn"]
  }
}

Redaction and minimization policies are defined in ACGP-5.

9.5 Blueprint Signing Canonicalization [NORMATIVE]

  1. Parse blueprint from YAML 1.2 or JSON.
  2. Convert to canonical JSON conforming to blueprint-core.schema.json.
  3. Apply RFC 8785 JCS.
  4. Sign via JWS (same construction as §4.4).

Two representations producing the same canonical JSON MUST produce identical signatures. Verification failure MUST be treated as IntegrityCheckFailed.


10. Formal Message Schemas [NORMATIVE]

The examples in this section are complete envelope-wrapped messages.

10.1 TRACE (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "TRACE",
  "message_id": "01924b1a-a001-7000-8000-000000000101",
  "timestamp": "2026-01-15T09:00:01.000Z",
  "sender_id": "runtime-sidecar-1",
  "receiver_id": "steward-abc-456",
  "payload": {
    "trace_id": "uuid-v4-string",
    "agent_id": "urn:acgp:agent:financeops:prod:7f4c9d2a",
    "session_id": "uuid-v4-string",
    "governance_tier": "GT-2",
    "hook": "tool_call",
    "context": {},
    "reasoning": "Customer reported defective product with photographic evidence.",
    "action": { "name": "issue_refund", "parameters": { "order_id": "12345", "amount": 250.0 } },
    "meta": { "agent_label": "FinanceOps-Agent" }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "abc123..."
  }
}

10.2 EVAL (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "EVAL",
  "message_id": "01924b1a-a001-7000-8000-000000000102",
  "timestamp": "2026-01-15T09:00:01.120Z",
  "sender_id": "steward-abc-456",
  "receiver_id": "agent-xyz-123",
  "payload": {
    "trace_id": "uuid-v4-string",
    "blueprint_id": "finance_qa@2.1",
    "governance_tier": "GT-2",
    "ctq_dimensions": {
      "reasoning_quality": {
        "score": 0.9,
        "weight": 0.25,
        "status": "evaluated",
        "contributors": ["rationale_clarity"]
      },
      "knowledge_grounding": {
        "score": 0.88,
        "weight": 0.20,
        "status": "evaluated",
        "contributors": ["citation_coverage"]
      },
      "ethical_alignment": {
        "score": 0.93,
        "weight": 0.20,
        "status": "evaluated",
        "contributors": ["fairness_review"]
      },
      "tool_safety": {
        "score": 0.92,
        "weight": 0.20,
        "status": "evaluated",
        "contributors": ["permission_check"]
      },
      "context_awareness": {
        "score": 0.89,
        "weight": 0.15,
        "status": "evaluated",
        "contributors": ["situational_fit"]
      }
    },
    "ctq_score": 0.9,
    "risk_score": 0.1,
    "tripwires_triggered": [],
    "intervention": "ok",
    "flagged": false,
    "runtime_posture": "normal",
    "review_required": false,
    "trust_debt": {
      "provider_id": "acgp.core.default@1",
      "pre": 0.0,
      "delta": 0.0,
      "post": 0.0,
      "thresholds_crossed": []
    }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "bcd234..."
  }
}

10.3 INTERVENTION (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "INTERVENTION",
  "message_id": "01924b1a-a001-7000-8000-000000000103",
  "timestamp": "2026-01-15T09:00:01.180Z",
  "sender_id": "steward-abc-456",
  "receiver_id": "agent-xyz-123",
  "payload": {
    "trace_id": "uuid-v4-string",
    "decision": "ok",
    "flags": { "flagged": false, "severity": null },
    "message": "Action approved within policy bounds."
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "cde345..."
  }
}

10.4 Session Bootstrap Note

SYNC is not part of the canonical v1.0 wire surface. Use SESSION_INIT for initial bundle activation and BUNDLE_UPDATE for subsequent bundle changes.

10.5 HITL (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "HITL",
  "message_id": "01924b1a-a001-7000-8000-000000000105",
  "timestamp": "2026-01-15T09:10:10.000Z",
  "sender_id": "steward-abc-456",
  "receiver_id": "human-review-queue",
  "payload": {
    "request_id": "uuid-v4-string",
    "escalation_id": "uuid-v4-string",
    "trace_id": "uuid-v4-string",
    "deadline": "2026-01-15T09:15:10.000Z",
    "fallback_on_timeout": "block",
    "priority": "high",
    "reason": "Risk score in escalate range",
    "context": {
      "agent_id": "urn:acgp:agent:financeops:prod:7f4c9d2a",
      "agent_governance_tier": "GT-3",
      "session_id": "uuid",
      "original_trace": { },
      "evaluation": { }
    },
    "suggested_actions": ["approve", "modify_and_approve", "deny"],
    "timeout_seconds": 300
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "efg567..."
  }
}

10.6 SESSION_INIT (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "SESSION_INIT",
  "message_id": "01924b1a-a001-7000-8000-000000000001",
  "timestamp": "2026-01-15T09:00:00.000Z",
  "sender_id": "steward-abc-456",
  "receiver_id": "agent-xyz-123",
  "payload": {
    "bundle_hash": "sha256:a1b2c3d4e5f6...",
    "blueprint_signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InN0ZXdhcmQta2V5LTIwMjYtMDEifQ...",
    "effective_at": "2026-01-15T09:00:00.000Z",
    "bundle": {
      "tier0_tripwires": [
        {
          "id": "max_refund",
          "condition": "action.parameters.amount > 500",
          "severity": "critical",
          "on_fail": { "decision": "block", "reason": "Refund exceeds limit" }
        }
      ],
      "rule_based_scorers": [],
      "pattern_match_scorers": [
        {
          "id": "pii_check",
          "pattern": "\\b\\d{3}-\\d{2}-\\d{4}\\b",
          "mode": "reject_on_match"
        }
      ],
      "thresholds": {
        "ok": 0.25, "nudge": 0.40, "escalate": 0.55
      },
      "governance_tier_overrides": {},
      "fallback_on_timeout": "deny",
      "blueprint_version_hash": "sha256:a1b2c3d4e5f6..."
    }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5"
  }
}

10.7 BUNDLE_UPDATE (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "BUNDLE_UPDATE",
  "message_id": "01924b1a-b002-7000-8000-000000000002",
  "timestamp": "2026-01-15T10:30:00.000Z",
  "sender_id": "steward-abc-456",
  "receiver_id": "agent-xyz-123",
  "payload": {
    "previous_bundle_hash": "sha256:a1b2c3d4e5f6...",
    "new_bundle_hash": "sha256:f6e5d4c3b2a1...",
    "blueprint_signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6InN0ZXdhcmQta2V5LTIwMjYtMDEifQ...",
    "effective_at": "2026-01-15T10:30:00.000Z",
    "changes": {
      "tier0_tripwires": {
        "added": [],
        "removed": [],
        "modified": [
          {
            "id": "max_refund",
            "condition": "action.parameters.amount > 1000",
            "severity": "critical",
            "on_fail": { "decision": "block", "reason": "Refund exceeds updated limit" }
          }
        ]
      },
      "thresholds": {
        "ok": 0.20, "nudge": 0.35, "escalate": 0.50
      }
    }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6"
  }
}

10.8 VERSION_NEGOTIATION (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "VERSION_NEGOTIATION",
  "message_id": "01924a8c-e7f0-7000-8000-000000000000",
  "timestamp": "2026-01-15T08:59:59.000Z",
  "sender_id": "agent-xyz-123",
  "receiver_id": "steward-abc-456",
  "payload": {
    "client_versions": ["1.0.0", "1.1.0"],
    "capabilities": {
      "batch_processing": true,
      "streaming": false,
      "compression": ["gzip"],
      "governance_contracts": false,
      "intervention_execution_modes": ["passive", "active"]
    }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "..."
  }
}

10.9 VERSION_SELECTED (full envelope)

{
  "protocol": "acgp",
  "protocol_version": "1.0.0",
  "message_type": "VERSION_SELECTED",
  "message_id": "01924a8c-e7f1-7000-8000-000000000001",
  "timestamp": "2026-01-15T09:00:00.000Z",
  "sender_id": "steward-abc-456",
  "receiver_id": "agent-xyz-123",
  "payload": {
    "selected_version": "1.0.0",
    "server_capabilities": {
      "batch_processing": true,
      "max_batch_size": 100,
      "streaming": false,
      "compression": ["gzip"],
      "governance_contracts": false,
      "intervention_execution_modes": ["passive", "active"]
    }
  },
  "security": {
    "checksum_alg": "sha256",
    "checksum": "..."
  }
}

11. Extension Boundary (Runtime Governance Contracts)

governance_contract is a reserved TRACE envelope field for the Runtime Governance Contracts extension.

v1.0 core behavior:

  • Unsupported optional extension data MAY be ignored after parsing and preservation
  • Unsupported required extension data MUST trigger the extension descriptor's declared fail behavior
  • Support for governance contract semantics is extension-defined
  • When both peers support the extension, contract fields MAY be included in TRACE and EVAL messages

12. Conformance Requirements

A conformant ACGP-2 implementation MUST:

  1. Serialize all messages as JSON over HTTPS (TLS 1.3+)
  2. Encapsulate all messages in the envelope structure defined in Section 4
  3. Generate and validate SHA-256 checksums for every message using RFC 8785 canonicalization over envelope-excluding-security
  4. Parse and emit all message types in Section 4.2, including VERSION_NEGOTIATION and VERSION_SELECTED
  5. Implement version negotiation before governed message exchange
  6. Implement retry with exponential backoff (3 attempts, 100ms base, jitter)
  7. Handle duplicate message_id idempotently
  8. Return structured error responses with standard error codes
  9. Preserve canonical behavior when optional fields are absent (e.g., local_eval_results)
  10. Implement ES256 message signing for Governance Tier GT-3 and above agents
  11. Enforce canonical lowercase intervention decision values on the wire

Normative References

  • RFC 2119 — Key words for use in RFCs to Indicate Requirement Levels
  • RFC 3339 — Date and Time on the Internet: Timestamps
  • RFC 7515 — JSON Web Signature (JWS)
  • RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3
  • RFC 8785 — JSON Canonicalization Scheme (JCS)
  • ACGP-1 — Core Concepts & Terminology, v1.0, 2026
  • ACGP-2 — Messages & Wire Protocol, v1.0, 2026
  • ACGP-3 — Blueprints, Traces & Evaluation, v1.0, 2026
  • ACGP-4 — Tripwires & Safety Semantics, v1.0, 2026
  • ACGP-5 — Audit & Privacy Controls, v1.0, 2026
  • ACGP-6 — Conformance, v1.0, 2026