# Governed Crossing

**An extension to the Agent2Agent (A2A) protocol for verifiable bilateral commitments between organizations.**

| | |
|---|---|
| **Extension URI** | `https://anaxstandard.ai/ext/governed-crossing/v1` |
| **Version** | v0.4.4 DRAFT |
| **Date** | 2026-09-17 |
| **Licence** | CC BY 4.0 (`CC-BY-4.0`) for this text and its conformance vectors — attribution "ANAX Standard — anaxstandard.ai"; no licence is required to implement. Reference implementations: Apache-2.0. See §9A. |
| **Trademarks** | Governed Crossing™, Crossing Seal™, Decision Passport™ — ANAX Standard. Operating a Registration Authority, Verification Authority or Centre is a service, not licensed by this document (§9A). |
| **Publisher** | ANAX Standard — ANAX Institute |
| **Contact** | contact@viccaone.com |
| **Verification Authority** | `verify.anaxstandard.ai` |

> ## Status: Draft for community review. Feedback welcome.
>
> This is a working draft published for comment. It is not a ratified standard. Normative requirements may
> change before v1.0. Implementers are welcome, and are asked to write to the contact address above — in
> particular where a requirement is unimplementable, ambiguous, or wrong.

> ## ⚠ Nothing in this specification is implemented or enforced.
>
> v0.3 fixes a vocabulary and a wire contract. **No component enforces either.** The conformance vectors for
> the commitment-class rules and for the two methods both fail, completely, as of this publication — see
> **§10 item 6**. This is stated here, at the top, because a specification that reads as though it describes
> a running system is worse than one that says plainly that it does not.

**Note on this document.** Normative content is specification; implementation notes reflect the reference
implementation.

---

## 0. Preliminaries

### 0.1 Normative references

| Reference | Used for |
|---|---|
| **A2A** — Agent2Agent protocol specification (Linux Foundation), `a2a-protocol.org` | Core object model, `TaskState`, RPC method conventions, per-transport method naming |
| **A2A extension mechanism** — extensions documentation | `AgentExtension`, activation header, extension types, constraints |
| **AP2** — Agent Payments Protocol specification, `ap2-protocol.org` | Mandate model, open/closed variants, SD-JWT basis, signing requirements |
| **RFC 2119 / RFC 8174** | Requirement keywords |
| **RFC 8785** — JSON Canonicalization Scheme (JCS) | **Normative** canonicalization for the Terms Document (§4.2, §5.8) |
| **SD-JWT** — Selective Disclosure JWT | Agreement Mandate encoding |

**Informative.** *"Governance Gaps in Agent Interoperability Protocols: What MCP, A2A, and ACP Cannot
Express"*, Kang & Diponegoro, arXiv 2606.31498, 30 June 2026 — the analysis this specification responds to.

### 0.2 Requirement status

Normative statements that describe capability not yet present in the reference implementation are marked
**IMPLEMENTATION PENDING**. The specification defines the target; implementations catch up. Such a marker
is not an admission of weakness — it is the point of writing a specification before code.

⚠ **As of v0.3 that marker applies to the whole of §3.7 and to the class and magnitude rules of §4.1.3.**
See §10, item 11-16.

### 0.3 Positioning

> **AP2 proves the user paid. Governed Crossing proves the deal should have been made.**

A2A standardizes how agents *talk*. AP2 standardizes how agents *pay*. Neither expresses whether a
commitment was **authorized, defensible, and auditable**.

**The SWIFT analogy.** In 1973 banks already moved money by telex. SWIFT did not invent the message — it
standardized *trust in the message*, and became mandatory infrastructure for fifty years. In 2026 agents
already talk (A2A) and already pay (AP2); nobody has standardized *trust in the agreement*.

A SWIFT message is **inherently bilateral** — a sender institution and a receiver institution — and the
whole value of the standard is that both ends can trust an instruction crossing between two organizations.
Governed Crossing exists to give agent-to-agent commerce that shape.


## 1. Scope & Conformance

### 1.1 Purpose

This specification defines **Governed Crossing**, an extension to the Agent2Agent (A2A) protocol that
allows two organizations, each represented by an agent, to make a **verifiable joint commitment** —
and to prove afterwards that each side held authority to make it.

A2A standardizes how agents *talk*. AP2 standardizes how agents *pay*. Neither expresses whether a
commitment was **authorized, defensible, and auditable**. That gap is independently documented.

Governed Crossing is that layer, expressed as an A2A extension so that it composes with the ecosystem
rather than competing with it.

### 1.2 What is in scope

- Declaration and activation of the Governed Crossing extension on an A2A Agent Card.
- The **Agreement Mandate**: a signed, machine-checkable statement of authority to commit.
- The **Crossing Seal**: the sealed record of a joint commitment, and its attachment point on A2A objects.
- The **bilateral record**: two mandates, a terms hash, one joint seal, and timestamps.
- Protocol flows and failure behaviour (§5).
- Public and offline verification (§6).
- Security considerations (§7).

### 1.3 What is out of scope

- **Payment.** Governed Crossing does not move money and does not replace AP2. An agreement may reference
 a payment; the payment is AP2's.
- **Identity issuance.** This specification consumes agent and organizational identity; it does not mint it.
- **The internal governance assessment.** Whether a commitment was *defensible* is determined by the
 committing party's own governance pack. This specification carries the *identity* of that determination
 (`pack_id`, `pack_version`) and its outcome, not its reasoning.
- **Certificates.** Certificate verification is a separate ANAX surface and is
 out of scope.

### 1.4 Conformance classes

Two classes. An implementation MUST declare which it satisfies.

#### Class 1 — **Verify-Only** (minimal)

An implementation is **Governed Crossing Verify-Only capable** if it:

1. MUST be able to retrieve a Crossing Seal from `Artifact.metadata` (§4.3) without failing on unknown keys.
2. MUST be able to resolve a Crossing Seal against the Verification Authority (§2) and interpret the
 response.
3. MUST NOT represent an unsealed commitment as sealed, or a seal it has not resolved as verified.
4. MAY decline to participate in bilateral sealing.
5. SHOULD declare the extension in its Agent Card with `required: false`.

Verify-Only exists so that an agent can be a **credible counterparty in one direction** — able to check
what it is being shown — without operating a sealing infrastructure. It is the on-ramp, and it is
deliberately cheap.

#### Class 2 — **Full** (bilateral sealing)

An implementation is **Governed Crossing Full capable** if it satisfies Class 1 and additionally:

1. MUST be able to present a valid **Open Agreement Mandate** for its Principal and a **Closed Agreement
 Mandate** for each commitment it makes (§4.1).
2. MUST verify the Counterparty's mandates before committing, and MUST NOT commit if verification fails
 (§5.4).
3. MUST participate in joint sealing and MUST NOT treat a commitment as made until a Crossing Seal exists.
4. MUST refuse rather than degrade: where a seal cannot be written, the implementation MUST NOT emit the
 commitment. *(This mirrors existing ANAX behaviour:)*
5. MUST declare the extension in its Agent Card and SHOULD declare it with `required: true` for any skill
 that can produce a commitment.

⚖ **DESIGN LAW (inherited):** *the gate must be the only path out.* A Full implementation MUST
NOT expose a commitment-emitting capability that is reachable without passing the sealing path.

### 1.5 Relationship to the ANAX tier model

Inherited design law. Normative for ANAX's own implementation; informative for third parties.

| Tier | Produces a Mandate? | Produces a Crossing Seal? | Tempo |
|---|---|---|---|
| **T0** — explanation, context, guidance | No | No | Instant. Unsealed by design; nothing here is a commitment. |
| **T1** — commitments within standing authority | Yes — Closed Mandate signed by the **agent** | **Yes. MUST.** | Synchronous hold-until-sealed at business tempo (~25s), surfaced as *"verification in progress"*. |
| **T2** — novel legal obligation | Yes — Closed Mandate signed by an **authorized human** | **Yes. MUST.** | Human-gated. |

⚖ **DESIGN LAW (inherited):** *the tier decides the tempo. T0 never waits; T1 never sends
before its seal exists.* There is no third mode, and in particular no fast path for a T1 commitment judged
low-risk — that judgement is itself a T1 output.

---

## 2. Terminology

### 2.1 RFC 2119 keywords

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 RFC 2119
and RFC 8174, and appear in **bold uppercase** when used normatively. Where these words appear in lowercase
they carry their ordinary English meaning and impose no requirement.

### 2.2 Defined terms

**Governed Crossing™**
: The A2A extension defined by this specification, and by metonymy a single instance of its use: one
 bilateral commitment made under verified mandates and sealed. **This is the name used on the wire.**

**Crossing Seal™**
: The sealed, verifiable record of a Governed Crossing. A cryptographic commitment over the bilateral
 record (§4.3), written into an append-only chain and resolvable at the Verification Authority.
 **This is the name used on the wire for the sealed object.**

**Agreement Mandate**
: A signed, machine-checkable statement of authority to commit, in **Open** and **Closed** variants (§4.1).
 The wire form of the Mandate primitive: *who* holds it, *what commitment
 class* it covers, *what magnitude limit* applies, *when it expires*.

**Principal**
: The organization on whose behalf an agent acts and which bears the commitment. A Principal is an
 organization, not a natural person. The Principal issues Open Agreement Mandates. *
 differs from AP2, whose mandates originate with a natural person via a Trusted Surface.)*

**Counterparty**
: The other Principal in a Governed Crossing, and by extension its agent. The presence of a Counterparty is
 what distinguishes a Governed Crossing from today's unilateral Canal Crossing.

**Verification Authority**
: The service that resolves a Crossing Seal and answers whether it is genuine and what it commits to.
 For this specification the Verification Authority is **`verify.anaxstandard.ai`**.
 The certificate registry is a separate surface and is **NOT** a Verification Authority for
 Governed Crossing.

**Commitment Class**
: The category of obligation a commitment creates. Determines which Mandate applies and whether human
 signature is required. IMPLEMENTATION PENDING — the vocabulary is defined by the committing Principal's
 governance pack; ANAX's own vocabulary is the T0/T1/T2 tier model (§1.5).

**Magnitude Limit**
: The ceiling — monetary, temporal, or scope-based — above which a Closed Mandate may not be signed under
 standing authority. IMPLEMENTATION PENDING.

**Terms Document**
: The canonical serialization of what was agreed. Its hash is `agreement_hash` (§4.1.3). *
 ANAX MUST define this canonicalization; AP2 inherits one for free from a merchant-issued artifact and
 ANAX has no equivalent.)*

**Bilateral Record**
: The complete object sealed by a Crossing Seal: two Agreement Mandates, a terms hash, participant
 identities, and timestamps (§4.4).

### 2.3 Naming — LOCKED

*Inherited design law. The rationale below is reproduced verbatim, as required, because it is the
reason the naming is locked and will be quoted when the naming is questioned.*

> **On the wire: "Governed Crossing" and "Crossing Seal". Never "Passport" at protocol level.**

**What A2A's Secure Passport actually is.** *Measured:* a **contextual state-sharing** extension. A
Calling Agent voluntarily shares a structured subset of its context — user preferences, previously
verified identity tokens, session history — with a Called Agent, without exposing its whole internal
memory. It is a **convenience and personalisation** primitive, positioned as a middle ground between A2A's
stateless design and the practical need for shared context.

**Assessment: collision, not opportunity — at the level of the name.** The two objects are close enough to
be confused and far enough apart to be **misleading in exactly the direction ANAX exists to prevent**:

| | A2A Secure Passport | ANAX Decision Passport |
|---|---|---|
| who asserts it | **the caller, about itself** | **a third party, about the caller** |
| what it is for | personalisation | attestation |
| verifiable by | the called agent | anyone, at a public URL |

A prospect who hears "ANAX Passport" in an A2A context will read it as *"the A2A one, extended"* — i.e. as
a self-asserted claim. And A2A's is the one with the Linux Foundation and 150+ organisations behind it.
ANAX will not win that naming contest and should not enter it.

**The real opportunity, stated honestly.** The two **compose**. An A2A Secure Passport can carry, as one
of its shared context items, a **reference to a Governed Crossing seal**. That is a strong story —
*"their passport says what I claim about myself; ours says what was verified about me"* — and it is
available **precisely because** the names differ. Renaming is not a concession; it is what makes the
composition legible.

**Normative consequence.** An implementation **MUST NOT** use the term "Passport" for any object defined by
this specification, in any protocol field, URI, method name, log line, or user-facing string emitted during
a Governed Crossing. "Decision Passport" remains the correct name for the ANAX-side artifact and product at
`verify.anaxstandard.ai`, and **MAY** be used there.

---

## 3. Extension Identity

### 3.1 Extension URI

A2A identifies an extension by a **URI**. Extensions hosted by the A2A project itself use
`https://a2a-protocol.org/extensions/{name}/v1`; third parties publish under their own authority.

> **Extension URI — APPROVED (2026-08-09):**
> ```
> https://anaxstandard.ai/ext/governed-crossing/v1
> ```
> **Frozen on publication.**

The URI is the permanent identifier of the extension and is subject to the same discipline as an issued
identifier namespace:

⚖ **DESIGN LAW (inherited):**
*a namespace is FROZEN once published.* Changing this URI after any counterparty has activated it breaks
every prior activation and every stored reference. A version increment (`/v2`) is the only permitted
change, and it **MUST** be additive — `/v1` **MUST** remain resolvable.

`anaxstandard.ai` is used rather than `.com` for consistency with the Verification Authority (§2.2).

**Backlog (§11-1):** the URI **MUST** eventually serve the specification document itself. An extension URI
that dereferences to nothing is a broken promise to every implementer who follows it, and A2A's whole
discovery model assumes a reader can resolve an unfamiliar extension. Not required for this draft; required
before publication.

### 3.2 Extension type

Per A2A's four extension types:

| Type | Used by Governed Crossing | For |
|---|---|---|
| **Data-only** | **Yes** | Declaring the Principal's clearance envelope and trust basis on the Agent Card (§3.4). |
| **Profile** | **Yes** | Overlaying pre-commitment state requirements on core messages — mandates MUST be exchanged and verified before a commitment message is honoured. |
| **Method (Extended Skills)** | **Yes** | `crossing:seal` and `crossing:verify` (§3.5). |
| **State Machine** | **Yes, with a constraint** | An extension-scoped commitment state. **This is NOT a new `TaskState` value —.5.** |

Governed Crossing is therefore a **composite extension**. This is permitted; the four types are
descriptive categories, not mutually exclusive declarations [D — the extensions documentation presents them
as things an extension "can add", not as an enumeration to choose from].

### 3.3 Declaration on the Agent Card

An agent declares support by including an `AgentExtension` object in `AgentCapabilities.extensions`.

`AgentExtension` fields: **`uri`**, **`description`**,
**`required`**, **`params`**.

*(****CONFIRMED 2026-09-01.** The rendered object list in `specification.md` showed only `uri`,
`description`, `required`, while `extensions.md` documented `params` with a worked example. Checked against
the normative definition: the A2A protocol buffers definition declares `google.protobuf.Struct params = 4` on
`AgentExtension`, and A2A v0.3.0 §5.5.2.1 gives `params?: { [key: string]: any }`. `params` is normative;
this declaration stands as written and no move to a Data-only surface is needed.)*

```jsonc
{
 "uri": "https://anaxstandard.ai/ext/governed-crossing/v1",
 "description": "Bilateral commitments under verified mandates, sealed and publicly verifiable.",
 "required": true,
 "params": {
 "conformance": "full", // "verify-only" | "full"
 "verification_authority": "https://verify.anaxstandard.ai/",
 "principal": {
 "id": "urn:anax:principal:<opaque>", // stable identifier of the Principal
 "clearance_id": "<envelope id>", // IMPLEMENTATION PENDING — see §3.4
 "trust_basis": "vicca_authority_sealed", // see §3.4
 "agc_level": 3
 },
 "mandate_formats": ["sd-jwt"],
 "commitment_classes": ["<class>", "..."] // classes this agent can commit within
 }
}
```

**Normative requirements.**
- An agent that can make commitments **MUST** declare the extension.
- `params.conformance` **MUST** be present and **MUST** be one of `"verify-only"` or `"full"`.
- A Full implementation **SHOULD** declare `required: true` for skills that can produce a commitment, and
 **MUST NOT** declare `required: true` on a skill that cannot.
