Skip to content

docs: sync README + AGENTS + config.example with supervisor + current config schema#1

Draft
Sbussiso wants to merge 1 commit into
masterfrom
claude/nice-fermat-U1PI8
Draft

docs: sync README + AGENTS + config.example with supervisor + current config schema#1
Sbussiso wants to merge 1 commit into
masterfrom
claude/nice-fermat-U1PI8

Conversation

@Sbussiso

Copy link
Copy Markdown
Contributor

Summary

Documentation drift audit — code is the source of truth; docs brought back into line.

  • Auth header: AGENTS outbound-API table listed X-API-Key for /api/nodes/register and /api/nodes/heartbeat. All six outbound call sites in src/api/client.rs have always used X-Node-API-Key. Fixed, and noted that heartbeats now carry per-camera CameraStatus { camera_id, status, last_error }.
  • FFmpeg supervisor: the new src/streaming/supervisor.rs (2s poll, 1s→30s exponential backoff, trips to Failed after 5 crashes in 60s, reports real pipeline state into the Dashboard) wasn't reflected in either README or AGENTS. Added to project structure and architecture in both, and noted that heartbeats now report real pipeline state (starting / streaming / restarting / failed / error) instead of the legacy hardcoded "streaming".
  • config.example.yaml: was missing streaming.encoder, the entire streaming.hls: subsection, and the entire motion: section — all of which are real config structs in src/config/settings.rs with defaults that matter (notably motion.threshold: 0.02, hls.segment_duration: 1, hls.playlist_size: 15).

No code changes — docs only.

Test plan

  • Re-read updated sections against src/api/client.rs, src/streaming/supervisor.rs, src/config/settings.rs to confirm parity
  • Confirm config.example.yaml parses cleanly into Config (should be a no-op — every field matches a serde-named struct field)

… config schema

Three pieces of drift:

- AGENTS.md "Outbound API surface" table listed `X-API-Key` for
  `/api/nodes/register` and `/api/nodes/heartbeat`. Code has always sent
  `X-Node-API-Key` on every outbound call (src/api/client.rs). Fixed
  the table and noted that heartbeats now carry per-camera
  `CameraStatus { camera_id, status, last_error }` with real pipeline
  state.
- The new FFmpeg supervisor (streaming/supervisor.rs) wasn't reflected
  anywhere in the docs. Added it to the project structure in both
  README and AGENTS, and documented its behaviour (2s poll, 1s→30s
  exponential backoff, 5-crashes-in-60s trips to `Failed`) plus the
  fact that every heartbeat now reports real pipeline state instead of
  the old hardcoded "streaming".
- config.example.yaml was missing `streaming.encoder`, the entire
  `streaming.hls:` subsection (enabled / segment_duration /
  playlist_size / bitrate), and the entire `motion:` section (enabled /
  threshold 0.02 / cooldown_secs). All three are real, required-shaped
  config structs in src/config/settings.rs.

No code changes.
Sbussiso added a commit that referenced this pull request Apr 27, 2026
🔴 #1 from yesterday's code review.

Previously: if init_file_logging failed (ACL denial on
%ProgramData%\OpenSentry\logs\, disk full, etc), service_main
would call tracing::error! + eprintln! and return. Both targets
are unobservable in a service context — tracing wasn't initialised
yet, eprintln has no console — so the service silently exited with
services.msc reporting "started and immediately stopped" and
nothing in any log to explain why.

Adds write_fatal_startup_error which:
  1. Tries %ProgramData%\OpenSentry\fatal-startup-error.txt first
     (the canonical place; any operator looking at the data dir
     will find it).
  2. Falls back to %TEMP%\opensentry-cloudnode-fatal-startup-error.txt
     if step 1 fails (which is exactly when init_file_logging
     would have failed too — same dir).
  3. Best-effort, append-only — chronological audit trail across
     multiple failed starts; failure to write either location is
     swallowed silently because at that point we're out of
     reporting options.

Synchronous std::fs write — no tracing dependency, no Tokio
runtime, no third-party crates. Works even if everything else in
the service initialisation is wedged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants