Skip to content

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.

- require: thing={camera};state=lifecycle.ready

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 still
  • restore_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.

- stimulus: trip_zone
  expect:
    - type=pq.event.video.analytics;thing={camera}
  timeout: 120

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.