- An agent **MUST NOT** declare a `trust_basis` it cannot substantiate at the Verification Authority.

### 3.4 The clearance envelope, and what it maps to

`params.principal` carries the Principal's standing governance posture. Its fields map onto the existing
ANAX System Clearance Envelope.

The envelope is already an **onboarding gate** in the existing implementation: without a
clearance envelope, the onboarding gate returns a VICCA-required outcome and issues **no passport**. That gate is
inherited: **an agent without a clearance envelope MUST NOT be Full-conformant.**

`trust_basis` values are the existing evidence trust hierarchy: `self_declared`, `organisational_controls`,
`third_party_audited`, `vicca_authority_sealed`, `nca_verified`.

> **Clarification of a term the design analysis corrected.** This is an **evidence** trust hierarchy — how good the
> evidence behind the Principal's posture is. It is **not** a trust relation between two parties, and
> **MUST NOT** be interpreted as one. A Counterparty's `trust_basis` says how well-evidenced its own
> governance posture is; it says nothing about whether you should trust it
>.

### 3.5 Activation, and a security note that cannot wait for §7

Activation is per-request, via the **`A2A-Extensions`** HTTP header carrying a comma-separated list of
extension URIs. The responding agent echoes back, in the same header, the extensions it actually activated.
**Extensions default to inactive.**

```http
POST /message:send HTTP/1.1
A2A-Extensions: https://anaxstandard.ai/ext/governed-crossing/v1
```

**⚠ This is the most consequential review finding, and it refines a security assumption in the design analysis.**

A2A's `required: true` means an agent **SHOULD** reject requests from clients that have not activated a
required extension. **SHOULD, not MUST** — and the rejection is the *agent's* choice, evaluated
per-request. It follows that **"simply do not send the header" is an available downgrade path by design of
A2A**. The anti-downgrade property **cannot be inherited from the transport**; this specification must
impose it.

#### 3.5.1 The normative pair — "no seal, no deal"

Because the transport cannot enforce this, **the endpoints must.** These two requirements are the load-bearing
pair of the entire specification, and every other normative statement about downgrade derives from them:

> **OUTBOUND.** A Class 2 implementation **MUST NOT** issue a commitment without a sealed Governed
> Crossing.
>
> **INBOUND.** A Class 2 implementation **MUST reject** any inbound commitment that does not carry a valid
> Crossing Seal.

**Defense lives at the endpoints, not the transport.** The consequence is the point: an attempted downgrade
stops being a silent path and becomes a **detectable violation**. A party that omits the header, or presents
a commitment without a seal, is not quietly served a lesser service — it is refused, and the refusal is
attributable. A protocol cannot prevent a peer from behaving badly; it can guarantee that behaving badly
fails visibly.

#### 3.5.2 Supporting requirements

1. A Class 2 implementation **MUST** reject any request that would produce a commitment and that has not
 activated this extension. It **MUST NOT** fall back to an unsealed commitment. The correct response is a
 refusal, not a degraded success.
2. A Class 2 implementation **MUST** treat the absence of the extension in the *response* header as a
 failed activation, and **MUST NOT** proceed to commit.
3. An implementation **MUST NOT** infer that a commitment is governed from the presence of the header
 alone. The header proves activation was requested and acknowledged; **only a resolvable Crossing Seal
 proves the commitment was governed** (§6).
4. A refusal under §3.5.1 **MUST** be recorded by the refusing party with sufficient detail to be
 auditable. A downgrade attempt that is refused but not recorded is a detection that was thrown away.

*Full treatment, including the disclosure of the transport property that makes this necessary: §7.4.*

### 3.6 Method extensions

Two new RPC methods. A2A's **REST** naming convention is a resource with a colon-verb —
`POST /message:send`, `POST /tasks/{id}:cancel`; **the JSON-RPC and
gRPC forms differ — see the binding table below**.

| Method | Shape | Purpose |
|---|---|---|
| `crossing:seal` | see binding table below | Submit a Bilateral Record for joint sealing; returns a Crossing Seal. |
| `crossing:verify` | see binding table below | Resolve a Crossing Seal. Delegates to the Verification Authority. |

**Per-transport binding.** A2A v0.3.0 fixes extension method naming per transport in three subsections:
**§3.5.5** (Extension Method Naming) requires JSON-RPC extension methods to follow `{category}/{action}`
with a clear namespace (its own example: `myorg.extension/action`); **§3.5.3** requires REST endpoints to
use `/v1/{resource}[/{id}][:{action}]` with colon notation for non-CRUD actions; **§3.5.2** requires gRPC
methods to use PascalCase. **§3.4.1** requires functional equivalence across transports.

| Operation | JSON-RPC `method` | REST | gRPC |
|---|---|---|---|
| seal | `anaxstandard.crossing/seal` | `POST /v1/crossing:seal` | `SealCrossing` |
| verify | `anaxstandard.crossing/verify` | `POST /v1/crossing:verify` | `VerifyCrossing` |

- **T-1** `crossing:seal` / `crossing:verify` are the **canonical operation names** used throughout this
 specification; the table above is their transport binding. *(an earlier draft used `crossing/seal`, which was
 correct for JSON-RPC and lacked only the namespace — §10.)*
- **T-2** An implementation **MUST** expose the methods on every transport it declares in its Agent Card,
 with identical semantics (A2A §3.4.1).
- **T-3** The `A2A-Extensions` header (§3.5) **MUST** name the extension URI on every request to either
 method. A request without it is refused with `EXT_NOT_ACTIVATED` — **HTTP 428 Precondition Required**, a
 missing precondition rather than a denied right (§3.7.4). This is the endpoint-side half of
 "no seal, no deal" (§3.5.1).
- **T-4** Relationship to `message/send`: the core methods carry the negotiation (mandate exchange, Terms
 Document) and receive the sealed Artifact. `crossing:seal` is the **commitment step**, invoked once per
 crossing after both Closed Mandates are verified (§5.4), by the initiator against the responder's
 endpoint; the responder returns the Crossing Seal and the initiator attaches it to the agreement Artifact
 (§4.3.1) in the terminal `message/send` / `message/stream` exchange. `crossing:verify` is exposed by the
 Verification Authority and **MAY** be proxied by any agent; its result is a projection, never an
 authority.

**The wire contract for both methods — params, result, errors, determinism — is §3.7.**

### 3.7 Wire contract

Merged from Addendum A-3, which closed §11-6. §3.6 names the methods and binds them to transports; this
section is what a caller and a responder must agree on to interoperate.

#### 3.7.1 `crossing:seal` — params

All fields REQUIRED unless marked.

| Field | Type | Meaning |
|---|---|---|
| `record` | object | The Bilateral Record (§4.4) **with chain position excluded** (`prev_hash`, `chain_seq` omitted) — the party-independent input to `joint_seal`. |
| `initiator_closed_mandate` | string (SD-JWT) | The initiator's Closed Mandate, by value — the responder verifies it (§5.4). |
| `initiator_anchor_intent` | object `{prev_hash, chain_seq}` | The initiator's own chain position, so the responder can check it is well-formed; **NOT** sealed into `joint_seal`. |
| `idempotency_key` | string | **MUST** equal `record.crossing_id`. Present explicitly so transports without a body-level convention still carry it. |

**Responder behaviour (normative).** Verify the initiator's Closed Mandate and its own (§5.4, all checks);
recompute `agreement_hash` from the Terms Document it holds (§4.2) and require equality with
`record.agreement_hash`; check the class and magnitude rules L-1, M-2, M-3 and M-4 (§4.1.3) against both
mandates; compute `joint_seal` (§4.4 req 4); write its own `anchor` into its chain; return the result.
**Idempotent on `crossing_id`** (§5.6 req 3): a repeat returns the existing result and **MUST NOT** write a
second anchor.

#### 3.7.2 `crossing:seal` — result

```jsonc
{
 "crossing_id": "<uuid>",
 "joint_seal": "<sha256 hex>",
 "seal_id": "canal-<ts>-<rand>", // the responder's public identifier for the seal
 "sealed_at": "<RFC3339>",
 "responder_anchor": { "prev_hash": "<sha256|null>", "chain_seq": 42 },
 "verify_url": "https://verify.anaxstandard.ai/?id=canal-<ts>-<rand>",
 "artifact_block": { /* the exact §4.3.2 block, ready for Artifact.metadata[uri] */ }
}
```

**Effector consumption — normative (v0.4 note, 2026-09-02).** An *effector* is a party that performs
`crossing:seal` on behalf of an agent whose Mandate it did not issue — a gateway, a broker, a second
implementer's seal endpoint. When an effector consumes a unit of an agent's `magnitude_limit` at the
issuing Registration Authority, the following are **REQUIRED**:

1. **Consumption is by possession, not by reference.** The effector MUST present the exact Mandate token
 the agent presented to it. The RA MUST locate the Mandate by the digest of those bytes (`token_sha256`,
 unique at issuance) and MUST NOT accept an identifier in its place. Knowledge of a Mandate's id is not
 possession of the Mandate; a tampered token MUST be indistinguishable from one never issued.
2. **An effector spends only what no issuer may issue for.** The RA MUST refuse, as
 `SERVICE_HELD_MANDATE`, any consumption by an effector of a Mandate whose subject is one that any
 registered issuer is permitted to issue for. Mandates held by services in their own right — a
 monitoring service's read grant, a provisioning service's issuance grant — are never spendable by an
 effector, **even when the effector holds the token**. This is the lock for the day a service-held
 token leaks: without it, a compromised or careless effector can drain a service's authority from
 outside.
3. **Roles do not blend.** An effector MUST NOT be able to issue, and an issuer MUST NOT be able to
 consume by possession; a call on the wrong route is refused as `ROLE_MISMATCH`. A party configured
 with both capabilities is a party that governs other agents' authority and quietly holds its own.

⚠ **A second implementer building an effector MUST honour rule 2 or it builds an effector that can
drain service Mandates.** The rule is stated here, and not only in the reference implementation's
code, for exactly that reason. Conformance: the acceptance test presents a service-held token from the
effector and requires `SERVICE_HELD_MANDATE` with nothing consumed (reference-implementation acceptance test).

#### 3.7.3 `crossing:verify` — params and result

> **v0.4 (adopted 2026-09-06) — where the two methods live, and under which URI.** `crossing:seal` and
> `crossing:verify` are methods **of this extension** — `https://anaxstandard.ai/ext/governed-crossing/v1` —
> and no separate URI exists or is declared for them; the `A2A-Extensions` header names that one URI for both.
> `crossing:seal` is an **act** and is served by the responder (Centre-001). `crossing:verify` is a
> **resolution** and is served by the **Verification Authority** (§3.1, `verify.anaxstandard.ai`) as one more
> resolver branch of the single public verify surface — the single-portal rule: one portal resolves every ANAX
> identifier, structurally, without login. A responder MAY additionally answer `crossing:verify` for its own
> seals; the Verification Authority's answer is the public one and the conformance target (WC-5, WC-6).

**params:** exactly one of `seal_id` (string) or `crossing_id` (uuid). Optional `record` (object): if
supplied, the verifier additionally checks §6.2 item 2 (recomputed seal equals stored seal).

**result:** the public projection — the §4.3.2 block fields `crossing_state`, `seal_id`, `seal`,
`prev_hash`, `chain_seq`, `is_genesis`, `seal_version`, `pack_id`, `pack_version`, `outcome`, `sealed_at`,
`verify_url`, plus `verified_by` (the VA identifier, e.g. `VA-001`) and `checks`: an object with one boolean
per §6.2 check (`resolves`, `seal_matches` — null if no record supplied — `chain_consistent`,
`basis_present`, `not_superseded`). **`clearance_id` MUST NOT appear** (§4.3.2). A non-resolving identifier
returns a result with `resolves:false` and every other check `null` — **a verdict, not an error** (§6.2:
a seal that does not resolve is a commitment that was not made).

`crossing:verify` is **public**: no activation header, no authentication. It is rate-limited and cacheable;
a sealed record is immutable, so a `resolves:true` result **MAY** be cached for the seal's lifetime.

#### 3.7.4 Error vocabulary

Errors are JSON-RPC error objects (A2A §6.12) with `code` in the range **−40000 to −40099** — outside the
JSON-RPC reserved range −32768…−32000 that A2A's own codes occupy — and `data.error` carrying the **name**
below. **Implementers switch on the name; the number exists for JSON-RPC compliance.** REST maps to the HTTP
status shown; gRPC to the equivalent status per A2A §3.2.2.

**The `Spec failure path` column is the point of this table.** A name without the rule that produces it is a
string an implementer has to guess at; every error here is traceable to the requirement it enforces.

| Name | Code | HTTP | Spec failure path | Raised by |
|---|---|---|---|---|
| `EXT_NOT_ACTIVATED` | −40001 | 428 | §3.5.2 req 1 | seal |
| `MANDATE_INVALID` | −40010 | 401 | §5.4 (signature / structure) | seal |
| `MANDATE_EXPIRED` | −40011 | 401 | F1 | seal |
| `MANDATE_AUDIENCE` | −40012 | 403 | §5.4 `aud` | seal |
| `MANDATE_NONCE_REPLAY` | −40013 | 409 | §7.1 | seal |
| `MANDATE_REVOKED` | −40014 | 401 | §5.4 revocation at commit (the Mandate Object Specification, forthcoming, §2.4) | seal |
| `AGREEMENT_HASH_MISMATCH` | −40020 | 422 | §4.2 | seal |
| `CLASS_EXCEEDED` | −40030 | 403 | §4.1.3 L-1 (CM-2) | seal |
| `MAGNITUDE_EXHAUSTED` | −40031 | 403 | §4.1.3 M-4 (CM-1) | seal |
| `NARROWING_VIOLATION` | −40032 | 403 | §4.1.3 L-2 / M-3 (CM-3) | seal |
| `CURRENCY_MISMATCH` | −40033 | 422 | §4.1.3 M-2 (CM-4) | seal |
| `MALFORMED_MANDATE` | −40034 | 400 | §4.1.3 L-5 / M-2 (CM-5, CM-6) | seal |
| `MAGNITUDE_MISMATCH` | −40035 | 403 | §5.4 magnitude equality — the record's `magnitude_asserted` must equal the Closed Mandate's asserted magnitude; two sealed documents disagreeing on the committed amount are refused, not sealed | seal |
| `COUNTERPARTY_NOT_PERMITTED` | −40040 | 403 | §4.1.3 `permitted_counterparties` | seal |
| `ROLE_MISMATCH` | −40041 | 403 | §3.7.2 effector rule 3 | seal (RA) |
| `SERVICE_HELD_MANDATE` | −40042 | 403 | §3.7.2 effector rule 2 (acceptance test) | seal (RA) |
| `MANDATE_PARTY_MISMATCH` | −40043 | 403 | §4.4 req 7 / §5.4 check 9 (v0.4) | seal |
| `CHAIN_POSITION_UNAVAILABLE` | −40050 | 503 | §4.4 req 5 / F6 | seal |
| `SEAL_MISMATCH` | −40051 | 409 | §4.4 req 6 | initiator-side (reported, not returned) |
| `RECORD_MALFORMED` | −40060 | 400 | §4.4 reqs 1–3 | seal, verify |
| `VERIFY_PARAMS` | −40070 | 400 | §3.7.3 (neither/both identifiers) | verify |
| `RATE_LIMITED` | −40090 | 429 | §3.7.3 | verify |

- **E-1** Every refusal **MUST** be recorded by the refusing party with the name, the `crossing_id` and the
 timestamp (§3.5.2 req 4 — a refusal not recorded is a detection thrown away).
- **E-2** `crossing:verify` **never** returns an error for an unknown identifier (§3.7.3); errors are for
 malformed calls and rate limiting only.
- **E-3** Names are stable across versions; new names **MAY** be added, none removed or renamed within `/v1`.

#### 3.7.5 Determinism

Both methods are deterministic for a given input and store state: two verifiers with the same seal store
return the same `crossing:verify` result; two responders with the same mandates and record compute the same
`joint_seal` (§4.2 fixes the bytes). This is truth-gate Π2 stated at the wire.

