Skip to content
Version v0.2 (draft)
ChangelogContributing

Orders and execution reports

The order state machine and what the executor reports.

The executor accepts POST /v1/orders with { "decision": {...}, "signature": "<hex>" }. Before anything reaches the venue it MUST:

  1. verify the signature against the authorizer’s keys (A2M_BAD_SIGNATURE, 422),
  2. parse the payload strictly (A2M_BAD_DECISION, 422),
  3. check that the caller is the agent the decision was signed for (A2M_AGENT_UNKNOWN, 401),
  4. accept only an executable verdict (A2M_NOT_AUTHORIZED, 422),
  5. accept only an enforcement mode it implements (A2M_ENFORCEMENT, 422),
  6. refuse an expired decision (A2M_DECISION_EXPIRED, 422),
  7. refuse a venue it has no route to (A2M_NO_ROUTE, 422) or that is unavailable (A2M_VENUE_DOWN, 503),
  8. refuse any order type or time in force the venue does not declare in its capabilities (A2M_ORDER_TYPE, A2M_TIME_IN_FORCE, 422). If capabilities cannot be read, it fails closed. It MUST NOT coerce the combination into one the venue accepts.

A refusal voids the decision and releases its reservation.

The authorizer mints client_order_id when it issues an executable decision: the prefix co_ followed by 32 hex characters, 35 characters in all, so the value fits venue fields capped at 36. A minted id is never reused.

The executor treats that id as the idempotency and reconciliation key:

  • A repeat submit of the same decision returns the existing order.
  • The same client_order_id with a different decision_id is refused (A2M_IDEMPOTENCY, 409).

If a venue needs a different format, the adapter derives it deterministically from this id.

new, pending_new, acked, partially_filled, filled, cancelled, rejected, expired, unknown.

Terminal states: filled, cancelled, rejected, expired.

From Allowed to
new pending_new, rejected
pending_new acked, partially_filled, filled, rejected, expired, unknown, cancelled
acked partially_filled, filled, cancelled, expired, unknown
partially_filled partially_filled, filled, cancelled, expired, unknown
unknown acked, partially_filled, filled, cancelled, rejected, expired (only through reconciliation)

Any other move is A2M_ORDER_STATE (409).

new --> pending_new --> acked --> partially_filled --> filled
| | |
| +--> cancelled / expired
+--> rejected
+--> unknown --(reconcile by client_order_id)--> any outcome

unknown means the executor cannot tell whether the venue has the order (a lost acknowledgement or an ambiguous send). It leaves unknown only through reconciliation against the venue on client_order_id. The executor never resends blindly (A2M_BLIND_RESEND).

The execution report is not a separately signed object. It is made of:

Order view (GET /v1/agent/orders/{id}, MCP a2m_order_status): client_order_id, decision_id, venue, venue_order_id, state, time_in_force, filled_qty, avg_px, fees, last_error.

Execution (executor to authorizer, service to service): fill_id, user_id, instrument, side, qty, price, fee, reservation_id, client_order_id, venue, external, release_remainder. The authorizer de-duplicates by fill_id and settles the reservation.

Release: returns the unused part of a hold when an order ends.

The executor writes order changes, fills and outgoing messages in one transaction and delivers them to the authorizer through an outbox, so a crash cannot lose a fill.

A signed execution report is planned.

POST /v1/orders/{id}/cancel (MCP a2m_cancel_order) asks the venue to cancel one of the agent’s working orders by client order id. The executor confirms the result against a venue snapshot. An agent asking about an order that is not its own gets the same answer as for an order that does not exist.

  • If the order is already terminal, the call returns the order.
  • If the order is in unknown, the executor refuses (A2M_UNKNOWN, 409). The order must be reconciled before it can be cancelled.
  • If the cancel has been sent but the venue still shows the order working, or does not yet list it (an asynchronous cancel), the executor answers A2M_CANCEL_PENDING (409) and does not mark the order cancelled. Reconciliation settles it. This is not a successful cancel.