Skip to content
Version v0.1 (draft)
ChangelogContributing

Objects

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.

A refusal voids the decision and releases its reservation.

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).

In v0.1 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.