#### 3.7.6 Versioning

Method-level evolution is governed by the extension URI (§3.1): additive changes — new optional params, new
result fields, new error names — stay within `/v1`; any incompatible change is `/v2` with `/v1` remaining
resolvable. Implementations **MUST** ignore unknown result fields.

#### 3.7.7 Conformance vectors — series WC-

- **WC-1** seal without activation header → `EXT_NOT_ACTIVATED`, nothing written, refusal recorded.
- **WC-2** seal with valid mandates and record → result with `joint_seal` equal to the initiator's own computation.
- **WC-3** repeat of WC-2 with the same `crossing_id` → byte-identical result, anchor count unchanged.
- **WC-4** seal with `record.agreement_hash` ≠ recomputed → `AGREEMENT_HASH_MISMATCH`.
- **WC-5** verify by `seal_id` of WC-2 → `resolves:true`, all checks true, no `clearance_id` key in the result.
- **WC-6** verify unknown `seal_id` → `resolves:false`, other checks null, no error.
- **WC-7** each class/magnitude refusal (§4.1.3 CM-1…CM-6) surfaces as its named error in §3.7.4.
- **WC-8** *(v0.4)* a valid Closed Mandate presented in a party slot whose `agent_id` is a different subject →
 `MANDATE_PARTY_MISMATCH`, nothing written, refusal recorded.
- **WC-8b** *(v0.4)* `record.parties[initiator].closed_mandate_hash` ≠ `SHA-256(initiator_closed_mandate)` →
 `MANDATE_PARTY_MISMATCH`, nothing written, refusal recorded.
- **WC-9** *(v0.4, §4.4.2)* two seals by the same responder with two different counterparties → two `chain_id`s,
 both `chain_seq: 0`, both `prev_hash: null` (two geneses); a third seal with the first counterparty → that
 chain's `chain_seq: 1` with `prev_hash` = its own genesis anchor and no reference to the other chain.
- **WC-10** *(v0.4.1, §5.4)* a Closed Mandate valid at consumption but revoked before the commit → the commit
 re-reads status and refuses `MANDATE_REVOKED`; nothing sealed, no anchor, the refusal recorded with
 `initiator_spent: true, responder_spent: true`.
- **WC-11** *(v0.4.2, §5.4)* a record whose `magnitude_asserted` differs from a party's Closed Mandate's asserted
 magnitude, both within the Mandate's limit → `MAGNITUDE_MISMATCH`, nothing written, nothing consumed,
 refusal recorded.

⚠ **WC-1…WC-7 all fail as of 2026-09-01. Nothing implements either method — see §11-16.**

---

## 4. Data Model

### 4.1 The Agreement Mandate

#### 4.1.1 Format and basis

The Agreement Mandate **MUST** be an **SD-JWT**, following AP2's mandate pattern.

**Normative:** implementations **MUST** use a non-deterministic signature scheme (ECDSA over P-256 or
stronger). Ed25519 and other deterministic schemes **MUST NOT** be used. *(This requirement is inherited
from AP2 rather than invented; its stated purpose there is to defeat rainbow-table attacks against SD-JWT
disclosure salts.)*

W3C Verifiable Credentials **MUST NOT** be assumed. *(v0.1 of the design analysis described AP2 as three W3C VC
mandates; that was the September-2025 launch model and is superseded*

#### 4.1.2 Open and Closed variants

Adopted from AP2:

| | AP2 | Governed Crossing |
|---|---|---|
| **Open mandate** | Created before a specific transaction. Carries the user's authorization and **constraints on agent behaviour**. Signed by the **Trusted Surface** on behalf of the user. Agent's public key appears as `cnf`. | Created before any specific agreement. Carries the Principal's authorization and **constraints on agent behaviour**: commitment classes, magnitude limits, permitted counterparties, expiry. Signed by the **Principal**. Agent's public key appears as `cnf`. |
| **Closed mandate** | Transaction-specific. Signed by the **user** (human-present) or by the **shopping agent** (autonomous), validated against the open mandate's constraints. | Agreement-specific. Signed by an **authorized human** (**T2**) or by the **agent** (**T1**) under the standing Open Mandate, validated against its constraints. |
| **Verification** | Verifiers evaluate whether a closed mandate satisfies all constraints from its corresponding open mandate before processing. | Identical. A Counterparty **MUST** evaluate the Closed Mandate against the Open Mandate before committing. |

> **A structural alignment worth recording.** AP2's **human-present / human-not-present** distinction is
> isomorphic to ANAX's **T2 / T1** tiers. A human-present closed mandate is a human committing — T2. An
> autonomous closed mandate is an agent committing within constraints its Principal signed — T1. T0 produces
> no mandate at all, because T0 makes no commitment.
>
> This is not a coincidence to be noted in passing; it means the tier model has an **existing, deployed
> cryptographic expression** rather than needing one invented. It should be stated plainly in any external
> presentation of the standard.

#### 4.1.3 Claims

Claims marked **[AP2]** are used with AP2's semantics. Claims marked **[NEW]** are additions specific to
agreements and have no AP2 equivalent.

| Claim | Variant | Source | Meaning |
|---|---|---|---|
| `vct` | both | [AP2] | Schema version. `mandate.agreement.open.1` \| `mandate.agreement.closed.1` |
| `iss` | both | [AP2] | Issuer. Open: the Principal. Closed: the human or agent signing. |
| `sub` | both | [NEW] | The agent the mandate authorizes. |
| `aud` | both | [AP2] | **Open:** `urn:anax:va:001` — the Verification Authority, as the Registration Authority issues it and as the Mandate primitive's verifier enforces it (`audience`). An Open's counterparty binding is **`permitted_counterparties`** (§5.2 item 5), never `aud`. **Closed:** the Counterparty — the party that will verify and act on it (§5.4 check 7). *(v0.4 — reconciles the two conventions; the earlier wording "the Counterparty, or a wildcard for an unbounded Open" described the Closed and was read against the Open.)* |
| `cnf` | open | [AP2] | The authorized agent's public key. **REQUIRED** on an Open Mandate that permits autonomous (T1) closing. |
| `exp` | both | [AP2] | Expiry. **REQUIRED on both variants.** See below. |
| `iat` | both | [AP2] | Issued at. |
| `nonce` | closed | [AP2] | Replay resistance. |
| `sd_hash` | both | [AP2] | SD-JWT disclosure binding. |
| **`commitment_class`** | both | [NEW] | Open: the **highest** class permitted (L-1 — actions of class ≤ this clear). Closed: the single class asserted. **Ladder below.** |
| **`commitment_act`** | both | [NEW] | *What act* is committed, as distinct from how much is at stake. String; vocabulary is per profile/domain and is **not** fixed by this specification. |
| **`magnitude_limit`** | open | [NEW] | The ceiling. **Non-negative integer; unit fixed by class — below.** |
| **`magnitude_asserted`** | closed | [NEW] | The magnitude of *this* commitment — integer, same unit as the class (§4.1.3). **MUST** satisfy `magnitude_limit`. |
| **`permitted_counterparties`** | open | [NEW] | Allowlist of Principal identifiers, or an explicit wildcard. |
| **`agreement_hash`** | closed | [NEW] | Hash of the canonical Terms Document. AP2's `checkout_hash` analogue — but see §5.8. |
| **`open_mandate_hash`** | closed | [NEW] | Binds this Closed Mandate to the Open Mandate it was issued under. |
| **`governance_basis`** | closed | [NEW] | `{pack_id, pack_version}` — which governance rules were applied. |
| **`crossing_id`** | closed | [NEW] | AP2's `transaction_id` analogue. Resolves on the Canal chain. |
| **`signer_role`** | closed | [NEW] | `human` \| `agent`. Distinguishes T2 from T1 at verification time. |

**Normative requirements on claims.**

- `exp` **MUST** be present on both variants. **A mandate that cannot lapse is not a mandate.** *(This is the
 field the design analysis found absent from every existing ANAX authorization surface:
 neither neither the admin session store nor the API-key store carries an expiry.)*
- An Open Mandate that omits `cnf` **MUST NOT** be used to close a mandate autonomously; only a
 `signer_role: human` Closed Mandate may be issued under it. *(This is how a Principal restricts an agent
 to T2 for a class of commitments.)*
- `permitted_counterparties` **MUST** be present. An unbounded Open Mandate **MUST** state that
 explicitly rather than by omission. ⚖ **Fail-closed on scope** — inherited from existing ANAX behaviour. Silence is refusal, never permission.
- `magnitude_asserted` **MUST** satisfy `magnitude_limit`. A verifier that cannot evaluate the comparison
 **MUST** treat it as failed.

**The commitment class ladder.** `commitment_class` is one of five fixed values, ordered. Higher classes
commit more; a Mandate's class is the **highest** class of action it authorises.

| Order | Value | Meaning | Examples |
|---|---|---|---|
| 1 | `observe` | No effect outside the agent. Read, recommend, draft. | reading a record; producing a recommendation |
| 2 | `reversible` | An effect the Principal can undo unilaterally, without a counterparty's consent, within the Mandate's `exp`. | placing a hold; creating a draft record another system can delete; sending an internal message |
| 3 | `irreversible` | An effect that cannot be undone unilaterally, but carries no financial or legal commitment. | sending an external email; publishing; provisioning access; deleting data |
| 4 | `financial` | Moves or commits value. | payment, transfer, order, refund |
| 5 | `binding` | Creates a legal obligation for the Principal. | signing, accepting terms, submitting a regulatory filing |

- **L-1** A Mandate with class *k* authorises actions of class ≤ *k*. An effector **MUST** refuse an action
 whose class exceeds the Mandate's.
- **L-2** Narrowing-only delegation applies to class: a delegated Mandate's class **MUST** be ≤ its parent's.
- **L-3** The class is chosen by the **issuer**, not inferred by the agent. An effector that cannot
 determine an action's class **MUST** treat it as the highest class it might be (fail-closed).
- **L-4** `observe` requires no Mandate under T0 (see Profile C0); it is in the ladder so that delegation and
 comparison are total.
- **L-5** Values are lowercase ASCII; unknown values are malformed and **MUST** be rejected.

**`commitment_act` is a separate axis.** `commitment_class` answers *how much is at stake*; it does not
answer *what act is being committed*, and the two are orthogonal rather than two spellings of one thing.
L-5 governs `commitment_class` alone and does not make an unrecognised `commitment_act` malformed; the act is
bounded by the profile's act vocabulary at the seal (§5.4 check 9, v0.4.4), not by L-5.

**`magnitude_limit` — a non-negative integer whose unit is fixed by the class:**

| Class | Unit of `magnitude_limit` | Example |
|---|---|---|
| `observe` | count of read operations (0 = unlimited within `exp`) | 0 |
| `reversible` | count of actions | 50 |
| `irreversible` | count of actions | 5 |
| `financial` | minor currency units (cents/pence), with `currency` REQUIRED alongside (ISO 4217) | 250000 + `"currency":"EUR"` = €2,500.00 |
| `binding` | count of instruments (1 = exactly one signature/filing) | 1 |

- **M-1** Integer only (consistent with the Terms Document constraint R-2, §4.2). No fractions, no strings.
- **M-2** For `financial`, `currency` is a required sibling field; a `financial` Mandate without it is
 malformed. A Mandate **MUST NOT** mix currencies; delegation across currencies is a new issuance, not a
 narrowing.
- **M-3** Narrowing-only: a delegated Mandate's magnitude **MUST** be ≤ its parent's (same class, same
 currency where applicable). A class narrowing (e.g. `financial` → `irreversible`) resets the unit; the
 delegated magnitude is then bounded by L-2 only.
- **M-4** Cumulative: `magnitude_limit` bounds the **total** committed under the Mandate over its lifetime,
 not per action. Effectors **MUST** track consumption per Mandate; a crossing that would exceed the
 remaining magnitude is refused, not partially executed.
- **M-4a** *(v0.4, adopted 2026-09-06)* **The draw is booked when the Closed Mandate is issued.** Issuing a
 Closed Mandate with `magnitude_limit = d` under an Open Mandate O consumes `d` of O's remaining magnitude **at
 issuance**. The issuer **MUST** refuse a Closed whose draw exceeds O's remaining (`MAGNITUDE_EXHAUSTED` at
 issuance). The sum of the draws of every Closed ever issued under O therefore never exceeds O's `magnitude_limit`:
 M-4 holds by construction, and **a seal does not touch O**. The Open is the per-agent envelope; the Closed is the
 per-agreement permission.
- **M-4b** *(v0.4)* **A Closed Mandate is spent once, whole, by possession.** A `crossing:seal` consumes the
 initiator's Closed and the responder's Closed, each in full (`consumed:= magnitude_limit`), each by presentation of
 its exact bytes to the issuing authority (§3.7.2 effector rule). A Closed already consumed is refused
 `MAGNITUDE_EXHAUSTED`. A Closed that expires unsealed leaves its draw booked against O; **no release exists at v1**
 (§11-17) and O's own `exp` bounds the loss. *(The earlier reading in which the seal debits the Open is withdrawn: it made every seal a remote read-modify-write of the envelope and left the sum of
 outstanding draws unbounded between issuance and seal.)*
- **M-5** `0` means "no actions of this class" for classes 2–5, and "unlimited reads within `exp`" for
 `observe` only.

⚠ **A Mandate is permission to ATTEMPT, not a guarantee of completion — note for v0.4.** Consumption is
recorded BEFORE the act it authorises, not after, and a unit spent on an attempt that then fails downstream
is spent. This is deliberate and it is the only order that makes `magnitude_limit` a control: a counter
decremented after the act has already happened is an audit trail, not a brake, and an effector that
consumed on success alone would grant itself unlimited retries of an act it was authorised to perform a
bounded number of times. The cost is that an attempt lost to an unrelated outage still counts against the
grant. Implementations SHOULD emit a distinguishable event when this occurs — the reference deployment logs
`mandate_unit_burned_on_503` — so the loss is measured rather than silently absorbed into the count.

**Conformance vectors — series CM-.**

- **CM-1** Mandate class `irreversible`, magnitude 5: five irreversible actions clear; the sixth is refused with reason `magnitude_exhausted`.
- **CM-2** Mandate class `reversible`: an `irreversible` action is refused with reason `class_exceeded`.
- **CM-3** Delegation `financial`/250000 EUR → child `financial`/300000 EUR is rejected at issuance (`narrowing_violation`); child `financial`/100000 EUR is accepted.
- **CM-4** Delegation `financial`/250000 EUR → child `financial`/100000 GBP is rejected (`currency_mismatch`).
- **CM-5** A Mandate with class `finance` (unknown value) is rejected as malformed.
- **CM-6** A `financial` Mandate without `currency` is rejected as malformed.

⚠ **v0.4 note (2026-09-02):** measured against the components that hold each rule — the Registration Authority for CM-3…CM-6 and the responder's crossing-path seam for CM-1/CM-2 — **CM-1, CM-2, CM-3, CM-5 pass; CM-4 and CM-6 are conditional** on M-TRANSACT being activated, because they exercise `financial`, which the operator's charter makes unreachable by design; CM-3 is restated at `irreversible` (see the A-2 addendum's v0.4 note). The sentence this replaces — *all fail as of 2026-09-01* — was true of the harness that day and is retained in the change log. §11-16 still stands for the WIRE contract: WC-1…WC-7 remain unimplemented.

**Relationship to Blast Radius.** Blast Radius (the Authority Doctrine, forthcoming, §2.2) aggregates `magnitude_limit`
per class over reachable effectors. This vocabulary makes that aggregation well-defined: sums are within a
class, and within a currency for `financial`; the ladder gives the weighting order. *(OQ-A1 answered: fixed
ladder. A weight table for a single scalar exposure figure is deferred to Authority Doctrine v0.2 — this
specification fixes vocabulary, not weights.)*

#### 4.1.4 THE MANDATE EXISTS — note for v0.4

⚠ **This section said "the Mandate does not exist" until 2026-09-01. It does now.** The Mandate primitive was built
and exercised on that date, and the claim is recorded here with what was measured rather than what was
intended:

- **Issued.** A Registration Authority mints ES256 SD-JWT Mandates under a P-256 key whose
 public half is published as a JWKS. The first Mandate was issued 2026-09-01.
- **Verified by a third party, offline.** The token verifies against the published JWKS alone — no call to
 ANAX, no shared secret. The class ceiling holds in the verifier: an `M-READ` Mandate authorises `observe`
 and refuses `reversible`. **This is the property the row below says the prior half-implementations could
 not have**, and it is the reason the signed open/closed pattern was adopted.
- **Bounded, and the bound bites.** `magnitude_limit` is enforced atomically at the row (`SELECT … FOR
 UPDATE`), and a first effector consults it before acting: over 40 authenticated reads on a governed route,
 **27 were authorised and 13 refused**, with the refusals carrying `magnitude_exhausted` and the read
 demonstrably not performed.

⚠ **WHAT THIS DOES NOT SAY.** One effector, on one route, in one service. §4.1.3's rules still have no
general enforcing component: **CM-1…CM-6 remain 6 of 6 failing** and §11-16 stands. *(v0.4, 2026-09-09: both counts have since moved — CM-1…CM-6 are 4 pass / 2 conditional / 0 fail, and the §3.7 methods are implemented and live. The sentence is retained as the record of its date; the current measurement is the v0.4 note in §11-16, which also lists the three things still not enforced.)* Delegation narrowing is
enforced at the issuer only. **A Mandate existing is not the same as this specification being implemented**,
and the distance between those two statements is exactly what §11 lists.

**The prior state, retained** — what existed before the Mandate primitive, and why neither half was a Mandate:

| Field | Nearest existing thing | Why it is not a Mandate |
|---|---|---|
| principal | an admin session record / an API-key record | a person's email, or a bearer secret |
| scope | the API key's scope list | present on the machine side only |
| magnitude | tier constants | hardcoded constants, not issued authority |
| expiry | — | absent everywhere |
| commitment class | — | absent everywhere in code. The **vocabulary** is now fixed (§4.1.3) and **nothing enforces it** (§11-16) |
| verifiability | — | **both are bearer secrets. A bearer secret proves possession, not authority, and cannot be shown to a counterparty.** |

That last row is why AP2's signed open/closed pattern is adopted rather than extended from what exists.

#### 4.1.5 Who signs for an organization — answered once

AP2's mandates originate with a **natural person**, signed by a Trusted Surface on their behalf. A
Governed Crossing Principal is an **organization**, and a T1 commitment may involve no human at all. The
question *"who may sign an Open Agreement Mandate for an organization?"* therefore has no AP2 answer and
must be ANAX's.

> **It is answered once, by the Mandate primitive** — **and the same answer serves
> the question of who may bind the organization**.

This is not a coincidence to be tidied away; it is the reason the design analysis names the Mandate as a *primitive*
rather than a protocol field. The same object answers three questions that look separate:

| Question | Asked by |
|---|---|
| What may this agent commit to, and up to what magnitude? | Tiered autonomy, the design analysis |
| How does a counterparty verify that authority? | This specification, §4.1 |
| Who may bind the company — for humans and agents alike? | the organizational control-map question |

**Normative consequence for this specification:** the identity and authority of an Open Mandate's `iss`
**MUST** be resolvable to the Principal by the Counterparty, and an implementation **MUST NOT** accept an
Open Mandate whose issuer it cannot resolve to the claimed Principal (§5.3, failure path
*counterparty unverifiable*). **How** that resolution works — a delegation chain, a registry, a signed
Agent Card lineage — is the Mandate primitive's design and is IMPLEMENTATION PENDING there, not here.
This specification states the requirement and consumes the answer; it does not fork it. Forking it is
precisely how one mandate model becomes two, which is the state the design analysis found and is closing.

### 4.2 Terms Document and `agreement_hash`

**ADOPTED 2026-09-01 — RFC 8785 (JCS). The adoption gate is passed; see §5.8 for how.**

AP2's `checkout_hash` binds a mandate to a **merchant-issued Checkout JWT** — a third artifact, produced by
one party, with a canonical serialization the protocol gets for free. **A bilateral agreement has no
such artifact.** The Terms Document is jointly constructed, and if the two parties canonicalize it
differently they will compute different hashes and the crossing will fail — or worse, appear to succeed
against different documents.

**Normative requirements:**

1. `agreement_hash` **MUST** be computed as **`SHA-256( JCS(terms_document) )`**, where **JCS** is the JSON
 Canonicalization Scheme of **RFC 8785**, applied to the Terms Document as a JSON value, producing a
 UTF-8 byte sequence. The digest is rendered as 64 lowercase hexadecimal characters.
2. Both parties **MUST** compute it independently and **MUST** compare before sealing. A mismatch
 **MUST** abort the crossing; implementations **MUST NOT** proceed on either party's value.
3. Implementations **MUST** use RFC 8785 as published; this specification does not restate it.

**Constraints on Terms Documents**, so canonicalisation is unambiguous:

- **R-1** A Terms Document is a JSON object at the top level.
- **R-2** Numbers **MUST** be integers within the safe range (|n| ≤ 2^53−1). Non-integer numbers are
 prohibited; monetary magnitudes are expressed in minor units as integers. *(RFC 8785 number
 serialisation is well-defined for IEEE-754 doubles, but excluding fractions removes an entire class of
 cross-language surprises at no cost to the model.)*
- **R-3** Keys **MUST** be unique within an object; a document with duplicate keys is malformed and
 **MUST** be rejected before hashing.
- **R-4** Array order is significant and is part of the hash. Two documents whose `parties` arrays differ
 only in order are different documents.
- **R-5** The document **MUST** carry `terms_version` (string). Implementations reject documents without it.

**Conformance vectors — series TD-.** TD-1 minimal; TD-2 the same document with keys shuffled and
whitespace added (**MUST** equal TD-1); TD-3 nested object with a non-ASCII string, emitted as UTF-8 rather
than `\u` escapes; TD-4 array order significant (**MUST** differ from TD-1); TD-5 booleans and null. An
implementation claiming conformance **MUST** reproduce all five byte-for-byte.

JCS is chosen over an ANAX-internal utility for one reason that outweighs familiarity: a bilateral hash must
be computable by an implementer who has never seen ANAX code, from a published standard, in the language of
their choice.

the existing single-party serialiser is noted as the **current single-party
utility, not the answer.** It has the right instinct — deterministic key ordering, with an explicit
`?? null` discipline so an absent key and a null key stay distinguishable — but it is one implementation in
one repository with no published test vectors, and it was written for a basis constructed by one party.

⚖ **Adoption gate — PASSED 2026-08-31.** The gate was: published test vectors, and two independent
implementations producing byte-identical hashes over them. Both halves are met; §5.8 records exactly how,
so a reader can check the claim rather than take it. Requirement 2 — both parties compute independently,
mismatch **MUST** abort before sealing — stands regardless, and is what protects the crossing when an
implementation is wrong.

### 4.3 The Crossing Seal, and where it attaches

#### 4.3.1 Attachment point

**The Crossing Seal attaches to `Artifact.metadata`**, on the Artifact representing the agreement, and is
echoed into `Task.metadata` on the terminal Task.`Task`, `Message` and `Artifact` each carry a `metadata` field, typed as a map of string to JSON values.A2A's extension constraints are explicit: an extension **may not change the definition of core data
structures** and **may not add values to enum types**; *"custom attributes belong in the metadata map
present on core data structures"*, and the Timestamp extension's documented example places its data on
`Message` and `Artifact`.

**Why the Artifact and not the Message**: Artifacts are the durable outputs A2A expects to be retained
and referenced; a Message is transient. A seal that lives only on a transient object cannot serve
post-hoc verification, which is the entire purpose (§6).

`Message` and `Artifact` additionally carry an `extensions` field. The extensions
documentation does not describe its relationship to `metadata`. The division is that `extensions` declares *which* extension URIs apply to the object and `metadata`
carries the *data*. **CONFIRMED 2026-09-01 against the normative A2A definition**:
the A2A protocol buffers definition declares `repeated string extensions = 7` on `Message` ("the URIs of extensions
that are present or contributed to this Message") and `repeated string extensions = 6` on `Artifact`
("…to this Artifact"), and both objects also carry `metadata` ("optional metadata for extensions; the key is
an extension-specific identifier"). A2A v0.3.0 §6.4 and §6.7 give `extensions?: string[]` on both. The
division above is the A2A design, not an inference. This specification populates both.

#### 4.3.2 Structure

```jsonc
Artifact.extensions = ["https://anaxstandard.ai/ext/governed-crossing/v1"]

Artifact.metadata["https://anaxstandard.ai/ext/governed-crossing/v1"] = {
 "crossing_state": "committed", // extension-scoped. NOT a TaskState — see §4.5
 "seal_id": "canal-<ts>-<rand>",
 "seal": "<sha256 hex>", // over the Bilateral Record, §4.4
 "prev_hash": "<sha256 hex | null>",
 "chain_seq": 42,
 "is_genesis": false,
 "seal_version": 3, //
 "pack_id": "<pack>", // governance basis of the sealing party
 "pack_version": "1.2.0",
 "outcome": "CLEARED", // the outcome vocabulary
 "sealed_at": "<RFC3339>",
 "verify_url": "https://verify.anaxstandard.ai/?id=canal-<ts>-<rand>"
}
```

**Every field in that block already exists in the current implementation**. **The projection an A2A counterparty needs is the projection
`GET /canal/verify/:seal_id` already computes** — including its deliberate stripping of `clearance_id`,
the envelope access key, while retaining `chain_seq`, `is_genesis` and `prev_hash` as non-sensitive
position context.

**Normative requirements.**
- `clearance_id` **MUST NOT** appear in `Artifact.metadata`. It is an access key, not position context.
- `verify_url` **MUST** point at the Verification Authority (§2.2) and **MUST** use `.ai`.
- An implementation **MUST NOT** treat the presence of this block as proof of a valid seal. It is a
 *pointer*; verification is §6.

### 4.4 The Bilateral Record

The object the Crossing Seal is computed over. **IMPLEMENTATION PENDING — this is the Bilateral Crossing,
and it does not exist:** today's Canal Crossing carries one `ai_system`, an owner reference,
and no counterparty field anywhere in the contract, the transaction
store, or the chain.

```jsonc
{
 "record": "anax-bilateral-crossing-v1",
 "crossing_id": "<uuid>",
 "created_at": "<RFC3339>",

 "parties": [ // exactly 2 — see normative note
 {
 "role": "initiator", // "initiator" | "responder"
 "principal_id": "urn:anax:principal:<opaque>",
 "agent_id": "<A2A agent identity>",
 "clearance_id_hash": "<sha256>", // HASH, never the key itself
 "trust_basis": "vicca_authority_sealed",
 "agc_level": 3,
 "open_mandate_hash": "<sha256>",
 "closed_mandate_hash": "<sha256>",
 "signer_role": "agent", // "human" | "agent" — T2 | T1
 "governance_basis": { "pack_id": "<pack>", "pack_version": "1.2.0" }
 }
 //... responder
 ],

 "agreement_hash": "<sha256>", // §4.2 — SHA-256(JCS(terms))
 "commitment_class": "<class>", // the §4.1.3 ladder: observe|reversible|irreversible|financial|binding
 "commitment_act": "<act>", // what act; per-profile vocabulary, §4.1.3
 "magnitude_asserted": 250000, // integer, unit fixed by class (§4.1.3)
 "currency": "EUR", // REQUIRED when commitment_class is financial (M-2)

 "a2a_context": {
 "task_id": "<A2A Task.id>",
 "context_id": "<A2A Task.contextId>",
 "artifact_id": "<A2A Artifact.artifactId>"
 },

 "timestamps": {
 "mandates_verified_at": "<RFC3339>",
 "terms_agreed_at": "<RFC3339>",
 "sealed_at": "<RFC3339>"
 },

 "prev_hash": "<sha256 | null>", // chain position, sealed IN — see below
 "chain_seq": 42
}
```

**Normative requirements.**

1. `parties` **MUST** contain exactly two entries, with distinct `principal_id` values and exactly one of
 each `role`. *(Multilateral crossings are out of scope for v1 and are noted as an open problem, not an
 omission.)*
2. **Mandates are carried by hash, not by value.** The record binds to them; it does not republish them.
 Mandates may carry commercially sensitive constraints, and the Bilateral Record is the input to a
 publicly resolvable seal.
3. `clearance_id_hash` **MUST** be a hash. The raw `clearance_id` is an envelope access key and **MUST NOT**
 appear in the record.
4. **Two-level sealing, per the dual-anchoring decision (§4.4.1).** A single seal cannot commit to two
 different `prev_hash` values, and a bilateral crossing has two clearance-envelope chains. The value is
 therefore split:

 ```
 joint_seal = SHA-256( canonical(Bilateral Record, chain position EXCLUDED) ) // party-independent
 anchor_i = SHA-256( joint_seal ‖ prev_hash_i ‖ chain_seq_i ) // one per party
 // ‖ is NORMATIVE from v0.4 (adopted 2026-09-05):
 // anchor_i = SHA-256( UTF-8( `${joint_seal}|${prev_hash ?? "genesis"}|${chain_seq}` ) )
 // "|" is the literal 0x7C; genesis prev_hash is the string "genesis"; chain_seq is decimal, unpadded.
 // Vectors AN-1 (genesis) and AN-2 (non-genesis) are published below; a second implementer MUST match both.
 ```

 **Conformance vectors — series AN-** *(folded into this section at v0.4.3; previously in an internal
 addendum).* Fixtures are themselves SHA-256 of fixed strings so anyone can regenerate them:
 `joint_seal = SHA-256("anax-an-vector:joint_seal")`, `prev_hash = SHA-256("anax-an-vector:prev_hash")`.

 | Vector | `prev_hash` | `chain_seq` | Preimage | `anchor` |
 |---|---|---|---|---|
 | **AN-1** genesis | `null` | `0` | `e2cd3bbd…f270\|genesis\|0` | `0389b62946981d1155cb6ab1b70ad99f15f3f9b66cccdbdb477976948842d85e` |
 | **AN-2** non-genesis | `293e3037…4012` | `42` | `e2cd3bbd…f270\|293e3037…4012\|42` | `3d907220b49faf996328fe47102d8941929e38cf9232026349b54dcdfe53e2cd` |

 Full fixture values: `joint_seal = e2cd3bbdb71cbf699b3b554a7081c7a24e695c923437906b55fbc67aba30f270`,
 `prev_hash = 293e3037ba29ad930f1b9357aaff94d41e075a06c50efa99a9c40ee3f4a44012`.

 - Both parties **MUST** compute an **identical `joint_seal`**. It is the commitment.
 - Each party **MUST** compute and write its own **`anchor`** into **its own** clearance-envelope chain,
 preserving the existing property that a chain link commits to its own position.
 - `joint_seal` is the value published, distributed (§5.6) and resolved at the Verification Authority
 (§6.2). `anchor_i` is each party's internal chain evidence and is **not** the identifier of the
 commitment.
 - **A partial anchor write does not invalidate the commitment.** If `joint_seal` was computed and agreed
 by both parties (§5.5) and at least one anchor was written, the commitment exists — because a
 commitment is defined by resolvability, not by message or by write count (§5.6). A missing anchor is
 an **audit-trail gap for that party**, recoverable by an idempotent retry (§5.6 req 3), and the party
 holding it **MUST** retry rather than treat the commitment as absent. This is distinct from F6
 (§5.7), which is the case where **no** anchor could be written and no chain position exists at all.
5. **A crossing whose chain position cannot be established MUST NOT be sealed**. Refuse; do not degrade.
6. Both parties **MUST** be able to independently recompute the seal from the record.
7. **Party binding** *(v0.4, adopted 2026-09-06)*. For each entry `p` in `parties`: `p.agent_id` **MUST** be the
 agent subject (`sub`) of the Mandate at `p.closed_mandate_hash`, and that Mandate's `open_mandate_hash` **MUST**
 equal `p.open_mandate_hash`. For an ANAX-derived subject, `p.agent_id` is `urn:anax:agent:<sha256(lowercased
 owner)>` and no other form. A record whose party does not satisfy this is not the record of that party's
 commitment. *(Why: without it, any holder of a valid Closed Mandate for the agreement could seal as a party it
 is not — the hash in the record is whatever the initiator wrote. Req 7 makes the presented bytes, the record's
 hash, and the record's named agent one fact. `principal_id` stays opaque; `agent_id` is the join.)*

#### 4.4.1 Chain placement — ✅ DECIDED: Option A, dual anchoring

Today's chain is keyed **per clearance envelope**: one chain per clearance envelope, unique on (envelope, sequence), and the seal is computed over a basis that **includes `prev_hash`**. **A bilateral crossing has two envelopes**, and therefore two possible chain positions
with two different `prev_hash` values.

> **⚠ This surfaces a genuine tension in §4.4 requirement 4.** A seal cannot simultaneously commit to two
> different `prev_hash` values. Any option that anchors in both chains requires splitting one value into
> two levels.
>
> **✅ RESOLVED (2026-08-09): Option A — dual anchoring — is APPROVED.** §4.4 requirement 4 is
> restated above in terms of the two-level split. The options analysis below is retained as the record of
> why.

**The two-level split** (required by Options A and D, not by B or C):

```
joint_seal = SHA-256( canonical(Bilateral Record without chain position) ) // party-independent
anchor_i = SHA-256( joint_seal ‖ prev_hash_i ‖ chain_seq_i ) // one per party
```

Both parties compute an identical `joint_seal`; each computes its own `anchor`. The existing property —
a seal that commits to its own chain position — is preserved at the anchor level, and the new property —
a seal both parties can independently derive — is satisfied at the joint level.

| | Option | How it works | For | Against |
|---|---|---|---|---|
| **A** | **Dual anchoring** *(recommended)* | Each party appends to **its own** envelope chain; each anchor references the shared `joint_seal`; mutual cross-reference recorded in the Bilateral Record. | Each party's own chain stays a **complete** record of its own commitments. Neither party depends on the other's infrastructure for its own evidence. Existing per-chain contention logic works unchanged — each anchor is an ordinary single-chain append. | Requires the two-level split, i.e. **reopens §4.4 req 4**. Two writes, so a partial-write window exists (§5.6). |
| **B** | **Single designated chain** | The initiator anchors; the responder holds a reference only. | Simplest. Preserves every existing invariant with no change. One write, no partial-write window. | **Asymmetric.** The responder's own chain has a hole where its commitment should be, and it depends on the counterparty's infrastructure for its own audit trail. For a standard whose premise is that neither party need trust the other, this is the wrong shape. |
| **C** | **Third joint record** | A new chain keyed by `crossing_id`, independent of both envelopes. | Clean symmetry; no two-level split needed. | Neither party's **own** envelope chain shows its bilateral commitments, so a party auditing itself misses them. Needs a new UNIQUE key and new contention logic — the existing hardened path is not reused. |
| **D** | **Hybrid (C + A)** | Joint record on its own chain, **plus** per-party anchors referencing it. | Most complete. Both the joint view and each party's self-audit are whole. | Most work; three writes; two new failure modes to specify. Hard to justify before a first implementation exists. |

**✅ DECIDED: Option A — dual anchoring.** The decisive fact is that **the per-envelope audit endpoints
already exist and are already per-envelope**: an authenticated owner-scoped verify endpoint and
its export counterpart. Under Option B or C,
a party exporting its own chain for a regulator, insurer or court would produce a record with its bilateral
commitments **missing** — which defeats the purpose those endpoints exist for. Option A preserves them, at
roughly a third of the cost of D.

**Option D remains additively reachable, and its natural future host is named.** A joint chain can be
added **on top of** Option A without migration: the `joint_seal` is already party-independent, so a central
registry consumes exactly the value both parties already compute, and no existing anchor, chain or exported
record changes. **That registry's natural home is the central crossing registry of the FRYKTORIA Centre
(roadmap).** Recorded here so that the decision to start with A is understood as a first step rather than a
ceiling.

**Consequences applied in this draft:**
- §4.4 requirement 4 is **restated** in terms of the two-level split (`joint_seal` / `anchor_i`), including
 the partial-anchor-write rule.
- §§5.5–5.6 were drafted to hold under all four options; **confirmed unchanged in substance** — only the
 forward references to the pending decision are resolved to Option A. §5.5's "chain write(s)" is now
 specifically one anchor per party; §5.6's definitional mitigation is unaffected, because it already
 defines commitment by resolvability rather than by write count.

#### 4.4.2 Chain scoping — one chain per counterparty pair *(v0.4, adopted 2026-09-06)*

A party's anchors for bilateral crossings are **not** one undifferentiated chain. They are scoped **per
counterparty pair**, so that no relationship leaks into another through `prev_hash`.

**Normative.**

1. **`chain_id`** for a crossing is a deterministic function of the two parties' agent subjects (§4.4 req 7
 `agent_id`), independent of role and order: `chain_id = SHA-256( UTF-8( min(agent_id_A, agent_id_B) || "|" ||
 max(agent_id_A, agent_id_B) ) )`, where `min`/`max` are by byte-wise (code-point) comparison of the UTF-8
 strings. Both parties compute the same `chain_id` for the same pair.
2. Each party keeps its anchors **per `chain_id`**: `chain_seq` starts at 0 at the **first crossing of the pair**
 (`prev_hash = null`, the genesis of that relationship — the §4.4 anchor rule hashes it as the literal `genesis`) and increases by
 one per sealed crossing of the same pair. `(chain_id, chain_seq)` is unique per party.
3. **`prev_hash` MUST be the previous anchor of the same `chain_id` and nothing else.** An anchor that references a
 `prev_hash` from a different pair's chain is malformed (`CHAIN_POSITION_UNAVAILABLE` at seal; `chain_position_valid:
 false` at verify). Consequently a verifier holding one relationship's chain learns nothing about the existence,
 count or timing of any other relationship of either party.
4. `crossing:verify` reports `chain_id` alongside `prev_hash`, `chain_seq`, `is_genesis` (§3.7.3); it does not report
 the subjects the id was derived from.

*(Why: a single chain per party would make every counterparty a witness to every other — the previous anchor of
a crossing with B would be the `prev_hash` in a record shared with C. Envelope chains (§4.4.1) are already scoped
per `clearance_id`; this is the same discipline for the bilateral case. The cost — a genesis per relationship — is
no cost: genesis is a value, not a ceremony.)*

### 4.5 Commitment state — and why it is not a `TaskState`

**This is a forced deviation from an earlier draft.**`TaskState` is a closed enumeration of eight values: `TASK_STATE_SUBMITTED`, `TASK_STATE_WORKING`,
`TASK_STATE_COMPLETED`, `TASK_STATE_FAILED`, `TASK_STATE_CANCELED`, `TASK_STATE_REJECTED`,
`TASK_STATE_INPUT_REQUIRED`, `TASK_STATE_AUTH_REQUIRED`.Extensions **may not add new values to enum types**.

the design analysis proposed *"a State Machine extension adding a `committed` state"*. That proposal
is **not conformant as literally stated** — and it is precisely the trap the design analysis itself warned about at
§B4.1, now confirmed against the actual enum rather than anticipated. The resolution:

> **The core `TaskState` remains one of the eight. Commitment is an *extension-scoped* state, carried in
> `Task.metadata` under the extension URI.**

| Extension state | Core `TaskState` | Meaning |
|---|---|---|
| `mandates_pending` | `TASK_STATE_AUTH_REQUIRED` | Counterparty must present mandates. *(A near-exact fit — this core state exists for precisely this shape of requirement.)* |
| `terms_proposed` | `TASK_STATE_INPUT_REQUIRED` | Terms on the table, awaiting counter-signature. |
| `sealing` | `TASK_STATE_WORKING` | Mandates verified; seal being written. |
| **`committed`** | `TASK_STATE_COMPLETED` | Sealed. The Crossing Seal exists and resolves. |
| `refused` | `TASK_STATE_REJECTED` | A normative refusal — expired mandate, magnitude exceeded, counterparty unverifiable. |
| `failed_unsealed` | `TASK_STATE_FAILED` | Seal could not be written. **No commitment was made.** |

⚖ **Normative, and it is the most important rule in §4:**
**A verifier MUST NOT infer commitment from `TaskState` alone.** `TASK_STATE_COMPLETED` on a Governed
Crossing task means the task finished — it does not mean a commitment was sealed. **Only a resolvable
Crossing Seal proves a commitment.** An implementation that treats `TASK_STATE_COMPLETED` as commitment has
implemented a downgrade attack against itself.The mapping above is a genuine gain rather than a workaround. `TASK_STATE_AUTH_REQUIRED` and
`TASK_STATE_REJECTED` already exist and already mean approximately the right thing, so the failure paths
land on core states that unextended A2A agents can interpret. An agent that does not implement Governed
Crossing still sees "this task was rejected" — the correct impression — rather than an opaque state.

---

## 5. Protocol Flows

### 5.1 Overview

Five phases. Each **MUST** complete before the next begins; there is no pipelining, and in particular no
phase may begin on the strength of a *predicted* outcome of an earlier one.

```
 P0 Discovery & activation Agent Cards read, extension activated (§3.5)
 │
 P1 Mandate exchange Open Mandates exchanged and screened (§5.2)
 │
 P2 Terms proposal Terms Document converged; agreement_hash (§5.3)
 │ computed INDEPENDENTLY by both parties
 │
 P3 Mutual mandate verification Closed Mandates issued, exchanged, and each (§5.4)
 │ verified against its own Open Mandate
 │
 P4 Joint sealing Bilateral Record built; joint seal computed (§5.5)
 │ by both; chain write(s) performed
 │
 P5 Seal distribution Seal attached to Artifact; both parties (§5.6)
 confirm resolvability at the VA
```

**Extension states** (§4.5) advance `mandates_pending` → `terms_proposed` → `sealing` → `committed`, with
`refused` and `failed_unsealed` as terminal alternatives.

⚖ **Governing rule for every phase: refuse, never degrade.** Inherited from existing ANAX behaviour. At no point in this flow is a partial
success an acceptable outcome. A commitment is made or it is not.

### 5.2 P1 — Mandate exchange

Each party sends its **Open Agreement Mandate** in `Message.metadata` under the extension URI.

**Screening verification.** On receipt, a party **MUST** check, before proceeding:

1. Signature validates, under a non-deterministic scheme (§4.1.1).
2. `vct` is `mandate.agreement.open.1`.
3. `exp` is in the future.
4. `iss` resolves to the claimed Principal (§4.1.5).
5. `permitted_counterparties` includes this party, or explicitly states unbounded. *(v0.4 note: at
 crossing v1 this claim is issued by nobody and verified by nobody, so item 5 is NOT enforced by the
 reference implementation. Accepted for v1 because the two bindings that matter already hold elsewhere:
 the Closed's `aud` names the counterparty (§5.4 check 7) and §5.4 check 9 binds each party's Mandates
 to the record by hash and subject. An Open's `aud` is the Verification Authority (§4.1.3) and is not a
 counterparty check; a responder MUST NOT refuse an Open on its `aud`. Hardening pass: issue the claim on
 Opens, verify it here.)*
6. `commitment_class` overlaps with the class this crossing concerns.
7. If the counterparty intends autonomous (T1) closing, `cnf` is present.

**Failure at P1 MUST terminate the crossing.** A party **MUST NOT** proceed to negotiate terms it cannot
lawfully be offered. Screening here is not an optimisation — negotiating first and checking authority
afterwards is how a party ends up holding an agreement it knew, at the time it was made, could not be
honoured.

**Normative:** a party **MUST NOT** disclose its `magnitude_limit` beyond what `permitted_counterparties`
and `commitment_class` require.A counterparty that learns the exact ceiling learns exactly what to
ask for; this is the pressure-negotiation surface of §7.5, and the mitigation begins here, at disclosure,
not later at refusal.

### 5.3 P2 — Terms proposal

The parties converge on a **Terms Document** (§4.2). This specification does not govern negotiation
content; it governs what happens to the result.

**Normative:**

1. Both parties **MUST** independently compute `agreement_hash` over the canonical serialization.
2. Both **MUST** exchange and compare the computed values **before** any Closed Mandate is issued.
3. **A mismatch MUST abort the crossing.** Neither party may adopt the other's value, propose a
 tie-break, or proceed on the assumption that the difference is cosmetic.
4. A party that cannot canonicalize the document **MUST** treat that as a mismatch, not as a pass.

Aborting on mismatch is not defensive tidiness. Two parties who seal against different documents have
produced a record that proves a commitment neither of them made — the exact failure a Crossing Seal
exists to make impossible.

### 5.4 P3 — Mutual mandate verification

Each party issues a **Closed Agreement Mandate** binding `agreement_hash`, `open_mandate_hash`,
`magnitude_asserted`, `crossing_id`, `nonce` and `signer_role`, and sends it to the counterparty.

**Binding verification.** Each party **MUST** verify the counterparty's Closed Mandate against the
counterparty's Open Mandate:

1. Signature validates; if `signer_role` is `agent`, the signing key **MUST** match the Open Mandate's `cnf`.
2. `open_mandate_hash` matches the Open Mandate received at P1.
3. `agreement_hash` matches the value agreed at P2.
4. `commitment_class` is one of the classes the Open Mandate permits.
5. `magnitude_asserted` satisfies `magnitude_limit` (§4.1.3) — one integer against one integer, in the unit the
 class fixes. *(v0.4: `magnitude_asserted` is record-level, one per crossing; it **MUST** satisfy
 **both** parties' Closed `magnitude_limit` and, through them, both Opens' declared limits — conjunctive
 across parties.)* *(v0.4.2: the magnitude is a single integer on the record and on each Closed Mandate
 (§4.1.2); the earlier "every dimension" wording described a per-dimension object no Mandate carries in
 this specification and is withdrawn.)*
6. `exp` on **both** mandates is in the future **at the moment of verification**, not merely at issuance.
7. `aud` names this party — the **Closed** Mandate's `aud`. *(v0.4: the Open's `aud` is the Verification
 Authority and is not checked here or at P1.)*
8. `nonce` has not been seen before for this `crossing_id`.
9. **Party binding** *(v0.4)* — seven equalities *(the seventh from v0.4.4)*, all **MUST** hold. For the initiator:
 `SHA-256(initiator_closed_mandate) == parties[initiator].closed_mandate_hash`,
 `closed.sub == parties[initiator].agent_id`, `closed.open_mandate_hash == parties[initiator].open_mandate_hash`,
 `closed.commitment_act == record.commitment_act`;
 and the same for the responder against its own stored Closed Mandate and `parties[responder]`.
 Failure on either party is `MANDATE_PARTY_MISMATCH` (§3.7.4). This check is pure verification and precedes any
 consumption.
 *(v0.4.4, normative)* A Closed Mandate **MUST** name the act it is drawn for (`commitment_act`, §4.1.3); the
 responder **MUST** refuse, as `MANDATE_PARTY_MISMATCH`, a Closed whose act is absent or differs from the
 record's, and, as `MALFORMED_MANDATE`, a record whose act is outside the profile's act vocabulary (§4.1.3).

**Magnitude equality** *(v0.4.2, normative)*. The record's `magnitude_asserted` **MUST** equal the asserted
magnitude of each party's Closed Mandate (§4.1.2 `magnitude_asserted`); a mismatch is refused
`MAGNITUDE_MISMATCH` (§3.7.4). This is an integrity check distinct from the budget ceiling
(`MAGNITUDE_EXHAUSTED`): the former means two sealed documents disagree on the amount, the latter means the
amount exceeds the Mandate. It is pure verification and precedes any consumption.

**Revocation at commit** *(v0.4.1, normative)*. A Mandate that was active when it was consumed may be
revoked before the seal is written. The responder **MUST** re-read the status of both Closed Mandates
inside the transaction that writes the seal, holding a read lock on both rows so that a concurrent
revocation either lands before the read or waits for the write; if either Mandate is no longer active
the seal **MUST** be refused `MANDATE_REVOKED` (§3.7.4), nothing is written, and the refusal is recorded
with both consumptions marked as spent (§11-17, cost (b)). This is the bilateral form of the Mandate Object
Specification (forthcoming) §2.4 (a revoked Mandate fails at commit even if it passed at start). The re-read is a read:
consumption remains the Registration Authority's alone.

**Normative:** a verifier that cannot evaluate any check **MUST** treat it as failed. There is no
"unable to determine, therefore accept" branch anywhere in this specification. *(This mirrors the
fail-closed discipline already in the reference implementation: an empty scope list denies rather than permits.)*

### 5.5 P4 — Joint sealing

**Normative:**

1. Both parties **MUST** construct the Bilateral Record (§4.4) and **MUST** independently compute the joint
 seal from it.
2. The parties **MUST** compare computed seal values before any chain write. A mismatch aborts (as §5.3).
3. **Each party MUST write its own `anchor` into its own clearance-envelope chain** (§4.4 req 4, §4.4.1
 Option A). The `joint_seal` is shared and identical; the anchors are per-party. A party **MUST NOT**
 write an anchor before seal comparison (req 2) has succeeded.
4. **If the chain write fails, no commitment has been made.** Both parties **MUST** enter
 `failed_unsealed` (core `TASK_STATE_FAILED`) and **MUST NOT** act on the agreement. Retry is permitted;
 silent acceptance is not.
5. A party **MUST NOT** report a commitment as made before it holds a seal value it computed itself and
 confirmed identical to the counterparty's.

### 5.6 P5 — Seal distribution, and the delivery window

The Crossing Seal is attached to `Artifact.metadata` on the Artifact representing the agreement, and echoed
into `Task.metadata` on the terminal Task (§4.3).

**⚠ Open problem, stated rather than papered over.** Between the chain write and the counterparty's receipt
of the seal there is a window in which one party knows a commitment exists and the other does not. This is
the two-generals problem and **it is not solvable by adding another acknowledgement.**

**The mitigation is definitional, and it is the right one:**

> ⚖ **A commitment is defined as *resolvable at the Verification Authority*, not as *delivered by message*.**

Consequences, all normative:

1. A party that has not received the seal **MUST NOT** conclude that no commitment exists. It **MUST**
 resolve `crossing_id` at the Verification Authority (§6) before acting on that assumption.
2. Seal distribution is therefore a **convenience, not the commitment event.** Losing the message loses
 nothing but time.
3. `crossing:seal` **MUST** be idempotent on `crossing_id`. A retry after a lost response **MUST** return
 the existing seal, never mint a second one. *(The estate already holds this discipline: the edu passport
 id is derived from the submission precisely so that a queue retry is a no-op by construction, after a
 defect in which a retry wrote a second attestation for one assessment. A second attestation of one
 commitment is the same failure at protocol scale.)*

### 5.7 Failure paths

Every path below is a **normative refusal**, not an error to be recovered from by proceeding. In each,
`refused` maps to core `TASK_STATE_REJECTED` (§4.5), except where noted.

| # | Failure | Detected at | Normative behaviour |
|---|---|---|---|
| **F1** | **Expired mandate** — `exp` on an Open or Closed Mandate is past at verification time | P1 screening; **re-checked at P3** | **MUST reject. MUST NOT commit.** A mandate valid at P1 and expired at P3 **MUST** fail: expiry is evaluated at the moment of verification, never at issuance. The counterparty **MAY** be invited to present a re-issued mandate, which restarts at P1. |
| **F2** | **Magnitude exceeded** — `magnitude_asserted` exceeds `magnitude_limit` | P3 | **MUST reject. MUST NOT commit.** The refusal is **structural, not discretionary**: there is no override, no "approve anyway", and no human-in-the-loop path that rescues *this* mandate. The correct remedy is a **new Open Mandate from the Principal**, or a **T2 human-signed Closed Mandate** if the Principal's governance permits one for this class. |
| **F3** | **Counterparty unverifiable** — `iss` does not resolve to the claimed Principal, signature fails, or `cnf` does not match the signing key | P1 or P3 | **MUST reject. MUST NOT commit.** A party **MUST NOT** proceed on a self-asserted identity. *(This is the §2.3 distinction made operational: a claim about oneself is not a verified fact about oneself.)* |
| **F4** | **Canonicalization mismatch** — the two computed `agreement_hash` values differ | P2 | **MUST abort before sealing.** Neither party may adopt the other's value or tie-break. Both **MUST** treat the terms as not agreed. |
| **F5** | **Downgrade attempt** — a commitment is requested or presented without extension activation or without a valid Crossing Seal | P0, or on any inbound commitment | **MUST reject** (§3.5.1). The refusal **MUST** be recorded and **MUST** be auditable (§3.5.2 req 4). A downgrade attempt is a **detectable violation**, and detection that is not recorded is detection thrown away. |
| **F6** | **Seal unwritable** — chain write fails or chain position cannot be established | P4 | **MUST NOT commit.** State is `failed_unsealed` → core `TASK_STATE_FAILED` (not `REJECTED`: nothing was refused, something failed). Retry permitted; idempotent on `crossing_id` (§5.6). |
| **F7** | **Seal mismatch** — the parties' independently computed joint seals differ | P4 | **MUST abort.** Same discipline as F4. |

**Normative on refusal messaging.** A refusal **MUST** state which failure path fired, at a granularity
sufficient for the counterparty to correct a legitimate error. It **MUST NOT** disclose the refusing
party's `magnitude_limit`, the contents of its Open Mandate beyond what was already exchanged, or any
internal governance verdict. *(The estate holds the analogous rule already, and holds it deliberately:
unknown, revoked and expired engagement codes are distinct internally and identical externally, because
distinguishing them "turns this into an enumeration oracle for anyone holding a list of guesses". F2 is exactly that shape: a counterparty that can
probe until refusal stops has measured the ceiling.)*

### 5.8 Named work item — Terms canonicalization

> **Terms canonicalization — CLOSED.**
> **Normative algorithm:** **RFC 8785, JSON Canonicalization Scheme (JCS).** Adopted; §4.2.
> **Not the answer:** the existing single-party serialiser — the current single-party
> utility. Right instinct, one implementation, no published test vectors, and written for a basis
> constructed by one party. It remains in use for the unilateral Canal seal and is **not** the bilateral
> algorithm.
> **⚖ GATE PASSED 2026-08-31: vectors TD-1…TD-5 produced by a sort-keys / UTF-8 serialiser and reproduced
> byte-for-byte by an independent RFC 8785 implementation, with a negative control;
> two implementations, not one run twice.** The negative control moved TD-1's digest from
> `cccd1864…` to `2b82efb6…` on a single-integer change, so the comparison is known to bite rather than
> merely to pass. The verifier reads its expected values out of the published vector set rather than
> restating them, so a transcription error cannot present as conformance.
> **Standing rule, independent of the algorithm:** both parties compute independently; **mismatch MUST abort
> before sealing** (§5.3).

Rationale for preferring a published standard over an internal utility: a bilateral hash must be computable
by an implementer who has never seen ANAX code, from a specification, in a language of their choosing.
An internal utility cannot meet that bar however correct it is.

---

## 6. Verification

### 6.1 What verification is for

A Crossing Seal is only worth what a third party can do with it. This section defines the resolution path
for a counterparty, and for the audiences the design analysis names: **regulators, insurers, courts**.

### 6.2 Public verification

**The Verification Authority is `verify.anaxstandard.ai`** (§2.2). Seal resolution is delegated to the
Canal projection:

```
GET /canal/verify/:seal_id → public, unauthenticated
``` This endpoint already exists and already computes very close to what a
counterparty needs. Specifically, it **strips `clearance_id`** — the envelope access key — from both the
chain position and the returned basis, while **retaining `chain_seq`, `is_genesis` and `prev_hash`** as
non-sensitive position context. A richer authenticated owner-scoped projection
exists separately and refuses on owner mismatch.That split — public position without the key, private detail behind ownership — is exactly the
projection this specification needs, and it was built before this specification existed. It is the single
most transferable asset from the current implementation.

**What a verifier MUST check** on resolving a seal:

1. The seal resolves at all, and to the `crossing_id` in question.
2. The returned `seal` value equals the value the verifier computes from the Bilateral Record, if it holds
 one.
3. `prev_hash` and `chain_seq` are present and consistent with the chain's own verification endpoint
 (an authenticated owner-scoped endpoint, available to a party for its own
 chain).
4. `pack_id` / `pack_version` are present — the governance basis under which the commitment was judged.
5. The seal is not marked superseded.

**Normative:** a verifier **MUST NOT** treat a non-resolving seal as merely absent evidence. Under §5.6 a
commitment **is** its resolvability; a seal that does not resolve is a commitment that was not made.

**⚠ Note on the portal's input handling.** The passport portal performs **no prefix validation** — a
`canal-` prefixed input routes to the Canal API, a UUID-shaped input is looked up on `id`, and **anything
else is looked up verbatim**. This is convenient today and is
an attack surface tomorrow; it is logged in the internal security backlog and addressed at
§7.6.

### 6.3 Offline verification

Offline verification is **partial by nature**, and the partition matters:

| Property | Offline? | Why |
|---|---|---|
| Mandate signatures validate | **Yes**, given the issuer's public key | SD-JWT verification is self-contained. |
| `agreement_hash` matches the Terms Document | **Yes**, given the document | A hash recomputation. |
| Joint seal matches the Bilateral Record | **Yes**, given the record | A hash recomputation. |
| Closed Mandate satisfies its Open Mandate | **Yes**, given both | Constraint evaluation, no network. |
| **Chain position is genuine** | **No** | Requires the chain. `prev_hash` in hand proves only what was claimed at seal time. |
| **The mandate has not been revoked** | **No** | Revocation is state, and state is not in a JWT. See §7.2. |
| **The seal has not been superseded** | **No** | Same reason. |

⚖ **Normative:** offline verification establishes **integrity**, never **currency**. An implementation
**MUST NOT** describe an offline check as verification without qualification, and a party relying on one
**MUST** state that it did so.The honest formulation for a report or an audit is: *"internally
consistent as of the record held; not checked against the ledger."*

This is not a weakness peculiar to Governed Crossing — it is the same limit every offline credential check
has — but a governance specification that let an implementer blur it would be failing at precisely the
thing it exists to do.

---

## 7. Security Considerations

Each threat is mapped to a **mitigation** or is named as an **open problem**. Open problems are stated
plainly; a specification that presents unsolved problems as solved is worse than one that has fewer
features.

### 7.1 Replay

**Threat.** A captured Closed Mandate or sealed record is re-presented to obtain a second commitment.

**Mitigation — considered adequate.** Four independent binds: `nonce` unique per `crossing_id` (§5.4 check
8); `exp` evaluated at verification time, not issuance (F1); `agreement_hash` binding the mandate to one
specific Terms Document; and `aud` naming the intended counterparty. A replayed mandate therefore fails on
audience, freshness, and terms simultaneously. `crossing:seal` idempotency (§5.6 req 3) ensures that even a
successful replay of the *sealing* call returns the existing seal rather than minting a second.

### 7.2 Mandate theft

**Threat.** An attacker obtains a mandate and uses it to commit.

**Partially mitigated.** An **Open Mandate is holder-of-key, not bearer**: `cnf` binds it to the authorized
agent's public key, so an attacker holding the mandate but not the private key cannot issue a valid Closed
Mandate under it. This is a material improvement on what the estate has today, where authority is carried by
**bearer secrets in both populations** — an admin session on one side and an API key on the other — neither of which distinguishes possession from authority.

**Residual — a stolen Open Mandate still leaks.** It discloses `magnitude_limit`, `commitment_class` and
`permitted_counterparties`. That is a negotiating disadvantage, not an authority compromise, and it is why
§5.2 restricts disclosure at exchange time.

**🔴 OPEN PROBLEM — revocation.** SD-JWT carries no revocation mechanism. Today, a compromised agent key can
only be neutralised by waiting for `exp`. **Proposed direction**: a revocation projection at the
Verification Authority, keyed by `open_mandate_hash`, that a verifier **MUST** consult during P3 when
online — making revocation a currency check of exactly the kind §6.3 already says cannot be done offline.
This is not specified in this draft and **MUST** be resolved before v1.0. Until it is, `exp` **SHOULD** be
set to the shortest interval the business process tolerates.

### 7.3 Seal forgery

**Threat.** A fabricated seal is presented as genuine, or a genuine seal is altered.

**Mitigated for fabrication and alteration.** A seal is SHA-256 over a canonical serialization of the
Bilateral Record; a verifier holding the record recomputes it (§6.3). Chain insertion is constrained by
`UNIQUE(clearance_id, chain_seq)` and by each link committing to its predecessor's hash, so retroactive insertion breaks every subsequent
link and is detectable by a chain walk.

**🔴 OPEN PROBLEM — the Verification Authority is a single point of trust.** A compromised VA can assert
that a seal resolves when it does not, or fail to resolve one that does. Three partial mitigations exist
and none is complete: the seal is **independently recomputable** by any party holding the record; a full
chain **export** endpoint exists so a party can retain its own copy; and the chain's internal
consistency is checkable without the VA's assent once exported. What none of these gives is *detection by a
third party who holds neither the record nor an export.* Named, not solved.The eventual answer is
probably periodic publication of chain head hashes to an independent witness; that is out of scope for v1.

### 7.4 Downgrade to unsealed commitments

**Full disclosure first.**

A2A extensions **default to inactive**. Activation is requested per-request via the `A2A-Extensions` header,
and the responding agent echoes back what it activated. `required: true` on an Agent Card means the agent
**SHOULD** — not **MUST** — reject a client that has not activated a required extension.

It follows plainly, and this specification states it without softening: **omitting the header is an
available path, by design of the transport.** The A2A extension mechanism does not, and does not attempt
to, guarantee that a governance extension cannot be skipped. **The anti-downgrade property cannot be
inherited from the transport layer.**

**The conclusion this specification draws.**

This is the cleanest available proof of the argument the design analysis and arXiv 2606.31498 make independently:
**governance cannot live at the transport layer.** A transport's job is to move messages between
consenting parties, and a mechanism whose activation is negotiated per-request is exactly right for
capability discovery and exactly wrong for obligation. An obligation that either party may decline to
activate is not an obligation. **Endpoint enforcement is therefore required — not as a workaround for a
gap in A2A, but because it is the only layer at which the property can exist at all.** This is the
"missing architectural layer above current interoperability standards, not a missing feature within them", observed concretely rather than argued abstractly.

**Mitigation — the normative pair (§3.5.1), restated because this is where it earns its place:**

> **OUTBOUND.** A Class 2 implementation **MUST NOT** issue a commitment without a sealed Governed
> Crossing.
> **INBOUND.** A Class 2 implementation **MUST reject** any inbound commitment that does not carry a valid
> Crossing Seal.

**No seal, no deal.** The pair converts downgrade from a silent path into a **detectable violation**: a
downgrading party is refused, the refusal is recorded and auditable (§3.5.2 req 4), and the record of
refusals is itself evidence. The protocol cannot stop a peer from trying; it guarantees that trying fails
visibly and leaves a trace.

**Residual, stated honestly.** Two Class 2 implementations that *both* choose to ignore the pair can
transact ungoverned. No specification can prevent that, and none should claim to. What the specification
gives is that neither can later claim the commitment was governed — because no seal exists, and a seal is
the only thing that proves it.

### 7.5 Sycophancy and pressure negotiation

**Threat**. A counterparty — human or agent — pressures an agent into a commitment its
Principal would not sanction: flattery, urgency, incremental concession, appeals to a relationship, or
simply persistence.

**Mitigated for out-of-bounds commitments — and this is the strongest argument for the Mandate primitive.**

> **The Mandate converts a persuasion problem into a bounded, attributable one.**

An agent talked into exceeding its `magnitude_limit` **cannot close a mandate**. The refusal is F2, and F2
is **structural, not behavioural**: there is no override and no discretion to erode. Persuasion cannot
reach past a constraint the Principal signed, because the agent has no key that produces a valid Closed
Mandate outside it. This is a categorically stronger guarantee than instructing a model to be firm, and it
does not degrade with a longer conversation, a more sympathetic counterparty, or a better-crafted appeal.

Attribution follows: every commitment carries `signer_role` (§4.1.3), so *"an agent committed this under
standing authority"* and *"a human committed this"* are distinguishable at verification time, permanently.

**🔴 OPEN PROBLEM — bad deals within limits.** An agent persuaded into a commitment that is *within* its
magnitude limit but *against its Principal's interest* is **not prevented by this specification, and cannot
be.** The commitment is authorized; it is merely unwise. That is a governance-pack and evaluation-harness
problem, not a
protocol problem.

Naming this boundary precisely is itself a requirement: **this specification bounds authority, not
judgement.** An implementer who believes a Crossing Seal proves a deal was *wise* has misread it. It proves
the deal was *authorized* — which is what this specification's one-line claim says, and no more.

### 7.6 Enumeration at the Verification Authority

**Threat.** The public verification endpoint accepts arbitrary input and distinguishes hit from miss,
performing no prefix validation. That is an unauthenticated
oracle for the existence of identifiers.

**Partially mitigated.** Seal identifiers carry a CSPRNG suffix — `crypto.randomBytes`, 48 bits, adopted
specifically because `Math.random` state is recoverable from observed outputs and a shared PRNG stream
would let one tenant predict another's identifiers. Guessing is
therefore infeasible; the residual risk is confirmation of identifiers obtained elsewhere, and volumetric
probing.

**Open, and already owned.** Logged as a security backlog item in the design analysis, with the timing
deliberately chosen: closing it before the first pilot would cost that pilot its cheapness, and by launch
`ASELF-` will be a registered prefix in the passport namespace, at which point an allowlist
becomes cheap exactly when it becomes necessary. This specification adds one requirement: **a Verification
Authority SHOULD rate-limit unauthenticated resolution**, and **MUST NOT** return differential error detail
that distinguishes "malformed" from "not found".

### 7.7 Open problems — consolidated

| # | Open problem | Section | Required before |
|---|---|---|---|
| **OP-1** | Mandate revocation — SD-JWT has none | §7.2 | **spec v1.0** |
| **OP-2** | Verification Authority is a single point of trust | §7.3 | post-v1.0 |
| **OP-3** | Bad deals within magnitude limits — out of protocol scope | §7.5 | ANAX evaluation harness (out of protocol scope) |
| **OP-4** | Enumeration surface at the VA | §7.6 | Front Office launch |
| **OP-5** | Delivery window between sealing and receipt | §5.6 | mitigated definitionally; no further work required |

---

## 8. Relationship to Adjacent Specifications

Governed Crossing is designed to **compose**. It replaces nothing in the stack.

| Specification | Relationship | Detail |
|---|---|---|
| **A2A core** | **Extends** | Governed Crossing is an A2A extension (§3). It adds no core fields, adds no enum values, and carries all data in `metadata` maps — the three constraints A2A places on extensions. An unextended A2A agent interoperates normally and simply cannot make governed commitments. |
| **A2A Secure Passport** | **Composes — does not compete** | Different objects with different truth-conditions: Secure Passport carries **what the caller asserts about itself** (preferences, session context) for personalisation; a Crossing Seal carries **what a third party verified about a commitment**. A Secure Passport **MAY** carry a reference to a Crossing Seal as one of its shared context items. **The composition is legible precisely because the names differ** (§2.3). |
| **AP2** | **Composes — adjacent domain** | AP2 governs **payment**; Governed Crossing governs **agreement**. Governed Crossing **reuses AP2's open/closed mandate pattern and SD-JWT basis** (§4.1) rather than inventing a credential format. The boundary is exact: AP2's `checkout_hash` binds to a **cart** — a thing with a price. There is no hash target for a **term**. An agreement **MAY** reference a payment made under AP2; the payment remains AP2's. |
| **A2A Timestamp extension** | **Composes** | Both place data in `Message.metadata` / `Artifact.metadata`, namespaced by extension URI, so they coexist without collision. Governed Crossing's own `sealed_at` is authoritative for the seal; Timestamp's values are transport-level and **MUST NOT** be substituted for it. |
| **A2A Traceability extension** | **Composes — complementary** | Traceability records **how** a result was reached; Governed Crossing records **under what authority** a commitment was made. Neither substitutes for the other, and an implementation **MAY** activate both.They are the natural pair for an audit: trace plus mandate answers "what happened and who was entitled to do it". |
| **A2A Agent Gateway Protocol** | **Orthogonal** | Concerns routing and intermediation. A gateway **MUST** forward the `A2A-Extensions` header unmodified; a gateway that strips it induces the downgrade of §7.4 and **MUST** be treated as an untrusted intermediary. |
| **MCP** | **Orthogonal** | Agent ↔ tools. No interaction. |
| **UCP** | **Composes** | Commerce primitives (catalog, cart, checkout). An agreement **MAY** reference UCP artifacts within its Terms Document. |

**Positioning, stated once.** ANAX does not compete with the Linux Foundation ecosystem — it plugs into it,
as AP2 did for payments. That is the whole design intent of expressing this as an extension rather than as a
protocol.

---

## 9. Appendix — Worked Example

**Illustrative only. All values are fictional. IMPLEMENTATION PENDING throughout — no capability shown
below exists today.**

**Scenario.** ANAX's front-office agent issues an **engagement code** to a prospective client — the
accepted first-pilot scenario, here extended to its bilateral form.

> **Note on scope.** The **accepted spike is unilateral**: ANAX seals its own Decision Passport for code
> issuance, `ASELF-` prefix, ~1–2 days, no counterparty involved. This appendix shows what the **same
> commitment** looks like once the Bilateral Crossing exists. The two halves are shown together deliberately, because
> the example also demonstrates the §2.3 naming split in practice: **the Crossing Seal is the wire object;
> the Decision Passport is the ANAX-side artifact.** One commitment, two artifacts, two names, doing two
> different jobs.

**Parties.** *Initiator:* ANAX front-office agent, Principal `urn:anax:principal:anax-standards`.
*Responder:* a prospective client's procurement agent, Principal `urn:anax:principal:example-trust`.
**Commitment act:** `engagement_code_issuance`. **Commitment class:** `irreversible` (§4.1.3).
**Tier:** T1 — agent-signed under standing authority.

### P0 — Discovery and activation

```jsonc
// ANAX agent card, capabilities.extensions[0]
{
 "uri": "https://anaxstandard.ai/ext/governed-crossing/v1",
 "description": "Bilateral commitments under verified mandates, sealed and publicly verifiable.",
 "required": true,
 "params": {
 "conformance": "full",
 "verification_authority": "https://verify.anaxstandard.ai/",
 "principal": {
 "id": "urn:anax:principal:anax-standards",
 "clearance_id": "<withheld>", "trust_basis": "vicca_authority_sealed", "agc_level": 3
 },
 "mandate_formats": ["sd-jwt"],
 "commitment_acts": ["engagement_code_issuance", "proposal_within_tariff"],
 "commitment_classes": ["irreversible"] // the ladder value; acts are the separate axis
 }
}
```
```http
POST /message:send
A2A-Extensions: https://anaxstandard.ai/ext/governed-crossing/v1
```

### P1 — Open Mandates exchanged

```jsonc
// ANAX Open Mandate (SD-JWT payload, abbreviated)
{
 "vct": "mandate.agreement.open.1",
 "iss": "urn:anax:principal:anax-standards",
 "sub": "urn:anax:agent:front-office-01",
 "aud": "*",
 "cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "…", "y": "…" } },
 "iat": 1786000000, "exp": 1788592000,
 "commitment_act": ["engagement_code_issuance", "proposal_within_tariff"],
 "commitment_class": "irreversible", // highest class authorised (L-1)
 "magnitude_limit": 1, // count of actions (irreversible unit, §4.1.3)
 // duration is `exp` above — the code's six-month validity window; scope (one party,
 // non-renewable) is a term of the agreement and lives in the Terms Document (§4.2).
 "permitted_counterparties": "*"
}
```
Both sides run the seven screening checks of §5.2. Both pass. State → `mandates_pending`
(core `TASK_STATE_AUTH_REQUIRED`).

### P2 — Terms and `agreement_hash`

Terms Document (canonicalized per §4.2): cohort `<cohort-id>`, one engagement code, six-month validity, no fee,
assessment under `<pack>` `<version>`.

Both parties compute independently and compare:
```
agreement_hash = 9f2c…a1 (ANAX) agreement_hash = 9f2c…a1 (client) ✓ match
```
State → `terms_proposed` (core `TASK_STATE_INPUT_REQUIRED`).

### P3 — Closed Mandates

```jsonc
// ANAX Closed Mandate (abbreviated)
{
 "vct": "mandate.agreement.closed.1",
 "iss": "urn:anax:agent:front-office-01",
 "aud": "urn:anax:principal:example-trust",
 "signer_role": "agent", // T1 — no human signature
 "iat": 1786000420, "exp": 1786004020, "nonce": "b7d1…",
 "open_mandate_hash": "4a10…",
 "agreement_hash": "9f2c…a1",
 "commitment_act": "engagement_code_issuance",
 "commitment_class": "irreversible",
 "magnitude_asserted": 1, // one action, irreversible unit (§4.1.3)
 "governance_basis": { "pack_id": "<pack>", "pack_version": "0.1.0" },
 "crossing_id": "d41e…"
}
```
Each party runs the eight binding checks of §5.4 against the counterparty's Open Mandate. All eight pass —
note `magnitude_asserted` satisfies `magnitude_limit`. State → `sealing`
(core `TASK_STATE_WORKING`).

### P4 — Joint sealing

Bilateral Record built per §4.4 — mandates by **hash**, `clearance_id` by **hash**. Both parties compute
the `joint_seal`; values match. Under dual anchoring (§4.4.1) each party then writes its **own** anchor
into its **own** clearance-envelope chain, both referencing the shared `joint_seal`:

```
joint_seal = c8e4… (identical for both parties — this IS the commitment)
anchor_anax = H(c8e4… ‖ 77b0… ‖ 128) → anax-standards chain, seq 128
anchor_trust = H(c8e4… ‖ 2d51… ‖ 17) → example-trust chain, seq 17
```

Each party's own chain export now contains this commitment — which is the property Option A was chosen
for.

### P5 — Seal attached

```jsonc
Artifact.metadata["https://anaxstandard.ai/ext/governed-crossing/v1"] = {
 "crossing_state": "committed",
 "seal_id": "canal-<ts>-<rand>",
 "seal": "c8e4…",
 "prev_hash": "77b0…", "chain_seq": 128, "is_genesis": false, "seal_version": 3,
 "pack_id": "<pack>", "pack_version": "0.1.0",
 "outcome": "CLEARED",
 "sealed_at": "2026-08-09T21:15:00Z",
 "verify_url": "https://verify.anaxstandard.ai/?id=canal-<ts>-<rand>"
}
```
Core `TaskState` is `TASK_STATE_COMPLETED`. ⚖ **A verifier MUST NOT read that as commitment** (§4.5) —
commitment is the resolvable seal.

### The ANAX-side artifact

Separately, ANAX writes its own Decision Passport for the same action:

```
<passport-id> → https://verify.anaxstandard.ai/?id=<passport-id>
```
Deterministic in the submission, frozen namespace, idempotent on retry — the passport-id derivation
discipline.

**Two artifacts, one commitment.** The **Crossing Seal** is what the counterparty holds and what a
regulator resolves to see that a bilateral commitment was made under verified mandates. The **Decision
Passport** is what ANAX publishes about its own governance of the action. Neither is called the other, at
any layer — which is §2.3 working exactly as intended.

### Verification

```
GET https://verify.anaxstandard.ai/?id=canal-<ts>-<rand>
 → resolves; chain position confirmed; clearance_id absent from the projection (§6.2)
```

## 9A. Licence, Marks and Services

*Carried into the specification at v0.4.3 from the licence addendum of 2026-08-25, which the v0.3 merge
did not include. Nothing in this section changes a requirement, a wire format or an error name; it states
what the text grants, what the names are, and what the operator's services are not.*

This specification, its conformance vectors, and the companion specifications published by ANAX Standard
(Mandate Object Specification, Crossing Taxonomy, Sovereign Channel Message Contract — forthcoming) are licensed under
**Creative Commons Attribution 4.0 International (CC BY 4.0)**. SPDX: `CC-BY-4.0`. Attribution:
"ANAX Standard — anaxstandard.ai". No licence is required to implement this specification.

Reference implementations published by ANAX Standard are licensed under **Apache License 2.0**.
SPDX: `Apache-2.0`.

**Marks.** Governed Crossing™, Crossing Seal™ and Decision Passport™ are trademarks of ANAX Standard.
Governed Crossing™ designates the protocol and may be used by any conformant Implementer to describe
conformance. The names ANAX, ANAX Standard, ANAX Institute, VICCA, VICCA ONE, FRYKTORIA, ANAX Canal and
X-Layer are trademarks of their owner and are not licensed by this document.

**Services.** Operation of a Registration Authority, Verification Authority, or Centre by ANAX Standard is
a service and is not licensed by this document.

---

## 10. Open Items Before v1.0

*Everything this draft knowingly leaves open. Nothing here is a discovery for a later reader to make.*

### Required before spec v1.0

| # | Item | Source |
|---|---|---|
| ~~**11-1**~~ | ✅ **DONE (2026-08-09)** — the extension URI serves the specification. **Live at https://anaxstandard.ai/ext/governed-crossing/v1** (rendered) and **https://anaxstandard.ai/ext/governed-crossing/v1.md** (raw markdown). A sanitized publication copy is served; this file remains canonical. An implementer encountering the extension URI can now resolve it and read the spec, as A2A's discovery model assumes. | — |
| ~~**11-2**~~ | ✅ **CLOSED (2026-09-01)** — confirmed against the A2A protocol buffers definition: `AgentExtension.params` is `google.protobuf.Struct params = 4`; `Message.extensions` is `repeated string extensions = 7`; `Artifact.extensions` is `repeated string extensions = 6`. PENDING CONFIRMATION markers removed from §3.3 and §4.3.1/§4.3.2. | — |
| ~~**11-3**~~ | ✅ **CLOSED** — chain placement decided (Option A, dual anchoring) and §4.4 requirement 4 restated for the joint-seal / anchor split. Retained struck-through as record; **not** one of the outstanding items. | — |
| ~~**11-4**~~ | ✅ **CLOSED (2026-08-31)** — RFC 8785 (JCS) adopted; the adoption gate passed with TD-1…TD-5 and two independent implementations producing byte-identical digests. §4.2, §5.8. | — |
| **11-5** | **Specify mandate revocation** (OP-1). SD-JWT has none; today a compromised agent key can only be neutralised by waiting for `exp`. | §7.2 |
| ~~**11-6**~~ | ✅ **CLOSED (2026-09-01)** — §3.7 gives params, result, a 17-name error vocabulary with JSON-RPC and HTTP codes, determinism and versioning for both methods; §3.6 gives the per-transport binding. | §3.6, §3.7 |
| ~~**11-7**~~ | ✅ **CLOSED (2026-09-01)** — `commitment_class` fixed to the five-value ordered ladder with L-1…L-5; `magnitude_limit` fixed as a non-negative integer whose unit is set by class, cumulative per Mandate, with M-1…M-5; `commitment_act` added as the separate axis. | §4.1.3 |
| **11-16** 🔴 | ⚠ **v0.4 note, 2026-09-09 — what is enforced, and what is not.** The 2026-09-01 wording below described a specification with no implementation and is retained as the record of that date; it is now wrong in both directions, and the direction that matters is that it understates what runs. **Measured, and dated:** `crossing:seal` and `crossing:verify` are **implemented and conformant** — the responder implementation and the Verification Authority's resolver; the first bilateral crossing was sealed and publicly verified on **2026-09-07** (`joint_seal` computed identically by both parties; genesis anchor written), with **WC-2, WC-3, WC-5, WC-6 exercised live** and WC-1, WC-4, WC-8, WC-8b, WC-9 green in the implementation's own suites. **`commitment_class` IS enforced** on the crossing path by the authority judge (L-1) and, for a bilateral crossing, by the full §5.4 check set including check 9 (party binding). **`magnitude_limit` IS enforced** atomically at the Registration Authority: a Closed Mandate is spent once, whole (M-4b), and its draw is booked against its Open at issuance (M-4a). **CM-1…CM-6: 4 pass, 2 conditional, 0 fail** — CM-4 and CM-6 are conditional because `financial` is unreachable under the operator's charter, and their reachable half is proven at issuance. **STILL NOT ENFORCED — this item stays 🔴 until each of the three closes:** **(i)** the mandated-act list is **three acts** (`crossing:seal` for both parties; one chain-verification read; one credential-provisioning act) and exists only in prose — there is no committed list and no parity check between the list and the code, so a gate can be removed or acquired without anything noticing. Canal's main path is Mandate-**optional by charter**, not by omission: the operator's charter names credential issuance as the one provisioned act. **(ii)** a `commitment_class` is a **caller's declaration with no floor derived from the act**, so the ladder is enforced against a self-declared number — the first live bilateral crossing declared `observe` for `crossing_seal`, an act that wrote an immutable anchor and spent two Mandates, and every check passed because every check compared the declaration to the declarer's own Mandate. **(iii)** the canonical WC suite **has no live mode** and therefore certifies nothing that runs: it now locates the implementation and still reports every vector as `NOT IMPLEMENTED`. ⚖ **This specification MUST NOT be read as describing a fully enforced system.** It MAY now be read as describing a system whose **bilateral crossing path is implemented, conformant and live**, and whose single-party path is governed only where the Charter says it is. Overclaiming the first half and underclaiming it are both refused. — **The 2026-09-01 record follows.** **⚠ ENFORCEMENT — the vocabulary and the wire contract are specified and NOTHING IMPLEMENTS OR ENFORCES EITHER.** §4.1.3's rules have no enforcing component: the only envelope validator in the reference implementation reads jurisdiction, sector, decision type, automation level, special category, children's data and oversight, and contains no reference to `commitment_class` or `magnitude_limit`. §3.7's methods have no handler, route or method string anywhere. **Measured 2026-09-01: CM-1…CM-6 fail 6 of 6; WC-1…WC-7 fail 7 of 7**, the CM vectors by being silently accepted and the WC vectors by having nothing to call. **This specification MUST NOT be read as describing an implemented system, and v0.3 MUST NOT claim enforcement or wire conformance, until both vector suites pass.** Publishing a vocabulary as though it were a control is the failure this project has already paid for twice. | §3.7, §4.1.3 |
| **11-17** 🟡 | **The draw-at-issuance rule's two known costs, stated so nobody discovers them live** *(v0.4, 2026-09-06)*. **(a) No release at v1.** A Closed Mandate that expires unsealed leaves its draw booked against its Open (M-4a); nothing gives it back. The Open's own `exp` bounds the loss; a release primitive (or reserve-then-confirm) is surface the Registration Authority does not have and is not specified here. **(b) A chain-write failure after the spend needs a fresh Closed.** M-4b spends both Closed Mandates before the anchor write (a refused crossing is never anchored — the invariant); if the write then fails, §5.5 req 4 applies (`failed_unsealed`, retry permitted) but the spent Closed cannot be reused — the retry draws a new Closed from the Open. This is the cheap failure, accepted; the expensive one — an anchored crossing with no authority behind it — is impossible by construction. Closes when a release or two-phase spend is specified and implemented, or when v1.0 accepts both costs as final. | §4.1.3 M-4a/M-4b, §5.5 req 4 |

### Deferred beyond v1.0

| # | Item | Source |
|---|---|---|
| **11-8** | **Verification Authority as a single point of trust** (OP-2). Probable direction: periodic publication of chain head hashes to an independent witness. | §7.3 |
| **11-9** | **Multilateral crossings.** v1 fixes `parties` at exactly two. More than two is out of scope, deliberately, and is an omission with a stated reason rather than an oversight. | §4.4 |
| **11-10** | **Enumeration surface at the Verification Authority** (OP-4). Already owned in the internal security backlog, with timing deliberately chosen: close before Front Office launch, when an allowlist becomes cheap exactly as it becomes necessary. | §7.6 |
| **11-14** | **Multilateral Crossing** — N-party joint commitments under a single `joint_seal`. The dual-anchoring model **generalizes**: `joint_seal` remains party-independent; `anchor_i` per party, N anchors. Natural fit with the central crossing registry (the Option D path at §4.4.1). Candidate for `/v2` or a companion extension. *(Expands 11-9, which records the v1 scope decision; this is the design sketch, that is the deferral.)* | §4.4, §4.4.1 |
| **11-15** | **Collective Mandate** — mandates issued by **group principals** without a single representative: threshold/multisig issuance (k-of-n internal signatures) so the Verification Authority can verify **quorum was met WITHOUT visibility into internal deliberation**. Bridges this specification's authority layer to community-governance dimensions (deliberation, voting) that remain out of scope per §7.5. | §4.1, §7.5 |

### Owned elsewhere — recorded here so it is not lost

| # | Item | Owner |
|---|---|---|
| **11-11** | **The Mandate primitive** — object, store, issuance, and the organizational delegation chain. This specification consumes it and **MUST NOT** fork it. | ANAX platform — the Mandate primitive |
| **11-12** | **The Bilateral Crossing** — the second party in the Canal contract and seal basis, with a sequencing rule that keeps new crossings from appearing superseded. | ANAX platform — the Bilateral Crossing |
| **11-13** | **Bad deals within magnitude limits** (OP-3). Out of protocol scope by construction — this specification bounds **authority**, not **judgement**. Belongs to the evaluation harness, which does not exist in any repository today. | ANAX evaluation harness (out of protocol scope) |

---

## 11. Change Log

### v0.4.4 — 2026-09-17 — act binding (§5.4 check 9, seven equalities; unknown act refused)

**Normative, additive (E-3): no name removed or renamed; `MANDATE_PARTY_MISMATCH` and `MALFORMED_MANDATE`
each gain a case.** §5.4 check 9 (party binding) now holds **seven** equalities: the seventh binds each party's
Closed Mandate to the record's act — `closed.commitment_act == record.commitment_act`. Six equalities bound
bytes, subjects and the Open and left the act loose, so a Closed drawn for one act could seal a record
declaring another with every check green. Stated with it: a Closed Mandate **MUST** name the act it is drawn
for; the responder **MUST** refuse, as `MANDATE_PARTY_MISMATCH`, a Closed whose act is absent or differs
from the record's, and, as `MALFORMED_MANDATE`, a record whose act is outside the profile's act vocabulary
(§4.1.3) — an unlisted act has no floor, and "no floor" may not mean "no floor check". §4.1.3's note that
L-5 does not make an unrecognised act malformed stands: the act is bounded by the vocabulary at the seal, not
by the class ladder. The v0.4 bullet below is corrected to the same count. Reference implementation: the
seal binds the act to the record (the seventh equality of check 9) and refuses an unlisted act; the Registration
Authority refuses to issue an act-less Closed; the row holds the same rule as a CHECK.

### v0.4.3 — 2026-09-16 — Licence, marks and services (§9A); anchor vectors folded (§4.4)

**Additive; no wire, rule or error-name change.** New **§9A Licence, Marks and Services** carries the
licence addendum of 2026-08-25 that the v0.3 merge did not include: the CC BY 4.0 / Apache-2.0 split
(specification text and vectors / reference implementations), the trademark notice (Governed Crossing™,
Crossing Seal™, Decision Passport™; the ANAX product names reserved), the statement that Governed Crossing™
may be used by any conformant Implementer to describe conformance, and the clause that operating a
Registration Authority, Verification Authority or Centre by ANAX Standard is a service not licensed by this
document. ™ added to the §2 definitions of Governed Crossing and Crossing Seal. **§4.4:** the anchor
conformance vectors **AN-1** and **AN-2** are now published in the specification itself, with the two
fixture preimages, instead of being cited from an addendum the public copy did not carry.

### v0.4.2 — 2026-09-15 — `MAGNITUDE_MISMATCH`, magnitude equality, WC-11 (normative)

**Normative addition.** Added the error name **`MAGNITUDE_MISMATCH` −40035** (HTTP 403, raised by seal) to
§3.7.4, a **magnitude equality** rule in §5.4 (the record's `magnitude_asserted` **MUST** equal the asserted
magnitude of each party's Closed Mandate; a mismatch is refused before any consumption), and conformance
vector **WC-11**. This is an integrity check distinct from the budget ceiling: `MAGNITUDE_EXHAUSTED` means
the amount exceeds the Mandate; `MAGNITUDE_MISMATCH` means two sealed documents disagree on the amount.
Additive only — no name removed or renamed (E-3). **Consistency edit in the same area:** §5.4 check 5, the
F2 failure row and the P3 walkthrough said `magnitude_asserted` satisfies "every dimension" of
`magnitude_limit`; §4.1.2 has always defined it as a single integer in the unit the class fixes, and no
Mandate in this specification carries a per-dimension object. The three passages now say "the magnitude";
the integer definition stands. The withdrawn wording is noted in place.

### v0.4.1 — 2026-09-15 — `MANDATE_REVOKED` and WC-10 (normative)

**Normative addition.** Added the error name **`MANDATE_REVOKED` −40014** (HTTP 401, raised by seal) to
§3.7.4, a **revocation-at-commit** rule in §5.4 (the responder re-reads both Closed Mandates' status inside
the seal-writing transaction under a read lock and refuses if either is no longer active; the re-read is a
read, consumption stays with the Registration Authority), and conformance vector **WC-10** (valid at
consumption, revoked before commit → `MANDATE_REVOKED`, nothing sealed, refusal recorded with both
consumptions spent). Closes the window between consumption and commit. Additive only — no name removed or
renamed (E-3). The wire form of the Mandate Object Specification (forthcoming) §2.4 for the bilateral path.
Two cross-references corrected before publication: the spent-cost cite resolves to §11-17 cost (b), and the
Mandate Object Specification is cited as forthcoming, as the Authority Doctrine is.

### v0.4 — 2026-09-15 — normative additions since v0.3, and a publication scrub

**This is a normative revision, not an editorial one.** Between the v0.3 publication (2026-09-01) and this
version the following were added to the specification and are carried into the published copy for the
first time:

- **Effector consumption (§3.7.2)** — normative: a Closed Mandate is consumed by possession at the seal, a
 service-held Mandate is refused, and roles do not blend. Error codes **`ROLE_MISMATCH` −40041**,
 **`SERVICE_HELD_MANDATE` −40042** and **`MANDATE_PARTY_MISMATCH` −40043** are added to the error table.
- **Party binding (§4.4 requirement 7, §5.4 check 9)** — each party's `agent_id` **MUST** equal its Closed
 Mandate's subject and the two `open_mandate_hash` values **MUST** agree; six equalities, all **MUST** hold
 *(seven from v0.4.4: the act, see that entry)*.
- **Draw at issuance (M-4a / M-4b, §4.1.4)** — the draw against an Open is booked when the Closed is
 issued, and a Closed is spent once, whole, by possession; the earlier seal-debits-the-Open reading is
 withdrawn; the rule's two known costs are stated at §11-17.
- **Chain scoping (§4.4.2)** — one chain per counterparty pair.
- **Anchor formula (§4.4)** — `anchor_i = SHA-256(UTF-8(joint_seal | prev_hash ?? "genesis" | chain_seq))`,
 with published vectors AN-1/AN-2.
- **Conformance vectors WC-8, WC-8b, WC-9** — Closed Mandate presented in a foreign party slot; initiator
 hash mismatch; two counterparties → two chains.
- **`crossing:verify` audience** — an Open's `aud` is the Verification Authority (`urn:anax:va:001`) as the
 Registration Authority issues it; an Open's counterparty binding is `permitted_counterparties`, never
 `aud`; `aud` = counterparty is the Closed's (§5.2 item 5, §5.4 check 7).
- **§11-16 restated to the measured state** (2026-09-09): the bilateral crossing path is implemented,
 conformant and live; `commitment_class` and `magnitude_limit` are enforced on that path; the item stays
 open for the three named reasons. **§11-17** added.

Alongside those additions, the published copy was audited against the publication filter (Standard
Doctrine §4ter) and the passages that carried operational detail were rewritten: a
customer example (cohort and engagement) and live-issued identifiers (a passport id, seal ids) are replaced
by placeholders; internal function, constant, endpoint and repository names are replaced by their role in
prose; internal decision labels and test labels are replaced by the rule they name; product id-namespace
prefixes are generalized; the certificate-registry host and the portal lookup-logic sentence are removed;
the Authority Doctrine is cited by name as forthcoming. A licence line (CC BY 4.0) is added to the front
matter. The publication projection enforces the same filter and refuses to
write a public copy that carries any of these terms.

### v0.3 — 2026-09-01 — Group A addenda merged

Four addenda, drafted separately and merged together in one step. Merging them one at a time would have left
this document disagreeing with itself in the interval — §4.1.3 carrying an integer `magnitude_limit` while
§4.4 still carried the object, or §3.6 naming a transport binding for methods whose error vocabulary had not
landed.

- **A-1 — canonicalisation.** `agreement_hash` fixed to `SHA-256(JCS(terms_document))` under **RFC 8785**;
 Terms Document constraints **R-1…R-5**; conformance vectors **TD-1…TD-5**. the adoption gate passed (§5.8).
 Closes **11-4**.
- **A-2 — class and magnitude.** `commitment_class` fixed to the five-value ordered ladder
 (`observe` < `reversible` < `irreversible` < `financial` < `binding`) with **L-1…L-5**; `magnitude_limit`
 fixed as a non-negative integer whose unit is set by class, cumulative over the Mandate's lifetime, with
 **M-1…M-5** and `currency` required for `financial`; **`commitment_act`** added as the separate axis of
 *what act* is committed. Conformance vectors **CM-1…CM-6**. Closes **11-7**.
- **A-3 — wire contract.** New **§3.7**: params and result for `crossing:seal` and `crossing:verify`, a
 17-name error vocabulary with JSON-RPC and HTTP codes, determinism, versioning, and vectors
 **WC-1…WC-7**. §3.6 gains the per-transport binding table.
 Closes **11-6**.
- **A-4 — schema confirmation.** `AgentExtension.params`, `Message.extensions` and `Artifact.extensions`
 confirmed against the A2A protocol buffers definition; PENDING CONFIRMATION markers removed from §3.3, §4.3.1 and
 §4.3.2. Both schema questions move to CONFIRMED. Closes **11-2**.
- **§9 worked example** updated: the Move 3 walkthrough's `engagement_code_issuance` and
 `proposal_within_tariff` are `commitment_act` values with `commitment_class: irreversible` beside them,
 and its `magnitude_limit` object becomes an integer count.
- **§11** gains **11-16**, the enforcement item. Outstanding before v1.0 falls from five to two: 11-5 and
 11-16.

**Why v0.3 publishes at the `/v1` extension URI, and why that satisfies §3.1.** The URI identifies the
*extension*, not the document; §3.1 freezes it and requires a version increment only for an **incompatible
change**, with `/v1` remaining resolvable. Everything in v0.3 is additive at the extension level: a new
claim (`commitment_act`), a wire contract for methods §3.6 already named, new error names, and a
canonicalisation that replaces a placeholder. §3.7.6 states the same rule for method evolution.

**The one genuine break is named rather than glossed:** `magnitude_limit` changes from an object to an
integer. That is incompatible in principle — but the field it changes carried `IMPLEMENTATION PENDING` and
was marked a proposal in v0.1, **no implementation of it exists anywhere**, and **no counterparty has ever
activated this extension**, so there is no deployed reader whose parse it can break. A `/v2` here would
freeze a placeholder into the URI space and buy nothing. Recorded so that a later reader can judge the
call rather than discover it.

⚠ **What this release does not do.** It specifies. Nothing in it is implemented or enforced: CM-1…CM-6 fail
6 of 6 and WC-1…WC-7 fail 7 of 7 as of 2026-09-01. See **§11-16**.

### v0.1 — 2026-08-09 — initial draft

Nights 1–2. Nine design deviations raised and resolved during drafting (internal register). Published at the extension URI.

---

## Feedback

This draft is published for community review. Comment, objection, and implementation experience are all
welcome — in particular where a normative requirement is unimplementable, ambiguous, or wrong.

**contact@viccaone.com**

---

*Governed Crossing v0.4.4 DRAFT · ANAX Standard — ANAX Institute · 2026-09-17*
*Extension URI: `https://anaxstandard.ai/ext/governed-crossing/v1` · Verification Authority: `verify.anaxstandard.ai`*
