Video (CCTV / NVR)¶
category:video = category-defining behavior (a CCTV adapter must do this at all). capability:video.* = selected when capabilities-coverage.yaml declares the slug applicable. Event/command names are the canonical PQ taxonomy (Pq.Adapters.Framework/pq-events.yaml). The physical acts reuse the existing closed stimulus vocabulary: motion in the field of view is a trip_zone (a detector walked), covering the lens is a tamper, and unplugging a camera or a disk from the recorder is a remove_module. Their fallback waves therefore apply unchanged.
Generated from the matrix
17 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-VIDEO-CHANNEL-01 | Every modeled channel is bound and readable once the adapter is online. | pq | 1 |
| AAT-VIDEO-CHANNEL-02 | A camera that loses its feed is reported as blind, and its recovery is reported too. | human | 4 |
| AAT-VIDEO-CHANNEL-03 | Two channels configured on the same device address are surfaced, not silently collapsed. | pq | 1 |
| AAT-VIDEO-LIVE-01 | A live view requested from PQ is registered and announced with the alias to play. | pq | 1 |
| AAT-VIDEO-LIVE-02 | The requested stream tier is the tier delivered, and the two tiers register separately. | pq | 1 |
| AAT-VIDEO-LIVE-03 | A live view can be re-established after the session was lost and came back. | pq | 4 |
| AAT-VIDEO-SNAPSHOT-01 | A snapshot requested from PQ is captured and stored against the camera. | pq | 1 |
| AAT-VIDEO-PLAYBACK-01 | Recorded footage for a requested time range is registered and announced. | pq | 1 |
| AAT-VIDEO-PLAYBACK-02 | Seeking within playback moves the replay to the new position instead of stacking streams. | pq | 1 |
| AAT-VIDEO-PLAYBACK-03 | Pause and resume are answered, not refused as unsupported verbs. | pq | 1 |
| AAT-VIDEO-PTZ-01 | A PTZ movement starts on command and stops on command. | pq | 1 |
| AAT-VIDEO-PRESET-01 | A stored preset can be recalled, and both operations are audited with the preset number. | pq | 1 |
| AAT-VIDEO-MOTION-01 | Motion in the camera's field of view is reported, and its end is reported too. | human | 3 |
| AAT-VIDEO-ANALYTICS-01 | A configured analytics rule that fires reaches PQ as an analytics event on its camera. | human | 3 |
| AAT-VIDEO-QUALITY-01 | Obstructing the camera is reported as degraded video, and clearing it is reported too. | human | 4 |
| AAT-VIDEO-STORAGE-01 | A recording-storage fault is reported against the recorder, not lost or misattributed. | human | 4 |
| AAT-VIDEO-TEARDOWN-01 | Streams registered before a link loss do not survive it as phantoms. | pq | 4 |
Channel discovery + online/offline (category-defining)¶
AAT-VIDEO-CHANNEL-01¶
Every modeled channel is bound and readable once the adapter is online.
| Applies when | category:video |
| Stimulus | pq · wave 1 |
| Capability | video.channel_discovery |
| Preconditions | adapter_connected, camera_modeled |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-01 |
| Since | Matrix v9 |
Given. The adapter has connected to the recorder and its channels are modeled.
When. The adapter finishes its initialization sequence.
Then. Each channel Thing is ready and its state reflects what the recorder reports for it.
PQ-visible behavior. Each channel reaches lifecycle.ready and carries no residual signal-loss state while the recorder reports it healthy. A channel modeled on an address the recorder does not serve stays unready or reports signal loss — it is not silently presented as a working camera.
Steps.
What the steps cannot decide. Whether the modeled channel set matches the recorder's own channel listing is a comparison of the imported tree against the device, which the timeline has no shape for. Adapters that model channels by configuration rather than by discovery (auto_discovery: false) cannot fail on the count — record the mismatch as partial with the observed contract, not as a failure. The steps prove the modeled channels are bound and ready.
AAT-VIDEO-CHANNEL-02¶
A camera that loses its feed is reported as blind, and its recovery is reported too.
| Applies when | category:video |
| Stimulus | human · wave 4 |
| Capability | video.channel_discovery |
| Hardware | A camera whose feed can be physically interrupted. |
| Preconditions | camera_modeled, camera_events_enabled |
| Depends on | AAT-VIDEO-CHANNEL-01 |
| Since | Matrix v9 |
Given. The modeled camera is online and its channel reads healthy.
When. The camera is disconnected from the recorder, and later reconnected.
Then. PQ reports the signal loss on that channel and, on reconnection, its clearing.
PQ-visible behavior. pq.event.video.blind on the channel with a signal-loss state, then pq.event.video.blind.cleared once the feed returns. Both paths must lead here: the recorder's own videoloss push and the adapter's status poll — the poll is what covers a recorder whose event linkage is off, so an adapter that only listens to the push reports nothing for minutes. The event carries which path produced it.
Physical acts.
remove_module— the camera feeding the modeled channel, unplugged from the recorder and then reconnected
Steps.
- stimulus: remove_module
expect:
- type=pq.event.video.blind;thing={camera}
timeout: 180
- stimulus: remove_module
restore: True
expect:
- type=pq.event.video.blind.cleared;thing={camera}
timeout: 180
What the steps cannot decide. That the adapter also tore down the streaming alias for the blind channel is state in the streaming control plane, not a record on the timeline — check that no alias for this camera survives the loss. The steps prove the loss and the recovery were both reported.
AAT-VIDEO-CHANNEL-03¶
Two channels configured on the same device address are surfaced, not silently collapsed.
| Applies when | category:video |
| Stimulus | pq · wave 1 |
| Capability | video.channel_discovery |
| Topology | 2× camera |
| Preconditions | adapter_connected, duplicate_channel_address |
| Depends on | AAT-VIDEO-CHANNEL-01 |
| Since | Matrix v9 |
Framework gap
No stable PQ-visible expression for this behavior exists yet. The scenario is kept so the gap stays counted and gets a verdict once it is closed — it does not pass today.
Given. Two camera Things carry the same protocol address — the everyday mistake on a recorder whose channels are authored by hand rather than discovered, and the one an installer makes by copying a channel and forgetting to change its number.
When. The adapter rebuilds its registry and the recorder reports on that address.
Then. PQ shows that the address is claimed twice; neither Thing is left quietly mute.
PQ-visible behavior. The address map is built once at startup and one Thing wins it. The other keeps its place in the tree, accepts commands and looks entirely healthy, while no event addressed to that channel will ever reach it again — the operator is watching a camera that can no longer report anything. Today this is a log warning inside the adapter and nothing else: no event, no state, no fault. The scenario is recorded as a framework gap until a duplicate claim is expressed PQ-side (an unresolved/configuration fault on the shadowed Thing is the obvious shape), and its verdict states what the run actually observed.
Steps.
- command: pq.command.restart
on: {root}
expect:
- kind=commandResult;result=success;thing={root}
timeout: 120
- require: thing={camera};state=lifecycle.ready
What the steps cannot decide. The verdict is what PQ shows about the duplicate, which no filter can express while nothing is published: read the adapter's own trace for the duplicate-address warning, confirm which Thing won the address, and then confirm the other receives no events while the recorder reports on that channel. Record it as the observed contract. This scenario is written to be re-run and re-verdicted once the gap is closed — it is not a pass today.
Live / playback / snapshot¶
AAT-VIDEO-LIVE-01¶
A live view requested from PQ is registered and announced with the alias to play.
| Applies when | capability:video.live_playback_snapshot |
| Stimulus | pq · wave 1 |
| Capability | video.live_playback_snapshot |
| Preconditions | adapter_connected, camera_modeled |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-03 |
| Since | Matrix v9 |
Given. The adapter is online and a camera channel is modeled.
When. An operator opens the live view of that camera.
Then. The stream is registered and PQ is told where to consume it.
PQ-visible behavior. pq.command.video.live on the channel succeeds and pq.event.video.stream.ready follows on the same channel, carrying the stream alias. A command that succeeds without announcing an alias leaves the client with nothing to play, which is a failure of this scenario, not of the client.
Steps.
- command: pq.command.video.live
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
- type=pq.event.video.stream.ready;thing={camera}
timeout: 60
What the steps cannot decide. That the announced alias actually carries video is a property of the streaming control plane, not of the timeline: confirm the alias exists there and produces frames. The steps prove the command was carried out and the alias was announced.
AAT-VIDEO-LIVE-02¶
The requested stream tier is the tier delivered, and the two tiers register separately.
| Applies when | capability:video.live_playback_snapshot |
| Stimulus | pq · wave 1 |
| Capability | video.live_playback_snapshot |
| Preconditions | adapter_connected, camera_modeled |
| Depends on | AAT-VIDEO-LIVE-01 |
| Since | Matrix v9 |
Given. The camera exposes a high-resolution main stream and a low-resolution substream.
When. An operator opens the live view at the low tier, and then at the high tier.
Then. Each request is served from its own tier, under its own alias, and both can run at once.
PQ-visible behavior. pq.command.video.live carries stream_quality — sub for the low-resolution substream, main for the high-resolution one; absent or unknown means main. Each tier is announced under its own alias, so the wall can hold a dense grid on substreams while a single detail view runs on main, and one closing does not tear the other down. An adapter with no substream answers on main — that fallback is documented, so it is partial with the observed contract, never a failure. A substream request silently served from the main stream is the defect this catches: invisible on one camera, and sixteen times the bandwidth and decode cost on a full wall.
Steps.
- command: pq.command.video.live
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
- type=pq.event.video.stream.ready;thing={camera}
timeout: 60
- command: pq.command.video.live
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
- type=pq.event.video.stream.ready;thing={camera}
timeout: 60
What the steps cannot decide. The two steps differ only in the stream_quality argument, which the step grammar cannot yet carry — the runner supplies sub on the first and main on the second, and says so with the verdict. What decides it is not on the timeline either: the two announced aliases must differ, both must be registered at the same time, and the sub tier must actually be the smaller resolution rather than the main stream under a second name. Compare the two in the streaming control plane.
AAT-VIDEO-LIVE-03¶
A live view can be re-established after the session was lost and came back.
| Applies when | capability:video.live_playback_snapshot |
| Stimulus | pq · wave 4 |
| Capability | video.live_playback_snapshot |
| Hardware | A way to interrupt the link between the adapter and the recorder. |
| Preconditions | live_stream_registered |
| Depends on | AAT-VIDEO-TEARDOWN-01 |
| Since | Matrix v9 |
Given. A live stream is running when the link to the recorder is lost.
When. The link is restored and an operator opens the live view again.
Then. The new request succeeds and delivers a stream that is actually live.
PQ-visible behavior. After pq.event.connection.restored, a fresh pq.command.video.live succeeds and announces an alias again. The adapter does not resurrect streams by itself — reconnection is the client's to drive — so what is certified here is that the re-request works against a session that has been through an outage. An adapter that answers success from stale registry state announces an alias pointing at a source the recorder no longer serves, and the operator gets a frozen frame that looks exactly like a working camera.
Physical acts.
cut_link— the link between the adapter and the recorder, cut 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
- command: pq.command.video.live
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
- type=pq.event.video.stream.ready;thing={camera}
timeout: 60
What the steps cannot decide. That the alias announced after the recovery carries moving, current video — rather than the pre-outage picture or a dead source — is judged in the streaming control plane; the steps prove the outage was reported, the recovery was reported, and the re-request was accepted.
AAT-VIDEO-SNAPSHOT-01¶
A snapshot requested from PQ is captured and stored against the camera.
| Applies when | capability:video.live_playback_snapshot |
| Stimulus | pq · wave 1 |
| Capability | video.live_playback_snapshot |
| Preconditions | adapter_connected, camera_modeled |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-03 |
| Since | Matrix v9 |
Given. The adapter is online and a camera channel is modeled.
When. An operator requests a still image from that camera.
Then. The image is fetched from the device and stored for that camera.
PQ-visible behavior. pq.command.video.snapshot on the channel succeeds and an image is stored server-side for that camera. A success reported without an image having arrived is the defect this catches.
Steps.
- command: pq.command.video.snapshot
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
timeout: 60
What the steps cannot decide. The image itself never appears on the timeline: confirm a non-empty image was stored for this camera and that it is the camera asked for. The steps prove the command succeeded.
AAT-VIDEO-PLAYBACK-01¶
Recorded footage for a requested time range is registered and announced.
| Applies when | capability:video.live_playback_snapshot |
| Stimulus | pq · wave 1 |
| Capability | video.live_playback_snapshot |
| Preconditions | adapter_connected, camera_modeled, recorded_footage_available |
| Depends on | AAT-VIDEO-LIVE-01 |
| Since | Matrix v9 |
Given. The recorder holds footage for the camera over a known past time range.
When. An operator opens playback of that camera for that range.
Then. A replay stream is registered and PQ is told where to consume it.
PQ-visible behavior. pq.command.video.playback on the channel succeeds and pq.event.video.stream.ready follows with a replay alias distinct from the live one, so opening playback does not disturb a live view of the same camera.
Steps.
- command: pq.command.video.playback
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
- type=pq.event.video.stream.ready;thing={camera}
timeout: 60
What the steps cannot decide. That the footage returned is the footage asked for is not on the timeline — confirm the frames come from the requested range. This is where timezone handling shows: a recorder that reads replay timestamps as local time regardless of the offset sent returns the wrong hour while every record still reads as a success. The steps prove the replay stream was registered.
AAT-VIDEO-PLAYBACK-02¶
Seeking within playback moves the replay to the new position instead of stacking streams.
| Applies when | capability:video.live_playback_snapshot |
| Stimulus | pq · wave 1 |
| Capability | video.live_playback_snapshot |
| Preconditions | adapter_connected, camera_modeled, recorded_footage_available |
| Depends on | AAT-VIDEO-PLAYBACK-01 |
| Since | Matrix v9 |
Given. A playback stream for the camera is registered.
When. An operator seeks to a different position in the recording.
Then. The replay resumes at the new position, and the previous replay stream is not left behind.
PQ-visible behavior. pq.command.video.playback.seek succeeds and the replay is announced again for the new position. An adapter that registers a second replay alias without removing the first leaks a stream per seek — the operator sees playback work while the recorder's session budget drains.
Steps.
- command: pq.command.video.playback
on: {camera}
expect:
- type=pq.event.video.stream.ready;thing={camera}
timeout: 60
- command: pq.command.video.playback.seek
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
timeout: 60
What the steps cannot decide. Whether the old replay alias was removed rather than left running is state in the streaming control plane: count the replay aliases for this camera before and after the seek — one, not two. The steps prove the seek was accepted.
AAT-VIDEO-PLAYBACK-03¶
Pause and resume are answered, not refused as unsupported verbs.
| Applies when | capability:video.live_playback_snapshot |
| Stimulus | pq · wave 1 |
| Capability | video.live_playback_snapshot |
| Preconditions | adapter_connected, camera_modeled, recorded_footage_available |
| Depends on | AAT-VIDEO-PLAYBACK-01 |
| Since | Matrix v9 |
Given. A playback stream for the camera is registered.
When. An operator pauses the playback and then resumes it.
Then. Both commands are answered with a result the client can act on.
PQ-visible behavior. pq.command.video.playback.pause and .resume each return a result. Where the protocol has no server-side pause the adapter answers success and the client pauses the video element — that is a documented contract, not a silent no-op, and the verdict is partial with the observed contract recorded. A failure result, or no result at all, leaves the client's pause button dead and is a fail.
Steps.
- command: pq.command.video.playback.pause
on: {camera}
expect:
- kind=commandResult;thing={camera}
timeout: 30
- command: pq.command.video.playback.resume
on: {camera}
expect:
- kind=commandResult;thing={camera}
timeout: 30
PTZ / presets¶
AAT-VIDEO-PTZ-01¶
A PTZ movement starts on command and stops on command.
| Applies when | capability:video.ptz_presets |
| Stimulus | pq · wave 1 |
| Capability | video.ptz_presets |
| Hardware | A camera with a motorized pan/tilt/zoom head. |
| Preconditions | adapter_connected, camera_modeled |
| Depends on | AAT-VIDEO-LIVE-01 |
| Since | Matrix v9 |
Given. The modeled camera has a controllable pan/tilt/zoom head.
When. An operator issues a continuous move and then a stop.
Then. The head moves while the move is in force and holds still after the stop.
PQ-visible behavior. Both commands succeed. PTZ carries no audited execution event — the movement is continuous and the device confirms nothing — so the command result is the record, and a stop that is not honored leaves the head drifting until it hits its limit. Cameras with a fixed lens record n_a.
Steps.
- command: pq.command.camera.ptz.move
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
timeout: 30
- command: pq.command.camera.ptz.stop
on: {camera}
expect:
- kind=commandResult;result=success;thing={camera}
timeout: 30
Strengthening. Watch the live view while the two commands run: the head moves in the commanded direction and stops where the stop was issued. This raises the scenario to observed evidence — it also catches an inverted sign or a speed scale the protocol expresses differently — but the command results carry the verdict.
What the steps cannot decide. No event confirms PTZ, so the steps are the whole mechanical record; whether the head actually moved and then held still is judged from the live view, and a fixed camera is n_a.
AAT-VIDEO-PRESET-01¶
A stored preset can be recalled, and both operations are audited with the preset number.
| Applies when | capability:video.ptz_presets |
| Stimulus | pq · wave 1 |
| Capability | video.ptz_presets |
| Hardware | A camera with a motorized head and preset storage. |
| Preconditions | adapter_connected, camera_modeled |
| Depends on | AAT-VIDEO-PTZ-01 |
| Since | Matrix v9 |
Given. The modeled camera supports presets and its head is at a distinguishable position.
When. An operator stores the current position as a preset and later activates it.
Then. Both operations are audited against the camera, naming the preset.
PQ-visible behavior. pq.command.camera.preset.store yields pq.event.video.preset.stored and pq.command.camera.preset.activate yields pq.event.video.preset.activated, each on the camera and each carrying presetNumber. A preset model that renumbers or offsets the operator's value shows up as a different number in the event than the one commanded.
Steps.
- command: pq.command.camera.preset.store
on: {camera}
expect:
- type=pq.event.video.preset.stored;thing={camera}
timeout: 30
- command: pq.command.camera.preset.activate
on: {camera}
expect:
- type=pq.event.video.preset.activated;thing={camera}
timeout: 30
What the steps cannot decide. The verdict is the equality of presetNumber in both events with the number commanded, which the filter does not read; the steps prove both operations were audited on the right camera.
Analytics¶
AAT-VIDEO-MOTION-01¶
Motion in the camera's field of view is reported, and its end is reported too.
| Applies when | capability:video.analytics |
| Stimulus | human · wave 3 |
| Capability | video.analytics |
| Hardware | A camera whose field of view a person can enter. |
| Preconditions | camera_modeled, camera_events_enabled |
| Depends on | AAT-VIDEO-CHANNEL-01 |
| Since | Matrix v9 |
Given. Motion detection is configured on the modeled camera and pushes to the adapter.
When. A person moves through the camera's field of view and then leaves it still.
Then. PQ reports the motion on that camera and, after the scene settles, its clearing.
PQ-visible behavior. pq.event.video.motion.detected on the channel that saw it, then pq.event.video.motion.cleared once the scene is still. The clearing matters as much as the detection: an adapter that only routes the active edge leaves the camera reading "motion" forever.
Physical acts.
trip_zone— the field of view of the modeled camera, walked through and then left stillrestore_zone— the field of view of the modeled camera, left still
Steps.
- stimulus: trip_zone
expect:
- type=pq.event.video.motion.detected;thing={camera}
timeout: 120
- stimulus: restore_zone
expect:
- type=pq.event.video.motion.cleared;thing={camera}
timeout: 180
AAT-VIDEO-ANALYTICS-01¶
A configured analytics rule that fires reaches PQ as an analytics event on its camera.
| Applies when | capability:video.analytics |
| Stimulus | human · wave 3 |
| Capability | video.analytics |
| Hardware | A camera with at least one analytics rule the rig can trigger. |
| Preconditions | camera_modeled, camera_events_enabled |
| Depends on | AAT-VIDEO-MOTION-01 |
| Since | Matrix v9 |
Given. One analytics rule is configured on the modeled camera — a crossed line, an entered region, a detected object — and it pushes to the adapter.
When. A person triggers that rule.
Then. PQ reports an analytics detection on that camera.
PQ-visible behavior. pq.event.video.analytics.object_detected (or the rule's own analytics event where the taxonomy carries one, e.g. .intrusion / .loitering) on the channel, naming what was detected where the protocol reports it. A rule the adapter does not map must still surface as an unknown device event rather than being dropped — a security-relevant detection is never silently discarded.
Physical acts.
trip_zone— the configured analytics rule of the modeled camera — its line, region or trigger area
Steps.
What the steps cannot decide. Several vendor rule types collapse onto one PQ analytics event, so the verdict names which rule was triggered and which event it produced. A rule that produces nothing at all is first a device-side configuration question — the rule may be recorded locally but not pushed to the adapter — and is recorded as blocked_by_hw naming the rule, not as an adapter failure, unless the trace shows the push arriving and the adapter dropping it.
AAT-VIDEO-QUALITY-01¶
Obstructing the camera is reported as degraded video, and clearing it is reported too.
| Applies when | capability:video.analytics |
| Stimulus | human · wave 4 |
| Capability | video.analytics |
| Hardware | A camera whose lens can be physically obstructed. |
| Preconditions | camera_modeled, camera_events_enabled |
| Depends on | AAT-VIDEO-CHANNEL-01 |
| Since | Matrix v9 |
Given. Tamper / obstruction detection is configured on the modeled camera.
When. The lens is covered, and later uncovered.
Then. PQ reports the degradation on that camera and, once uncovered, its restoration.
PQ-visible behavior. pq.event.video.quality.degraded on the channel while the view is obstructed, then pq.event.video.quality.restored once it is clear. Covering a lens is the cheapest attack on a camera, so a missing report here is a security gap, not a cosmetic one; where the protocol distinguishes the cause (tamper, shelter, defocus, poor video) it appears in the event.
Physical acts.
tamper— the lens or enclosure of the modeled camera, covered and then uncovered
Steps.
- stimulus: tamper
expect:
- type=pq.event.video.quality.degraded;thing={camera}
timeout: 120
- stimulus: tamper
restore: True
expect:
- type=pq.event.video.quality.restored;thing={camera}
timeout: 180
Faults & teardown¶
AAT-VIDEO-STORAGE-01¶
A recording-storage fault is reported against the recorder, not lost or misattributed.
| Applies when | capability:video.faults_and_teardown |
| Stimulus | human · wave 4 |
| Capability | video.faults_and_teardown |
| Hardware | A recorder whose storage can be removed or failed on the rig. |
| Preconditions | adapter_connected, camera_events_enabled |
| Depends on | AAT-CROSS-CUTTING-UNIVERSAL-01 |
| Since | Matrix v9 |
Given. The recorder is recording to a removable or failable storage device.
When. That storage is removed or made to fail.
Then. PQ reports a hardware fault on the recorder.
PQ-visible behavior. pq.event.technical.fault.hardware on the recorder root — disk full, disk error and storage detection are recorder-level conditions and belong on the root, not on a channel. Where the recorder additionally reports a failed recording, pq.event.video.recording.failed appears on the affected channel.
Physical acts.
remove_module— the recording storage of the recorder, removed or failed and then restored
Steps.
- stimulus: remove_module
expect:
- type=pq.event.technical.fault.hardware;thing={root}
timeout: 180
- stimulus: remove_module
restore: True
What the steps cannot decide. Whether the fault clears when the storage returns is the second half of this scenario, and many recorders report only the active edge — record what the restore produced as the observed contract. A fault that never clears leaves the recorder reading faulty until the adapter restarts, which is a limitation to state, not a silent one to leave undiscovered.
AAT-VIDEO-TEARDOWN-01¶
Streams registered before a link loss do not survive it as phantoms.
| Applies when | capability:video.faults_and_teardown |
| Stimulus | pq · wave 4 |
| Capability | video.faults_and_teardown |
| Hardware | A way to interrupt the link between the adapter and the recorder. |
| Preconditions | live_stream_registered |
| Depends on | AAT-VIDEO-LIVE-01, AAT-CROSS-CUTTING-UNIVERSAL-02 |
| Since | Matrix v9 |
Given. A live stream for the modeled camera is registered and being consumed.
When. The link between the adapter and the recorder is lost and later restored.
Then. The registered streams are torn down with the session, and nothing re-appears on its own.
PQ-visible behavior. pq.event.connection.lost, then pq.event.connection.restored once the link returns. Around them, the streams the adapter registered are released: a stream left registered after the device is gone shows an operator a frozen last frame as if it were live, which is worse than showing nothing. On reconnect the adapter does not re-register streams by itself — reconnection is the client's to drive, so a stream re-appearing without a command is equally wrong.
Physical acts.
cut_link— the link between the adapter and the recorder, cut 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
What the steps cannot decide. The aliases live in the streaming control plane, not on the timeline: check that no alias of this adapter's cameras survives the loss, and that none returns after the reconnect until a client asks for one. The steps prove the loss and the recovery were reported.