Repository navigation
Engineering onvif event verification
This record maps the implementation to issue #96
and the associated ISAPI work, published together in
draft PR #221. This is implementation
and test evidence, not physical-camera certification. The protected api/
contracts are unchanged relative to the integrated upstream main branch.
The implementation was committed as 557b433 and merged with upstream main
4ac3efe in b4c4a43. Upstream per-user camera permissions, backup and notification
metrics, configuration ownership, camera groups, and Home Assistant support are
retained. Both initial and event-triggered capability snapshots filter camera,
live-source, and stored-source collections through current camera permissions.
Every native delivery, including a capability-cache hit, rechecks session expiry
and source access. Credential-bound expiry and restricted-snapshot tests cover
this integration; production authorization was not relaxed for old test fixtures.
The complete canonical gate passes for repair commit be58e3a, with the log in
target/pr221-merged-check-2.log: 2,248 Rust tests, 266 Bun tests, 127 browser/visual
tests, 57 compatibility tests, and 204 Playwright tests. The integrated upstream
test set has 20 existing Rust skips and two codec-capability skips. Strict Clippy,
formatting, dependency checks, UI checks, and Home Assistant checks pass.
CI caught a Rust 1.98 chunk-iteration lint and Linux early callback rejection.
The callback fixture now uses bounded Expect: 100-continue, and the server's
automatic interim response omits final-response framing headers. The wire
regression and all callback tests pass. Linux also exposed a metadata relay
teardown case; d69edb1 explicitly shuts down relay-owned sockets. The unchanged
idle/playing wire tests and test-camera Clippy pass locally.
Final cross-platform status and logs are linked from PR #221 checks. A passing local gate does not substitute for a successful CI run on the final PR head. The hardware matrix and browser talkback limitations below remain open regardless of the CI result.
The complete canonical gate passes on 2026-09-06. The final log is
target/issue96-final-check-4.log. Run from the repository root:
TMPDIR=/Volumes/KeepPeekCheckTmp NEXTEST_TEST_THREADS=4 ./check.sh| Gate | Result |
|---|---|
| Rust workspace tests | 2,157 passed; 19 existing skips; 431.684 seconds |
| Strict workspace Clippy | Passed with warnings denied |
| Dependency and formatting checks | Cargo Machete, Rustfmt, Taplo, and Black passed |
| UI static checks | Public registries, Paper/visual/demo contracts, formatting, lint, Svelte, and E2E typecheck passed |
| UI unit tests | 222 Bun, 110 browser/visual, and 28 compatibility tests passed |
| Playwright | 189 passed; two existing codec-capability skips; 51.8 seconds |
The first run, target/issue96-final-check.log, stopped after 69 passing tests
and one ISAPI fake-camera failure. Accepted sockets inherited nonblocking mode
on macOS, causing an early read to close the connection before headers arrived.
An explicit blocking-mode setup plus a delayed-request regression fixed the
fixture; all four ISAPI fake-camera integration tests then passed.
The rerun is recorded in target/issue96-final-check-2.log.
That second run exposed a software-publication capability regression, which was
fixed by merging software-publication types separately from native device flags.
The existing publication/idempotence test and all 15 capability-ordering tests
pass. The third run, target/issue96-final-check-3.log, passes all 2,157 Rust tests
and stopped at three formatting-only Clippy diagnostics. Those diagnostics were
fixed, and the fourth run passed every stage. Four concurrent Nextest processes avoid excessive macOS CoreFoundation
test-directory enumeration; no test, timeout, assertion, or skip policy changes.
Final supplementary checks pass: 48 ISAPI core tests without the HTTP feature,
150 Retina tests without H.265, two Retina doctests, four ISAPI doctests, two
ONVIF doctests, and one fake-ONVIF doctest. Logs are
target/issue96-isapi-core-final.log, target/issue96-retina-minimal-final.log,
and target/issue96-protocol-doctests-final.log.
Staged, unstaged, and new-file whitespace checks pass. A high-signal credential
pattern scan found no matches in the 198 changed text files at that checkpoint;
it is not a comprehensive secret audit. The protected api/ diff is empty.
The focused checks below use existing repository test entry points. Loopback fixtures need no camera credentials, multicast, Internet access, or external inference service. Package tests run with the locked dependency graph.
| Criterion | Testable outcome | Verification | Observed evidence |
|---|---|---|---|
| Preserve discovery, media, recording, and vendor behavior | Existing discovery/media tests stay green; native events do not cancel media workers | Workspace canonical gate; generic_event_policy_reconfiguration_does_not_cancel_media_workers; unchanged_settings_still_require_an_explicit_media_restart; Reolink tests |
Both restart regressions, Reolink tests, and the full canonical gate pass |
| Retain internal service evidence without secrets | Exact namespace and camera-bound endpoint; cached evidence survives a failed refresh without URL serialization |
event_service_discovery*; camera_events::pullpoint::service_cache_tests; discovered_service_is_retained_without_claiming_a_working_subscription
|
Discovery/cache and sanitized evidence tests pass |
| One complete PullPoint lifecycle per device | Create, synchronize, pull, renew, unsubscribe, bounded failure and cancellation |
camera_events::pullpoint::; independent test_hikvision::onvif fixtures |
23 focused lease/discovery/fault/queue tests pass; worker test verifies one active subscription |
| Correct motion/tamper intervals and channel attribution | Exact source filters and independent source/rule/object identities; unrelated clears cannot close other intervals |
camera_events::lifecycle::; event_normalize; actual RTSP source-2 fixture |
43 lifecycle tests pass; non-default source-token fixture passes; physical NVR matrix pending |
| Malformed/unknown messages do not become motion or stop healthy media | Invalid messages isolated; valid neighbors retained; unknown namespace/type ignored | ONVIF XML/normalization/timestamp tests; malformed_and_unsupported_xml_do_not_stop_events_or_video
|
Parser and real-video regressions pass |
| Event failure does not reconnect healthy media | Event-only replacement, failed images, malformed metadata, and unsupported vendor fallback leave media workers independent | Root ISAPI/generic event integration; test-camera native-event E2E |
Existing focused tests pass; dual-stream recording continues through invalid metadata |
| Native capabilities require evidence | Plain RTSP has no invented kinds; disabled policy stays disabled; new kinds are announced before event delivery |
native_event_capabilities_*; generic_event_capabilities_and_subscriptions_use_observed_native_kinds; capability-ordering tests |
Capability, ordering, queue-saturation, and source-identity regressions pass |
| Consume metadata with independent health and bounds | One admitted profile; bounded RTP/document queues; metadata cannot satisfy the video watchdog | Retina tests; camera_events::registry and consumer; HTTP metrics tests |
Registry/consumer loss and handoff regressions pass; HTTP exposes event evidence even without video health |
| Support XML/gzip and reject unsupported EXI honestly | Standard +gzip and legacy .gzip; output/ratio/time bounds; no EXI claim |
Retina feature-mode tests; camera_events::metadata; real gzip RTSP fixture |
Both parser/assembly feature modes and gzip E2E pass in focused runs |
| Deduplicate transport overlap | Matching PullPoint/metadata observation yields one ID; source-specific loss preserves remaining backing; vendor handoff is sequential | Lifecycle source tests; metadata main/sub test; automatic_events_fall_back_to_onvif_after_isapi_is_unsupported
|
Replay/class-conflict/profile-handoff regressions pass; no simultaneous vendor/generic reconciliation mode exists |
| Preserve only valid Profile T/M evidence | Explicit classes, finite confidence, transformations, partial frames, and deletion; no invented image association |
event_metadata; event_normalize; classified_person_box_and_delete_persist_without_image_association
|
Validated boxes remain structured payloads until an attachment coordinate association is proven |
| Plain RTSP remains usable without native claims | Both streams record and no native event/type is fabricated |
plain_rtsp_records_both_streams_without_creating_events; plain-capability regression |
Real dual-stream recording and capability checks pass |
| Software inference remains distinct | KeepPeek-origin publication does not mutate physical camera capabilities |
software_origin_does_not_mutate_native_capabilities; existing published_detection_is_persisted_and_retry_is_idempotent and event-publication tests |
Origin, publication/idempotence, and attachment conformance pass in the canonical gate |
| Clean stop/reconfiguration | Subscription teardown; snapshot cancellation; ordered endings; retired owners cannot accept late starts | Consumer pressure tests; PullPoint cleanup; keeppeek::tests::native; snapshot queue tests |
11 retired-owner tests pass, including 256 endings and failed commit retries; persistent disk failure remains explicit best effort |
| Reject unsafe URLs and protect sensitive data | No foreign endpoint/redirect/downgrade; bounded XML/JPEG; no raw credential or recognition metric labels | Endpoint/authentication/snapshot/XML safety tests; camera event policy tests; native metrics tests | Canonical security/serialization checks, diff hygiene, protected-API comparison, and the scoped credential-pattern scan pass |
| Pass required automated gates | Workspace tests, strict Clippy, Rustfmt, UI checks, browser tests, and relevant protocol checks |
./check.sh; protocol feature/doctest commands |
Complete canonical gate and supplementary protocol checks pass; existing skips unchanged |
| Document supported behavior and limitations | Modes, source tokens, topic support, auth/network limits, push prerequisites, and hardware status are explicit | Operator guide, configuration, ISAPI guide | Documentation formatting passes |
The release performance report contains the reproducible same-build policy comparison, exact workload, run order, binary and input hashes, budgets, individual samples, and nearest-rank p50/p95 statistics. It compares events disabled with RTSP metadata enabled, not two different commits.
The final-build 10-pair run had disabled/enabled maximum-fragment-gap p95 values of 1014.465/1017.661 ms: +3.196 ms against the unchanged 86.667-ms fixture guard. All 40 finalized MP4 files and all 150 enabled camera events validated. Raw samples and the final release-binary hash are linked from the report. This does not establish fleet CPU/RSS, long-soak behavior, or physical-camera performance.
Every row remains pending for this implementation. Existing ONVIF example comments and previous ISAPI diagnostics are not substituted for new measurements.
| Device scenario | Required evidence | Status |
|---|---|---|
| Axis motion/tamper | Model/firmware, auth/dialect, start/clear, lease renewal/cleanup | Pending |
| Dahua/Amcrest forced generic | Same evidence with vendor mode excluded | Pending |
| Hikvision forced generic | Same evidence independently of ISAPI | Pending |
| Reolink forced generic | Same evidence independently of Baichuan | Pending |
| Uniview RuleEngine | Actual advertised rule/topic and stable identity | Pending |
| Profile T metadata | Encoding, RTP loss/recovery, media continuity | Pending |
| Profile M classification | Classes, confidence, transformed boxes, object deletion | Pending |
| Gzip metadata device | Standard/legacy encoding and bounded decode with live media | Pending |
| Broken/absent PullPoint | Metadata fallback and continued recording | Pending |
| Non-default NVR channel | Observed exact source token and correct configured camera association | Pending |
| Plain manual RTSP | Native flags false, recording usable, optional external inference separate | Pending |
Use private config-based credentials for read-only probes. Record exact model, firmware, profile, auth mode, topic dialect, source token, subscription behavior, encoding, and sanitized results. Verify start/clear and uninterrupted video/store progress, then stop the process and verify cleanup. No detector settings or audio output need to be changed for these checks. Multiple independently configured logical entries at one IP are not introduced by this implementation.
The same working tree contains owned Rust ISAPI event parsing/transport, analytics, image correlation, callbacks, management, fake-device coverage, shared motion/PTZ controls, and protocol-level audio. Its prior full-gate evidence is recorded in the control alignment tracker; the passing combined gate above supersedes that local checkpoint.
Browser microphone routing remains unimplemented because the protected API has no
camera speaker-session destination. Generic ONVIF push remains conditional on a
demonstrated firmware need. No new inference service or model is provisioned.
The code is committed and pushed on feat/isapi-onvif-events in draft PR #221.
No issue closure, merge to main, physical camera write, or release deployment
has been performed.
Final-head CI and the hardware matrix must be attached before treating either
broad issue as fully complete.
- KeepPeek
- Feature guide and navigation
- Get started
- Authentication and access control
- Camera controls
- Demo videos
- Live wall and kiosk display
- Recording and evidence
- Digital zoom and pan
- Camera and stream health
- Visual configuration management
- Configuration reference
- Export and import configuration
- Backup and restore
- Upgrades and migrations
- Recording maintenance
- Recording archive recovery
- Native camera events
- External analysis
- Notifications and integrations
- Home Assistant card
- Groups and two-way audio: current status
- How KeepPeek works
- Users and design choices
- Release readiness and known limitations
- Reporting bugs
- Open source and licensing
- Contributing
- Access control
- Backup and restore
- Camera controls and vendor alignment
- Computer Vision Service Scenario
- Visual configuration management
- Demo Video Publishing
- MQTT 5 Event Forwarder
- Event-Loop Runtime
- Event presentation metadata
- Event browsing, search, and encoded previews
- Event Review and Shared Bookmarks
- Evidence exports
- External authentication proposal
- Operate external authentication
- External authentication performance evidence
- External authentication verification
- Group Client Scenarios
- Hikvision ISAPI integration notes
- Home Assistant Card
- macOS installation
- Native event recording performance
- Notification rules and delivery
- Native event acceptance evidence
- Generic ONVIF and RTSP events
- Performance benchmarks
- Event pre-recording contract proposal
- Event pre-recording performance qualification
- Event pre-recording acceptance evidence
- Pushover notifications
- Recording integrity
- Recording policy audit
- Runtime profiles implementation contract
- Secrets configuration
- Shared State Store Scenario
- Transcoding Service Scenario
- Viewer Application Scenario
- Wiki publishing
- Windows service