Cross-cutting¶
universal scenarios run for every adapter. capability:cross_cutting.* scenarios run only when the adapter's capabilities-coverage.yaml declares that slug applicable. Event/command names are the canonical PQ taxonomy (Pq.Adapters.Framework/pq-events.yaml).
Generated from the matrix
20 scenarios, from Matrix v9. See Adapter Acceptance Tests for how a scenario is written, what the waves mean, and which verdicts a run can record.
| Scenario | Purpose | Stimulus | Wave |
|---|---|---|---|
| AAT-CROSS-CUTTING-UNIVERSAL-01 | The adapter connects to the device and reports itself online. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-02 | A link that goes silent mid-session is detected and reported, then recovered on reconnect. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-03 | A command that reaches the device is confirmed, not silently dropped. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-07 | An operator command is confirmed by its paired audited event in the remote form, with attribution. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-04 | An audited event that occurs while disconnected is recovered on reconnect, once. | human | 3 |
| AAT-CROSS-CUTTING-UNIVERSAL-05 | A vendor event code the adapter does not map is surfaced, never silently swallowed. | human | 3 |
| AAT-CROSS-CUTTING-UNIVERSAL-06 | An invalid credential configuration is rejected, not accepted and silently ignored. | pq | 1 |
| AAT-CROSS-CUTTING-TIME-SYNC-01 | The adapter writes the device clock and the change is observable. | pq | 1 |
| AAT-CROSS-CUTTING-SUPERVISION-01 | A device tamper is reported and its restore is reported too. | human | 4 |
| AAT-CROSS-CUTTING-SUPERVISION-02 | A power/battery fault is reported and restored. | human | 4 |
| AAT-CROSS-CUTTING-SUPERVISION-03 | A missing/supervised module is reported and restored. | human | 4 |
| AAT-CROSS-CUTTING-DISCOVERY-01 | Importing the device configuration builds a tree matching the physical panel. | pq | 1 |
| AAT-CROSS-CUTTING-DISCOVERY-02 | Re-importing does not duplicate Things and preserves reconciled properties. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-08 | A command aimed at a Thing the running adapter does not hold fails fast with a reason. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-09 | Restarting the adapter neither duplicates audited history nor re-pushes unchanged data. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-14 | State is read back from the device after startup, not merely accumulated from events. | pq | 1 |
| AAT-CROSS-CUTTING-COMMAND-TARGETING-01 | A command is confirmed on the Thing it was issued for, never on a sibling sharing its command — on every type where the rig offers a pair. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-11 | A command issued while the channel is held exclusively is refused, not deadlocked. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-15 | A protocol message split across transport segments is reassembled before it is parsed. | pq | 1 |
| AAT-CROSS-CUTTING-UNIVERSAL-13 | An event addressed to a Thing that is not modeled stays visible instead of being dropped. | human | 3 |
Universal: connection & liveness¶
AAT-CROSS-CUTTING-UNIVERSAL-01¶
The adapter connects to the device and reports itself online.
| Applies when | universal |
| Stimulus | pq · wave 1 |
Given. The adapter is configured for a reachable device.
When. The adapter starts.
Then. It establishes the session and PQ sees it online.
PQ-visible behavior. Adapter presence goes online, pq.event.system.adapter.started is observed for the adapter and its Things reach lifecycle.ready, with no authentication/session errors in trace. A cold start raises no pq.event.connection.restored — "restored" states a recovery, and nothing was lost yet; that event belongs to AAT-CROSS-CUTTING-UNIVERSAL-02.
Steps.
- expect:
- kind=presence
- type=pq.event.system.adapter.started;thing={root}
- state=lifecycle.ready;thing={root}
timeout: 120
- require: thing={root};state=lifecycle.ready
AAT-CROSS-CUTTING-UNIVERSAL-02¶
A link that goes silent mid-session is detected and reported, then recovered on reconnect.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Hardware | A way to silence the link without closing the socket. |
| Preconditions | adapter_connected |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-01 |
| Since | Matrix v4 |
Given. The adapter is online with an established session carrying traffic.
When. The link goes silent while that session is up — no data passes in either direction and the socket is neither closed nor reset, exactly as a severed cable behaves — and is later restored.
Then. PQ reports the loss and, on reconnect, the recovery.
PQ-visible behavior. pq.event.connection.lost within the keepalive/watchdog window after the link falls silent, then pq.event.connection.restored once traffic resumes; presence tracks offline→online. The detection must come from the adapter's own keepalive or watchdog: an adapter that only notices a link failure when the socket closes will never report the loss here, which is the point of the scenario. Reconnect attempts during the outage are neither refused nor closed — they carry no traffic.
Physical acts.
cut_link— the link between the adapter and the device, left silent and then restored · performed by the lab:lab link cut
Steps.
- stimulus: cut_link
expect:
- type=pq.event.connection.lost;thing={root}
timeout: 180
- stimulus: cut_link
restore: True
expect:
- type=pq.event.connection.restored;thing={root}
timeout: 180
AAT-CROSS-CUTTING-UNIVERSAL-03¶
A command that reaches the device is confirmed, not silently dropped.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Preconditions | adapter_connected |
Given. The adapter is online and accepts at least one command.
When. An operator issues a supported command from PQ.
Then. The adapter reports the command outcome.
PQ-visible behavior. The command result carries the outcome — success or failure with a reason — and is never lost. Only a failure is additionally audited as pq.event.technical.command.failed; success has no audited event of its own, because the effect the operator asked for is what the domain event or status reports.
Steps.
AAT-CROSS-CUTTING-UNIVERSAL-07¶
An operator command is confirmed by its paired audited event in the remote form, with attribution.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Preconditions | adapter_connected |
| Since | Matrix v3 |
Given. The adapter is online and supervises at least one state-changing or momentary command via an audited execution event (ExecuteCommand event-supervision).
When. An operator issues such a command from PQ and the device executes it.
Then. The device's execution event surfaces paired to the command — in its remote variant, carrying the operator identity and the device timestamp.
PQ-visible behavior. The confirming audit event arrives as the remote variant of the action (pq.event.intrusion.armed.remote, pq.event.access.door.unsecured.remote, ...) with the operator identity from the command and the device-side timestamp — never the local/plain variant and never an unknown/unattributed actor. The timestamp is the device's own, carries a timezone offset, and is not substituted by adapter wall-clock. A local/plain variant for an operator-issued command means the command→event pairing was severed (the command was concluded by ACK or a state read-back instead of the event) and is a fail. Commands documented as ACK-only (no audited execution event exists for them) are exempt.
Steps.
- command: {any_supervised_command}
on: {any_commandable_thing}
expect:
- type=.remote;kind=event
timeout: 60
Universal: audit visibility (RULE-020/026/027)¶
AAT-CROSS-CUTTING-UNIVERSAL-04¶
An audited event that occurs while disconnected is recovered on reconnect, once.
| Applies when | universal |
| Stimulus | human · wave 3 |
| Hardware | A device that buffers events offline and a way to trip one event. |
| Preconditions | adapter_connected |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-02, AAT-CROSS-CUTTING-UNIVERSAL-07 |
Given. The adapter is online and the device buffers events while we are away.
When. The link is cut, an audited event is caused on the device, then the link is restored.
Then. The buffered event arrives after reconnect with its device timestamp, exactly once.
PQ-visible behavior. The event surfaces on pq.event.* after reconnect carrying the device-side timestamp (not wall-clock of readback), with no duplicate on a second reconnect (replay dedup).
Physical acts.
cut_link— the link between the adapter and the device, cut for the outage and restored after it · performed by the lab:lab link cuttrip_zone— a zone the device audits, tripped while the link is down
Steps.
- stimulus: cut_link
expect:
- type=pq.event.connection.lost;thing={root}
timeout: 180
- stimulus: trip_zone
timeout: 300
- stimulus: cut_link
restore: True
expect:
- type=pq.event.connection.restored;thing={root}
- type=pq.event.intrusion;thing={zone}
order: sequence
timeout: 300
AAT-CROSS-CUTTING-UNIVERSAL-05¶
A vendor event code the adapter does not map is surfaced, never silently swallowed.
| Applies when | universal |
| Stimulus | human · wave 3 |
| Preconditions | adapter_connected |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-07 |
Given. The adapter is online.
When. The device emits an event whose meaning the adapter cannot resolve.
Then. PQ still sees it — as unresolved (address known, Thing missing) or unknown (code unmapped).
PQ-visible behavior. pq.event.device.unresolved when the address is known but no Thing exists, or pq.event.device.unknown for a genuinely unmapped code; a documented code must NOT arrive as device.unknown (that would be a false "I don't know" — RULE-020) and must never be dropped.
Physical acts.
trip_zone— a source whose resulting event code the adapter has no mapping for
Steps.
- stimulus: trip_zone
expect:
- type=pq.event.device.unresolved|pq.event.device.unknown
timeout: 180
Universal: configuration integrity¶
AAT-CROSS-CUTTING-UNIVERSAL-06¶
An invalid credential configuration is rejected, not accepted and silently ignored.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Preconditions | adapter_connected |
Given. The adapter is online.
When. A credential with a configuration the device cannot honor is pushed (e.g. wrong format).
Then. The adapter rejects it with a reason rather than reporting a phantom success.
PQ-visible behavior. The sync/credential operation reports a failure with a reason (credential enrollment failed / command failed), and the bad credential does not appear as synced.
Steps.
- command: pq.command.access.synchronize
on: {root}
expect:
- type=pq.event.access.credential.enrollment.failed|pq.event.technical.command.failed
timeout: 300
Capability-conditional: time synchronization¶
AAT-CROSS-CUTTING-TIME-SYNC-01¶
The adapter writes the device clock and the change is observable.
| Applies when | capability:cross_cutting.time_synchronization |
| Stimulus | pq · wave 1 |
| Capability | cross_cutting.time_synchronization |
| Preconditions | adapter_connected |
Given. The adapter declares time synchronization and the device clock is writable.
When. A time sync is triggered (startup or periodic resync).
Then. The device clock is set to PQ time.
PQ-visible behavior. pq.event.system.time.changed (or the adapter's time-sync confirmation) reflects the device clock moving to PQ time; subsequent device event timestamps align with PQ time.
Steps.
Capability-conditional: health & supervision¶
AAT-CROSS-CUTTING-SUPERVISION-01¶
A device tamper is reported and its restore is reported too.
| Applies when | capability:cross_cutting.health_and_supervision |
| Stimulus | human · wave 4 |
| Capability | cross_cutting.health_and_supervision |
| Hardware | Physical access to open a tamper switch (enclosure/cover). |
| Preconditions | adapter_connected |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-07 |
Given. The device exposes a tamper signal.
When. A tamper is caused on the device, then cleared.
Then. PQ sees the tamper and, separately, the restore.
PQ-visible behavior. pq.event.intrusion.tamper (or supervision fault) on tamper, then pq.event.intrusion.tamper.cleared on restore — both directions routed, restore not swallowed.
Physical acts.
tamper— the tamper-protected enclosure or cover of the panel or a peripheral
Steps.
- stimulus: tamper
expect:
- type=pq.event.intrusion.tamper|pq.event.supervision.fault
timeout: 180
- stimulus: tamper
restore: True
expect:
- type=pq.event.intrusion.tamper.cleared|pq.event.supervision.fault.cleared
timeout: 180
AAT-CROSS-CUTTING-SUPERVISION-02¶
A power/battery fault is reported and restored.
| Applies when | capability:cross_cutting.health_and_supervision |
| Stimulus | human · wave 4 |
| Capability | cross_cutting.health_and_supervision |
| Hardware | Ability to disconnect mains or battery safely on the rig. |
| Preconditions | adapter_connected |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-07 |
Given. The device exposes power/battery supervision.
When. A power or battery fault condition is induced, then removed.
Then. PQ sees the fault and the return to normal.
PQ-visible behavior. pq.event.technical.battery.low / .fault (or mains fault) on the condition, then pq.event.technical.battery.normal / fault.cleared on restore.
Physical acts.
power_fault— the panel's mains supply or its backup battery
Steps.
- stimulus: power_fault
expect:
- type=pq.event.technical.battery|pq.event.technical.power
timeout: 300
- stimulus: power_fault
restore: True
expect:
- type=pq.event.technical.battery|pq.event.technical.power
timeout: 300
AAT-CROSS-CUTTING-SUPERVISION-03¶
A missing/supervised module is reported and restored.
| Applies when | capability:cross_cutting.health_and_supervision |
| Stimulus | human · wave 4 |
| Capability | cross_cutting.health_and_supervision |
| Hardware | A removable bus module/peripheral on the rig. |
| Preconditions | adapter_connected |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-07 |
Given. The device supervises the presence of expansion modules/peripherals.
When. A supervised module is removed from the bus, then reconnected.
Then. PQ sees the supervision fault and its clear.
PQ-visible behavior. pq.event.supervision.fault or pq.event.system.device.module.missing on removal, then the corresponding restore/enabled event on reconnection.
Physical acts.
remove_module— a supervised expansion module or peripheral on the device bus
Steps.
- stimulus: remove_module
expect:
- type=pq.event.supervision.fault|pq.event.system.device.module.missing
timeout: 300
- stimulus: remove_module
restore: True
expect:
- type=pq.event.supervision|pq.event.system.device.module
timeout: 300
Capability-conditional: configuration discovery (cluster 0)¶
AAT-CROSS-CUTTING-DISCOVERY-01¶
Importing the device configuration builds a tree matching the physical panel.
| Applies when | capability:cross_cutting.configuration_discovery |
| Stimulus | pq · wave 1 |
| Capability | cross_cutting.configuration_discovery |
| Preconditions | adapter_connected |
Given. The device holds a real configuration (zones, partitions, readers, doors).
When. pq.command.config.import runs.
Then. PQ's device tree reflects the panel's actual configuration.
PQ-visible behavior. After import, lab tree shows the panel's real counts and names of zones, partitions and readers; the user confirms they match the physical panel. This tree serves as the precondition for all later scenarios (setup = test).
Steps.
- command: pq.command.config.discover
on: {root}
expect:
- kind=commandResult;result=success;thing={root}
timeout: 600
What the steps cannot decide. Whether the discovered tree matches the physical panel is a comparison against the rig, not a record on the timeline — the steps only prove the import ran to completion.
AAT-CROSS-CUTTING-DISCOVERY-02¶
Re-importing does not duplicate Things and preserves reconciled properties.
| Applies when | capability:cross_cutting.configuration_discovery |
| Stimulus | pq · wave 1 |
| Capability | cross_cutting.configuration_discovery |
| Preconditions | adapter_connected |
Given. The device tree was already imported once.
When. pq.command.config.import runs a second time with an unchanged device.
Then. The tree is stable — no duplicate Things, ref properties and names preserved.
PQ-visible behavior. lab tree --json before/after the second import is equivalent (no new Thing ids, tri-state deviceRefs and preserved names honored per the discovery reconciliation contract).
Steps.
- command: pq.command.config.discover
on: {root}
expect:
- kind=commandResult;result=success;thing={root}
timeout: 600
What the steps cannot decide. The verdict is the equivalence of two lab tree --json dumps taken around the second import. That comparison has no shape on the timeline, so the steps only carry the import itself.
Universal: registry, restart & state recovery¶
AAT-CROSS-CUTTING-UNIVERSAL-08¶
A command aimed at a Thing the running adapter does not hold fails fast with a reason.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Preconditions | adapter_connected |
| Since | Matrix v4 |
Given. A Thing exists in PQ's device tree but not in the running adapter's registry — the state after a configuration change without a restart. The registry is built at startup only, so lab tree restore <node> without a following restart reproduces it deterministically.
When. An operator issues a supported command on that Thing.
Then. The adapter reports the command as failed, naming the unresolved target.
PQ-visible behavior. pq.event.technical.command.failed carrying a not-ready / device-not-found reason within the command timeout. The command never hangs and never reports success. After a restart the same command succeeds — proving the failure was the stale registry, not a broken command path.
Steps.
- command: {any_supported_command}
on: {unregistered_thing}
expect:
- type=pq.event.technical.command.failed;thing={unregistered_thing}
reject:
- kind=commandResult;result=success;thing={unregistered_thing}
timeout: 60
- command: pq.command.restart
on: {root}
expect:
- state=lifecycle.ready;thing={root}
timeout: 180
- command: {any_supported_command}
on: {unregistered_thing}
expect:
- kind=commandResult;result=success;thing={unregistered_thing}
timeout: 60
AAT-CROSS-CUTTING-UNIVERSAL-09¶
Restarting the adapter neither duplicates audited history nor re-pushes unchanged data.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Preconditions | adapter_connected |
| Since | Matrix v4 |
Given. The adapter is online with an imported tree and a completed synchronization.
When. The adapter is stopped and started again with unchanged configuration and unchanged PQ data.
Then. It comes back to the same picture without replaying what PQ already holds.
PQ-visible behavior. After restart the tree is identical; no audit event arrives a second time with a device timestamp already seen before the restart (replay dedup holds); and no synchronization operation runs against unchanged input. Presence returns online without an error burst.
Steps.
- restart: process
- expect:
- type=pq.event.connection.restored;thing={root}
timeout: 300
- reject:
- type=pq.event.access.synchronization.started;thing={root}
timeout: 60
What the steps cannot decide. Replay dedup is a comparison of device timestamps seen before and after the restart, which no single expectation expresses; the steps prove the adapter came back and re-pushed nothing.
AAT-CROSS-CUTTING-UNIVERSAL-14¶
State is read back from the device after startup, not merely accumulated from events.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Topology | 1× door / partition / detector / output |
| Preconditions | adapter_connected |
| Since | Matrix v4 |
Given. A stateful Thing is put into a non-default state through PQ (bypass a zone, arm a partition, hold a door open) and PQ observes that state.
When. The adapter is restarted while the device stays in that non-default state.
Then. PQ shows the device's real state after startup, without needing a new event to learn it.
PQ-visible behavior. The Thing's status after startup matches the state the device is actually in. An adapter that only accumulates state from the event stream shows the default/stale value here and reports a state PQ never left — a fail. Targets are chosen from the discovered topology, so the scenario covers whichever stateful types the rig actually has.
Steps.
- command: {any_state_command}
on: {any_stateful_thing}
expect:
- kind=event;thing={any_stateful_thing}
timeout: 60
- require: thing={any_stateful_thing};state={non_default_state}
- restart: process
- expect:
- kind=status;thing={any_stateful_thing}
timeout: 300
- require: thing={any_stateful_thing};state={non_default_state}
Universal: command addressing fidelity¶
AAT-CROSS-CUTTING-COMMAND-TARGETING-01¶
A command is confirmed on the Thing it was issued for, never on a sibling sharing its command — on every type where the rig offers a pair.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Topology | 2× door / partition / zone / output / switch on distinct addresses |
| Preconditions | adapter_connected |
| Since | Matrix v8 |
Given. Every type of which the rig holds two or more commandable siblings on distinct addresses — relays and outputs, zones, partitions, doors.
When. An operator issues the type's command on A, and then, separately, on B.
Then. Each command is confirmed on the Thing it was issued for, and the two confirmations name different Things — for every such type, not merely for one of them.
PQ-visible behavior. The command on A yields its confirming event carrying A's node id; the same command on B yields its confirming event carrying B's node id. The two node ids differ, and neither command confirms on the other's Thing. Where the protocol confirms by status read-back instead of an event, the same assertion applies to the status target. A shared, transposed or off-by-one address shows up here as both commands confirming on one Thing. The concern is addressing, not the domain, and it is not one address family: a panel that gets doors right can still transpose relay outputs or zones, because each type is addressed by its own scheme on the wire. So the scenario is run once per type that offers a pair — every one of them must hold for the verdict, and a type with only one instance on the rig is simply not covered here. The partition variant (AAT-INTRUSION-TARGETING-01) folds into this scenario once requires_topology can select on a declared command rather than on a category.
Steps.
- command: pq.command.access.open
on: {door}
expect:
- type=pq.event.access.door.unsecured.remote;thing={door}
reject:
- type=pq.event.access.door.unsecured;thing={door2}
timeout: 30
- command: pq.command.access.open
on: {door2}
expect:
- type=pq.event.access.door.unsecured.remote;thing={door2}
reject:
- type=pq.event.access.door.unsecured;thing={door}
timeout: 30
Strengthening. When both Things report an independently readable state — a door contact, a partition's armed state, a relay's on/off — additionally assert that the sibling's state stays unchanged during the other's command. This raises the scenario to observed evidence but is not required for a verdict.
What the steps cannot decide. The steps carry one pair — doors, where requires_topology can express the requirement. The runner repeats the same shape for every other type holding a pair (relays/outputs, zones, partitions), and the verdict holds only when all of them targeted correctly. A type whose confirmation is a status rather than an event is asserted on the status target instead.
Universal: channel arbitration¶
AAT-CROSS-CUTTING-UNIVERSAL-11¶
A command issued while the channel is held exclusively is refused, not deadlocked.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Preconditions | adapter_connected |
| Since | Matrix v4 |
Given. The adapter holds the protocol channel exclusively for a long operation (configuration discovery, history read, bulk synchronization).
When. An operator issues a command while that operation is in flight.
Then. The command is refused with a busy outcome, and succeeds once the channel frees up.
PQ-visible behavior. The command result is Busy (or pq.event.technical.command.failed with a busy reason) — never a hang until timeout and never interleaved bytes corrupting the exclusive exchange. Re-issuing the same command after the operation completes succeeds.
Steps.
- command: pq.command.config.discover
on: {root}
timeout: 30
- command: {any_supported_command}
on: {any_commandable_thing}
expect:
- type=pq.event.technical.command.failed;thing={any_commandable_thing}
timeout: 60
- expect:
- kind=commandResult;result=success;thing={root}
timeout: 600
- command: {any_supported_command}
on: {any_commandable_thing}
expect:
- kind=commandResult;result=success;thing={any_commandable_thing}
timeout: 60
Universal: transport framing¶
AAT-CROSS-CUTTING-UNIVERSAL-15¶
A protocol message split across transport segments is reassembled before it is parsed.
| Applies when | universal |
| Stimulus | pq · wave 1 |
| Preconditions | adapter_connected |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-03 |
| Since | Matrix v4 |
Given. A baseline run has established the PQ-visible result of an exchange whose payload exceeds one segment — a command with its confirming event, a status poll, or a configuration import.
When. The same exchange runs again with the transport delivering the payload in small fragments.
Then. The adapter produces the same result as the baseline.
PQ-visible behavior. The fragmented run yields the same PQ events and status values as the baseline, with no parse or checksum errors and no partial-frame timeouts in trace. An adapter that reads per transport read instead of per protocol frame fails here — it drops, truncates or mis-parses the split message. This is a common defect that a healthy link never exposes, which is why it is worth forcing. lab link fragment supplies the fragmentation. Adapters whose transport is not a byte stream — vendor SDK owning its own framing, datagram-only protocols — record n_a, since reassembly is not theirs to get wrong. Keep the per-byte delay well inside the adapter's own response timeout. Chosen too large, the exchange times out and the scenario measures the timeout instead of reassembly, which reads as a failure the adapter did not commit. Size the delay so the longest expected frame still completes within that timeout, and record the settings used with the verdict.
Steps.
- command: {any_supported_command}
on: {any_commandable_thing}
expect:
- kind=commandResult;result=success;thing={any_commandable_thing}
timeout: 60
- fragment: True
- command: {any_supported_command}
on: {any_commandable_thing}
expect:
- kind=commandResult;result=success;thing={any_commandable_thing}
timeout: 120
- fragment: False
What the steps cannot decide. The verdict is the equality of the fragmented run's events and status values with the baseline run's, which only a comparison of the two windows shows; the steps carry both runs and prove each completed.
Universal: unresolved addressing (pairs with UNIVERSAL-05)¶
AAT-CROSS-CUTTING-UNIVERSAL-13¶
An event addressed to a Thing that is not modeled stays visible instead of being dropped.
| Applies when | universal |
| Stimulus | human · wave 3 |
| Hardware | A zone the user can physically trip. |
| Preconditions | adapter_connected, thing_omitted_from_tree |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-01, AAT-CROSS-CUTTING-UNIVERSAL-05 |
| Since | Matrix v4 |
Given. The device knows a source that PQ does not model — one trippable zone is left out of the imported tree and the adapter is restarted so its registry omits it too.
When. That source produces an event on the device.
Then. PQ still sees the event, marked as addressed to an unresolved target.
PQ-visible behavior. pq.event.device.unresolved on the panel carrying the source address in its payload, within the routing window. Silence is a fail: the address was decodable, so the event had a known origin and must not vanish from the audit trail.
Physical acts.
trip_zone— the zone omitted from the tree
Steps.