screentinker/server
ScreenTinker 4cf156d4a0 feat(server): v4 liveness CORE pass — uniform heartbeat-ack + ack-gap + dashboard liveness + identity
Server-side keystone: the server now honors the v4 liveness contract uniformly across the MIXED
fleet (v4 + old pre-v4 + disconnected), all three clients depending on it.
- UNIFORM heartbeat-ack: emitted from the single shared device:heartbeat handler (uniform by
  construction; no per-client/per-path branch), BEFORE the auth guard so a known device's watchdog
  stays armed. Harmless to old clients (they ignore it).
- RECONNECT-WINDOW ack-gap fix (ackableHeartbeat): ack a KNOWN device (authed socket OR a device_id
  that resolves) even mid-reconnect; NOT anonymous/never-authenticated sockets (degrade-safe);
  identity-agnostic. No state mutation before requireDeviceAuth (auth surface unchanged; device_ids
  are uuidv4).
- DASHBOARD LIVENESS (deriveLiveness): server-derived, VERSION-AGNOSTIC Healthy/Degraded/Offline
  from signals every client sends (socket presence, heartbeat age, reconnect frequency); no client
  status-push.
- IDENTITY CAPTURE (capture-don't-act): client_type/client_version/platform/contract_version columns;
  degrades to legacy/unknown for old clients; NEVER breaks register.
- A-BUCKET FIX (QA): recordReconnect + persistIdentity gated on !isPlaylistRefresh (a ~45-60s refresh
  is not a reconnect/new identity — matches #134), and the identity write is change-detected — closing
  the WAL write-amplification (A1) and the benign-refresh -> false-"Degraded" (A2) regressions.
New lib/liveness.js (pure helpers, unit-tested). 30 new tests (uniform ack, ack-gap, mixed fleet,
identity capture, cross-client conformance, refresh-gate reproduce-then-prove); 366/366 total.
OTA artifact-availability is a separate concern (out of scope).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 11:18:55 -05:00
..
config PiP overlay MVP: push image/web overlays to a device or group (#109) (#127) 2026-06-18 14:54:44 -05:00
db feat(server): v4 liveness CORE pass — uniform heartbeat-ack + ack-gap + dashboard liveness + identity 2026-07-08 11:18:55 -05:00
lib feat(server): v4 liveness CORE pass — uniform heartbeat-ack + ack-gap + dashboard liveness + identity 2026-07-08 11:18:55 -05:00
middleware feat(#146): billing:read scoped token — dual-path auth for the Usage Report (Option C) 2026-07-01 21:16:21 -05:00
player feat(player): v4 liveness contract — throttle-aware watchdog + browser triggers + identity 2026-07-08 10:34:05 -05:00
routes feat(#150): preserve per-device settings across delete+re-pair (fingerprint-keyed) 2026-07-07 12:40:47 -05:00
scripts feat(scheduling): per-item schedule blocks (#74 dayparting, #75 auto-expire) 2026-06-11 15:46:41 -05:00
services feat(server): v4 liveness CORE pass — uniform heartbeat-ack + ack-gap + dashboard liveness + identity 2026-07-08 11:18:55 -05:00
test feat(server): v4 liveness CORE pass — uniform heartbeat-ack + ack-gap + dashboard liveness + identity 2026-07-08 11:18:55 -05:00
ws feat(server): v4 liveness CORE pass — uniform heartbeat-ack + ack-gap + dashboard liveness + identity 2026-07-08 11:18:55 -05:00
.gitignore feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
config.js fix(db): WAL checkpointer worker-death handling (respawn + inline-autocheckpoint fallback) 2026-07-06 23:50:18 -05:00
package-lock.json chore(release): v1.9.2-patch3 2026-07-06 23:51:44 -05:00
package.json chore(release): v1.9.2-patch3 2026-07-06 23:51:44 -05:00
server.js fix(db): off-main-thread WAL checkpointer (worker) to kill the ~60s p99 checkpoint spike 2026-07-06 23:50:18 -05:00
version.js chore(version): single-source VERSION, env-configurable data paths, bump tooling 2026-06-10 12:56:03 -05:00