From a0eee0e6d4aed8285be780238f9e5cba6b0100a4 Mon Sep 17 00:00:00 2001 From: Peter Woolery Date: Fri, 1 May 2026 13:19:11 -0700 Subject: [PATCH] fix(firmware): preserve buffered records appended during flush POST reporter_flush() snapshotted the buffers under lock, released the lock to POST, then unconditionally cleared the entire buffer on success. Records appended by reporter_submit_*() during the in-flight POST were silently erased. Replace clear() with erase() of just the snapshotted prefix so concurrent appends survive. Found via adversarial review (gpt-5.5 reviewer, run 2026-05-01-190903). Co-Authored-By: Claude Opus 4.7 (1M context) --- firmware/src/reporter.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/firmware/src/reporter.cpp b/firmware/src/reporter.cpp index cda1536..49a0447 100644 --- a/firmware/src/reporter.cpp +++ b/firmware/src/reporter.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -296,7 +297,10 @@ void reporter_flush(const DeviceConfig& cfg) { String body = build_camera_batch(cfg, cam_snap); if (post_json(cfg, "/api/v1/camera/events/batch", body)) { xSemaphoreTake(s_buf_mutex, portMAX_DELAY); - s_cam_buf.clear(); + // Erase only the prefix we snapshotted; FIFO append from + // submit_camera during the in-flight POST stays buffered. + size_t n = std::min(cam_snap.size(), s_cam_buf.size()); + s_cam_buf.erase(s_cam_buf.begin(), s_cam_buf.begin() + n); xSemaphoreGive(s_buf_mutex); } } @@ -304,7 +308,8 @@ void reporter_flush(const DeviceConfig& cfg) { String body = build_ble_batch(cfg, ble_snap); if (post_json(cfg, "/api/v1/events/batch", body)) { xSemaphoreTake(s_buf_mutex, portMAX_DELAY); - s_ble_buf.clear(); + size_t n = std::min(ble_snap.size(), s_ble_buf.size()); + s_ble_buf.erase(s_ble_buf.begin(), s_ble_buf.begin() + n); xSemaphoreGive(s_buf_mutex); } }