Sentinel is a local camera-monitoring app for operators who need to connect cameras, watch a live field HUD, review detection events, estimate range when calibrated, and export useful records. It is built to run on the operator's own machine first: video is processed on-device by default, detection starts disarmed, and safety/security behavior is documented and tested.
Sentinel runs on Windows, macOS, and Linux, processes video on-device by default, and serves a backend-canonical UI for camera setup, live HUD views, event review, and exports.
Contributers:
NOTE: Sentinel is a safety and operator-awareness software, it is not a weapon system.
- Do not implement weapon targeting logic.
- Do not implement weapon employment logic.
- Do not implement operational intercept algorithms.
- If
interceptappears in labels or legacy fixtures, treat it as simulation terminology only. - Public-safety, provenance, human-factors, fail-closed behavior, and traceability requirements govern all changes.
Canonical contributor and coding-agent policy is located in AGENTS.md.
Sentinel is designed so two devices loading the same committed build and settings receive the same runtime behavior and presentation.
- Runtime API responses, UI shell files, static assets, and MJPEG streams are served with no-store cache controls.
- The frontend
distbundle and packaged backend UI bundle are checked for staleness against frontend source. - Stale generated UI artifacts fail closed instead of being silently served as current behavior.
- Browser
localStorage, browser media-device enumeration, browser labels, and browser-specific device IDs are not runtime authority. - Camera identity, source binding, HUD defaults, and detector state are backend-canonical and schema-validated.
- Legacy
browser_device_idinputs are accepted only for compatibility and normalized tonullby the backend. - Synthetic, replay, simulation, and test-harness outputs must be explicitly tagged as non-truth data in integration-facing metadata.
Use Python 3.12. Sentinel is currently pinned to >=3.12,<3.13; newer Python versions, including Python 3.14, should be tested in a dedicated runtime-upgrade branch before being treated as supported.
pip install -e .Use Node.js 20 and npm 10 for frontend work. Install frontend dependencies when changing or rebuilding the UI:
npm --prefix apps/frontend installsentinel --data-dir "C:/Users/<you>/SentinelData" --bind 127.0.0.1 --port 8765Defaults:
--bind 127.0.0.1--port 8765--data-dirdefaults to a platform-specific user data location, not the repo root- Browser opens automatically unless
--no-openis passed - Detection starts disarmed by default
Field HUD launch:
sentinel --field --capture-card
sentinel serve --field --webcamUse --bind 0.0.0.0 only on trusted networks. Sentinel prints a warning when LAN binding is enabled.
Frontend build output is generated, not source of truth. Both apps/frontend/dist and the backend-synced bundle under apps/backend/sentinel/web are ignored so hashed assets such as index-*.js and index-*.css do not become stale committed surfaces.
pwsh -NoProfile -File scripts/build.ps1./scripts/build.shThe build scripts install backend/frontend dependencies, build the frontend, replace the ignored apps/backend/sentinel/web bundle with the fresh frontend dist, and verify the CLI with python -m sentinel.cli --help. Release packaging should include the generated web bundle from the build job, not from committed hashed assets.
Do not commit generated hashed UI assets to hide stale-source problems. Runtime bundle freshness is part of the safety surface.
- Webcam or capture card: use camera type
webcamwith source index0,1, etc. Backend discovery provides labels and class hints. - RTSP: add the full RTSP URL. Credentials and secret references are redacted in logs and API responses.
- ONVIF: use discovery in the Cameras page. If discovery is unavailable, paste and validate RTSP directly.
Detailed operator setup: docs_public/camera_setup.md.
Sentinel stores runtime data under the chosen data directory:
db/sentinel.dbmedia/<camera_id>/<YYYY>/<MM>/<DD>/...exports/...logs/...
Retention controls include event/media age trimming, optional size-based trimming, and safe deletion that removes database rows and media references together.
Per-camera recording modes:
event_only: default, log only detection eventsfull: continuous recording segments plus segment log entrieslive: short continuous recording segments plus segment log entries
Runtime data, logs, exports, scratch plans, model artifacts, and local reports are ignored by .gitignore.
- Local-only bind by default.
- LAN access requires explicit opt-in.
- External input is untrusted and validated or sanitized.
- Configuration is versioned and schema-validated; unknown keys are validation errors.
- Missing or invalid critical data fails closed.
- Security-sensitive values are redacted in logs and API responses.
- Secret storage uses the OS keychain where available, with encrypted local fallback. Fallback secret files are created or replaced with owner-only permission attempts where the platform supports them.
- Telemetry is off by default unless explicitly added and opted in.
See SECURITY.md and docs/security_threat_model.md.
# Backend and frontend dev
make dev
# Linux/macOS
./scripts/dev.sh
# Windows
./scripts/dev.ps1Frontend source lives in apps/frontend/src. Backend API/runtime code lives in apps/backend/sentinel. Backend tests live in apps/backend/tests.
The Browser plugin is required for full rendered frontend QA in Codex sessions: page identity, DOM snapshots, console health, screenshots, and interaction proof. If that plugin is absent, use the repo's Playwright workflow when installed; otherwise record that rendered browser validation was not available and rely on lint/typecheck/build plus backend tests.
Minimum gates before merge:
ruff check apps/backend
mypy apps/backend/sentinel
python -m pytest apps/backend/tests
npm --prefix apps/frontend run lint
npm --prefix apps/frontend run typecheck
npm --prefix apps/frontend run buildFor UI changes, also verify that the generated apps/backend/sentinel/web bundle matches the current frontend build and scan committed/runtime surfaces for stale labels or browser-specific authority.
Useful audit scans:
rg -n -F -e "Engineering Test Mode" -e "showFieldHudControls" -e "HudControlPanel" -e "useLocalStorage" -e "getUserMedia" -e "enumerateDevices" apps/frontend/src apps/frontend/dist apps/backend/sentinel/web docs docs_public README.md AGENTS.md
rg -n browser_device_id apps/frontend/src apps/frontend/dist apps/backend/sentinel/web
git diff --checkCommitted assurance artifacts live under docs/:
docs/requirements.mddocs/verification_plan.mddocs/traceability.mddocs/hazard_log.mddocs/security_threat_model.mddocs/config_schema.mddocs/operational_concepts.md
Public/operator-facing docs live under docs_public/.
PR evidence should reference affected REQ-*, V-*, and HZ-* items, include deterministic verification evidence, and summarize safety/security impact.
- ONVIF discovery is best effort and depends on network and camera vendor behavior.
- Browser-native directory access may be restricted by browser sandboxing; Sentinel also provides backend-assisted local workflows.
- Clip writing depends on host OS codec availability through OpenCV/FFmpeg.
- Full rendered frontend QA requires the Browser plugin or an installed Playwright workflow.