AXIAM PHP SDK

ReactorEvents
in package

FinalYes

The CONTRACT.md §22.5 event registry, §22.8's budget constants and §22.1's topology helpers.

The registry is served live at GET /api/v1/reactors/events, and that is the copy an admin UI SHOULD read. This class restates it because a reactor runtime has to validate an incoming event name and a handler's patch keys on the delivery path, where a network call is not available — the same reason the contract restates it in prose and the server keeps it as pure data in crates/axiam-core/src/models/reactor.rs.

WHAT IS DELIBERATELY ABSENT IS LOAD-BEARING. The three hot-path decision operations — the single authorization check, the batch check and token introspection — are not hookable (§22.7, a MUST NOT), so they appear in no constant, no list and no example anywhere under src/Reactor/. Their wire names are not written here either, so ReactorHotPathExclusionTest can enforce the rule with a plain scan of this directory rather than a judgement call about which mentions are innocent.

The reason is arithmetic, not policy: a reactor round-trip is milliseconds and the check path's budget is microseconds. An application that needs external input on an authorization decision writes a deny grant, which the engine evaluates in the hot path at hot-path cost.

Table of Contents

Constants

CHAIN_CEILING_MS  : mixed = 5000
Wall-clock ceiling on a whole dispatch chain (§22.8). Reactors not reached inside it are **not contacted**, and each of their own failure policies is applied anyway — so an unreached `fail_closed` veto still denies.
DEFAULT_TIMEOUT_MS  : mixed = 500
The per-dispatch timeout a registration gets when it names none (§22.8).
EXCHANGE  : mixed = 'axiam.reactor.events'
The topic exchange every reactor event is published to (§22.1). The SERVER declares it; a reactor runtime never does.
EXCHANGE_TYPE  : mixed = 'topic'
Type of {@see self::EXCHANGE} (§22.1). Stated for assertions and admin tooling only — a reactor never declares an exchange.
FAIL_CLOSED  : mixed = 'fail_closed'
Failure policy (§22.8): deny the underlying operation, with an audited reason naming the failure.
FAIL_OPEN  : mixed = 'fail_open'
Failure policy (§22.8): proceed as if the reactor had replied `allow`.
GRANT_PRE_ASSIGN  : mixed = 'grant.pre_assign'
Fires before a role or permission assignment. Veto-only — four-eyes workflows live here.
LOGIN_POST_AUTH  : mixed = 'login.post_auth'
Fires after credentials verify and before any session or token is issued — on password login, on SAML ACS and on the OIDC callback alike (§22.5, SEC-095). Veto-only, and the only event on which `require_mfa` is meaningful.
MAX_TIMEOUT_MS  : mixed = 5000
Upper bound on `timeout_ms` at registration (§22.8).
MIN_TIMEOUT_MS  : mixed = 1
Lower bound on `timeout_ms` at registration; `0` is refused (§22.8).
MODE_INTERCEPT  : mixed = 'intercept'
Registration mode (§22.9): synchronous request/response — the server waits and the reply can veto or mutate within the event's allow-list.
MODE_LISTEN  : mixed = 'listen'
Registration mode (§22.5): fire-and-forget observation. The server never waits and never reads a reply, so a listener cannot affect any outcome — and a listener handler MUST NOT publish one.
TOKEN_PRE_ISSUE  : mixed = 'token.pre_issue'
Fires before an access token is issued. Mutable: claims under the `ext.` namespace only.
USER_PRE_CREATE  : mixed = 'user.pre_create'
Fires before a user is created.
USER_PRE_UPDATE  : mixed = 'user.pre_update'
Fires before a user profile is updated.

Methods

all()  : array<int, ReactorEventSpec>
The §22.5 registry, mirroring `EVENT_REGISTRY` in `crates/axiam-core/src/models/reactor.rs`.
assertHookable()  : void
Assert that $event is a hookable §22.5 registry event, or throw.
defaultFailurePolicy()  : string
Composes the failure policy a registration naming none inherits from its events (§22.8): the **strictest default wins**, in either array order.
queueName()  : string
Renders the durable per-reactor queue the **server** declares: `axiam.reactor.q.<tenant_id>.<reactor_id>` (§22.1). Mirrors `queue_name()` in `crates/axiam-amqp/src/reactor/protocol.rs`.
routingKey()  : string
Renders the topic routing key for one event: `<tenant_id>.<event>` (§22.1).
specFor()  : ReactorEventSpec|null
Looks an event up by wire name, returning null for any name outside the §22.5 registry.

Constants

CHAIN_CEILING_MS

Wall-clock ceiling on a whole dispatch chain (§22.8). Reactors not reached inside it are **not contacted**, and each of their own failure policies is applied anyway — so an unreached `fail_closed` veto still denies.

public mixed CHAIN_CEILING_MS = 5000

DEFAULT_TIMEOUT_MS

The per-dispatch timeout a registration gets when it names none (§22.8).

public mixed DEFAULT_TIMEOUT_MS = 500

EXCHANGE

The topic exchange every reactor event is published to (§22.1). The SERVER declares it; a reactor runtime never does.

public mixed EXCHANGE = 'axiam.reactor.events'

EXCHANGE_TYPE

Type of {@see self::EXCHANGE} (§22.1). Stated for assertions and admin tooling only — a reactor never declares an exchange.

public mixed EXCHANGE_TYPE = 'topic'

FAIL_CLOSED

Failure policy (§22.8): deny the underlying operation, with an audited reason naming the failure.

public mixed FAIL_CLOSED = 'fail_closed'

FAIL_OPEN

Failure policy (§22.8): proceed as if the reactor had replied `allow`.

public mixed FAIL_OPEN = 'fail_open'

GRANT_PRE_ASSIGN

Fires before a role or permission assignment. Veto-only — four-eyes workflows live here.

public mixed GRANT_PRE_ASSIGN = 'grant.pre_assign'

LOGIN_POST_AUTH

Fires after credentials verify and before any session or token is issued — on password login, on SAML ACS and on the OIDC callback alike (§22.5, SEC-095). Veto-only, and the only event on which `require_mfa` is meaningful.

public mixed LOGIN_POST_AUTH = 'login.post_auth'

MAX_TIMEOUT_MS

Upper bound on `timeout_ms` at registration (§22.8).

public mixed MAX_TIMEOUT_MS = 5000

MIN_TIMEOUT_MS

Lower bound on `timeout_ms` at registration; `0` is refused (§22.8).

public mixed MIN_TIMEOUT_MS = 1

MODE_INTERCEPT

Registration mode (§22.9): synchronous request/response — the server waits and the reply can veto or mutate within the event's allow-list.

public mixed MODE_INTERCEPT = 'intercept'

MODE_LISTEN

Registration mode (§22.5): fire-and-forget observation. The server never waits and never reads a reply, so a listener cannot affect any outcome — and a listener handler MUST NOT publish one.

public mixed MODE_LISTEN = 'listen'

TOKEN_PRE_ISSUE

Fires before an access token is issued. Mutable: claims under the `ext.` namespace only.

public mixed TOKEN_PRE_ISSUE = 'token.pre_issue'

USER_PRE_CREATE

Fires before a user is created.

public mixed USER_PRE_CREATE = 'user.pre_create'

USER_PRE_UPDATE

Fires before a user profile is updated.

public mixed USER_PRE_UPDATE = 'user.pre_update'

Methods

all()

The §22.5 registry, mirroring `EVENT_REGISTRY` in `crates/axiam-core/src/models/reactor.rs`.

public static all() : array<int, ReactorEventSpec>

A fresh ReactorEventSpec list is built per call so a caller cannot edit the SDK's own allow-lists in place: an allow-list a caller can widen is not an allow-list.

Return values
array<int, ReactorEventSpec>

assertHookable()

Assert that $event is a hookable §22.5 registry event, or throw.

public static assertHookable(string $event) : void

The single validation both spellings of §22.14's declarative binding go through — OnReactorEvent and ReactorHandlers::bind() — so the two cannot drift apart.

Parameters
$event : string

The candidate event name.

Tags
throws
InvalidArgumentException

when $event is outside the registry. This is also how the §22.7 hot-path exclusion is enforced one layer up: those operations are in no registry row, so they fail here like any other unknown name.

defaultFailurePolicy()

Composes the failure policy a registration naming none inherits from its events (§22.8): the **strictest default wins**, in either array order.

public static defaultFailurePolicy(array<int, string> $events) : string

A reactor registered for both token.pre_issue (open) and login.post_auth (closed) can veto a login, so it inherits fail_closed. Taking the first event's default instead would let the order of a JSON array decide whether an unreachable fraud check passes — which is why §22.8 states this as a MUST NOT reimplement rather than as a note.

An unknown event name contributes fail_closed: the server will refuse the registration outright, and guessing open on a name this SDK does not recognise is the wrong way to be wrong. An empty list is fail_closed for the same reason.

Parameters
$events : array<int, string>
Return values
string

queueName()

Renders the durable per-reactor queue the **server** declares: `axiam.reactor.q.<tenant_id>.<reactor_id>` (§22.1). Mirrors `queue_name()` in `crates/axiam-amqp/src/reactor/protocol.rs`.

public static queueName(string $tenantId, string $reactorId) : string

Deriving the name is not the same as declaring it. A reactor consumes this queue and nothing else; it never declares, redeclares or binds it, and never derives a name for a reactor other than the one it is configured as. A reactor that can bind is a reactor that can bind itself to *.token.pre_issue and read another tenant's issuance events.

Parameters
$tenantId : string
$reactorId : string
Return values
string

routingKey()

Renders the topic routing key for one event: `<tenant_id>.<event>` (§22.1).

public static routingKey(string $tenantId, string $event) : string

Mirrors routing_key() in crates/axiam-amqp/src/reactor/protocol.rs.

Exported for logging, assertions and admin tooling. A reactor runtime never binds it: bindings are the server's, derived from the registration's events.

Parameters
$tenantId : string
$event : string
Return values
string

specFor()

Looks an event up by wire name, returning null for any name outside the §22.5 registry.

public static specFor(string $name) : ReactorEventSpec|null

The hot-path decision operations §22.7 excludes are absent by construction rather than by a filter that could be forgotten: they are not in self::all(), so this returns null for them like any other unknown name, and the runtime refuses such a delivery before a handler ever sees it.

Parameters
$name : string
Return values
ReactorEventSpec|null
On this page

Search results