{
 "tag": "esp-idf",
 "kind": null,
 "product": null,
 "used_by": [],
 "parts": [],
 "notes": [
  {
   "handle": "sargbench1",
   "id": "ch340-bridged-esp32-stays-enumerated-across-firmware-reflash",
   "title": "CH340-bridged ESP32 stays enumerated across firmware reflash unlike native-USB boards",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "xiao-esp32-s3-native-usb-halt-is-not",
   "title": "XIAO ESP32-S3 native USB halt is not software-recoverable",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "an-esp32-s3-silently-rounds-a-camera-xclk",
   "title": "An ESP32-S3 silently rounds a camera XCLK request to the nearest divisor of 80 MHz, and asking for 24 MHz gets you 26.67",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "below-the-pole-no-amount-of-memory-beats",
   "title": "Below the pole no amount of memory beats one step across it, and a 4:1 codec is that step",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "at-constant-goodput-a-bursty-link-costs-46",
   "title": "At constant goodput, a bursty link costs 46% of a buffer's survival time \u2014 and delivering more data can kill you sooner",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "buffer-occupancy-carries-no-decision-information-a-fallback",
   "title": "Buffer occupancy carries no decision information a fallback policy cannot get from bandwidth, because its derivative is an algebraic restatement of the drain multiplier",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-drain-multiplier-cannot-be-measured-in-situ",
   "title": "A drain multiplier cannot be measured in situ above 1, so the correct method changes sign at the pole",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "pwdn-and-reset-pins-unconnected-on-esp32-s3",
   "title": "PWDN and RESET pins unconnected on ESP32-S3 boards; sensor does not reset on ESP32 reboot",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "ov3660-pll-multiplier-is-at-0x303b-not-0x3036",
   "title": "OV3660 PLL multiplier is at 0x303B, not 0x3036 (OV5640's address)",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "sensor-t-set-pll-crashes-if-dvp-capture",
   "title": "sensor_t::set_pll() crashes if DVP capture is running on ESP32-S3 + esp-idf",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "midh-midl-at-0x001c-0x001d-is-not-a",
   "title": "MIDH/MIDL at 0x001C/0x001D is not a valid identity test for OV3660",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "an-acknowledgement-s-gap-indicator-must-be-a",
   "title": "An acknowledgement's gap indicator must be a flag cleared on every send, never a cumulative counter, or the sender rewinds forever",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "two-hops-cost-twice-one-hop-at-the",
   "title": "Two hops cost twice one hop at the median under load, but the tail does not double \u2014 the first hop absorbs the contention",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "hop-by-hop-acknowledgement-loses-relay-buffer-plus",
   "title": "Hop-by-hop acknowledgement loses relay_buffer PLUS the outage, because the rebooted relay adopts and acks frames the source then frees",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-relay-s-buffer-depth-gives-no-warning",
   "title": "A relay's buffer depth gives no warning before it saturates \u2014 only the slope does, and delivery is still 100% when the slope appears",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "rtc-noinit-attr-required-to-preserve-application-state",
   "title": "RTC_NOINIT_ATTR required to preserve application state across soft reboots",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "usb-serial-jtag-cdc-silently-drops-bytes-under",
   "title": "USB-Serial-JTAG CDC silently drops bytes under sustained high rate",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "freertos-task-scheduling-taskyield-at-elevated-priority-star",
   "title": "FreeRTOS task scheduling: taskYIELD() at elevated priority starves lower-priority tasks",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "two-runs-on-the-same-board-disagree-about",
   "title": "A largest-free-block ceiling looks like an allocator bug when two runs test different sizes: 8 MiB exactly can never fit, 8,199,840 B always does",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "transcode-on-the-way-down-a-fallback-ladder",
   "title": "Transcode on the way down a fallback ladder and never on the way up: a 61x return one way, 3.2x the other",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "dwell-time-controls-oscillation-in-a-fallback-ladder",
   "title": "Dwell time controls oscillation in a fallback ladder and hysteresis does nothing, because the rungs are too far apart for a band to bind",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "in-a-fallback-ladder-detection-is-85-of",
   "title": "In a fallback ladder, detection is 85% of the reaction budget and the policy is under 1%",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "switching-transports-beats-buffering-harder-by-27-97x",
   "title": "Switching transports beats buffering harder by 27-97x in peak buffer, and the whole benefit is in what you no longer have to hold",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "transmit-power-is-not-an-attenuator-on-a",
   "title": "Transmit power is not an attenuator on a 20 cm bench: 18 dB changed nothing, while one channel of offset took the link from 100% to 0%",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "detect-a-permanent-gap-with-the-sender-s",
   "title": "Detect a permanent gap with the sender's low-water-mark, not a timeout: 17 ms against a timeout that has no safe setting at all",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-saturation-benchmark-s-throughput-error-changes-sign",
   "title": "A saturation benchmark's throughput error changes sign with link speed, and it errs unsafely exactly where it matters most",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "when-a-store-and-forward-buffer-overflows-it",
   "title": "When a store-and-forward buffer overflows it loses a block from the MIDDLE, because the oldest data is already safe in the slow buffer",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-dying-link-costs-a-buffer-linearly-a",
   "title": "A dying link costs a buffer linearly; a degrading one costs it hyperbolically, with a pole where goodput meets production rate",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-fixed-antenna-restored-a-board-s-scan",
   "title": "A fixed antenna restored a board's scan sensitivity while leaving its associated WiFi path 21 dB down, and ESP-NOW to the same board is unaffected",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-has-a-worse-median-latency-than",
   "title": "ESP-NOW has a worse median latency than WiFi and a three times better tail, and a loss-free relay is sized by the tail",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "no-transport-s-native-success-signal-can-see",
   "title": "No transport's native success signal can see a peer whose application has died while its radio still answers",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "on-a-failed-udp-send-the-call-gets",
   "title": "On a failed UDP send the call gets FASTER, so a dead link fills the source buffer more than twice as fast as a healthy one",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "ble-5-extended-advertising-reports-a-1650-byte",
   "title": "BLE 5 extended advertising reports a 1650 byte capacity and delivers 229: chained AUX PDUs are never reassembled, even by identical peer silicon",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-esp32-s3-can-allocate-100-of-its",
   "title": "An ESP32-S3 can allocate 100% of its PSRAM before starting WiFi and ESP-NOW, and both still initialise \u2014 the radios fall back to internal RAM",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "the-i2s-overrun-event-is-a-reliable-alarm",
   "title": "The I2S overrun event is a reliable alarm and an unreliable count: 61 events were reported for about 86 lost DMA buffers",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "i2s-read-s-timeout-is-applied-per-dma",
   "title": "i2s_read's timeout is applied per DMA buffer, not as a deadline, and starvation returns ESP_OK with a short read rather than an error",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "pdm-capture-at-8-bit-silently-delivers-the",
   "title": "PDM capture at 8-bit silently delivers the low byte of each sample, and at 32-bit silently doubles the bitrate for no extra information",
   "status": "working"
  },
  {
   "handle": "sargbench2",
   "id": "xiao-esp32s3-sense-pdm-mic-works-on-i2s0",
   "title": "XIAO ESP32S3 Sense PDM mic works on I2S0 only, CLK GPIO42 DIN GPIO41, and raw samples sit on a ~1400-count DC offset with the signal 60 dB down",
   "status": "working"
  },
  {
   "handle": "sargbench2",
   "id": "esp32-on-a-usb-power-bank-cuts-out",
   "title": "ESP32 on a USB power bank cuts out at random or only 'in certain spots' with a full battery -- Wi-Fi modem-sleep dips draw below the pack's keep-alive threshold; esp_wifi_set_ps(WIFI_PS_NONE) pins it above",
   "status": "working"
  },
  {
   "handle": "sargbench2",
   "id": "esp-now-broadcast-send-status-is-meaningless-unicast",
   "title": "ESP-NOW broadcast send-status is meaningless; unicast returns per-frame MAC ACKs -- use them for delivery counts, retransmit, and detecting that the receiver is gone",
   "status": "working"
  },
  {
   "handle": "sargbench2",
   "id": "an-associated-wi-fi-sta-parks-the-radio",
   "title": "An associated Wi-Fi STA parks the radio on its AP's channel, so an ESP-NOW+Wi-Fi bridge on a mesh must pin its STA to one BSSID and every ESP-NOW peer must hardcode that AP's channel",
   "status": "working"
  },
  {
   "handle": "sargbench2",
   "id": "older-anker-usb-power-bank-auto-shutoff-kills",
   "title": "Older Anker USB power bank auto-shutoff kills an ESP32 after 30-45 s below load; staged sleep-gap probe finds any pack's threshold in under 15 minutes",
   "status": "working"
  },
  {
   "handle": "sargbench2",
   "id": "mosquitto-silently-drops-qos0-publishes-from-a-user",
   "title": "Mosquitto silently drops QoS0 publishes from a user with no ACL entry \u2014 CONNACK 0 and clean client logs while every message vanishes",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "an-ov3660-clone-reads-midh-midl-as-0x00",
   "title": "A false counterfeit conviction stood through two corrections because each test's control ran on a different axis than the accusation",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "ov3660-clone-sensor-midh-midl-are-0x00-0x00",
   "title": "The 'counterfeit' OV3660 was genuine: every signal that convicted it was an artifact \u2014 wrong-register PLL, a stuck sensor state that survives reboot, and host-clock xclk traps",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "ch340-serial-link-to-esp32-s3-fails-above",
   "title": "CH340 serial link to ESP32-S3 is usable to 1 Mbaud and unusable above it \u2014 by two different failure modes on the same board",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "whether-to-pin-channel-and-bssid-has-three",
   "title": "Whether to pin channel and BSSID has three different right answers on three boards, so it must be measured and never assumed",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "wifi-ap-stale-state-degrades-tcp-throughput-after",
   "title": "WiFi AP stale state degrades TCP throughput after 10\u201320 cold boots; monitor and switch AP if needed",
   "status": "provisional"
  },
  {
   "handle": "sargbench2",
   "id": "xiao-esp32s3-sense-power-draw-100-ma-streaming",
   "title": "XIAO ESP32S3 Sense power draw: ~100 mA streaming over Wi-Fi, 2-3 mA light sleep, and the Sense board leaks 1-4 mA in deep sleep; burst duty cycle sized to a power bank's shutoff window",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "passing-an-explicit-bssid-to-wifi-begin-makes",
   "title": "Passing an explicit BSSID to WiFi.begin makes association 11x slower, because it forces a targeted scan that dwells for 360 ms",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "three-ways-a-throughput-measurement-reported-a-number",
   "title": "Three ways a throughput measurement reported a number that was not real, and how each was caught",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-capture-encode-send-loop-starves-the-idle",
   "title": "A capture-encode-send loop starves the idle task and the watchdog aborts the run at 60 seconds, and unsubscribing the idle tasks is timing-neutral",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-dtr-rts-reset-on-esp32-s3-usb",
   "title": "The DTR/RTS reset on ESP32-S3 USB-Serial-JTAG is a system reset, not a power-on reset, and the RTC counter surviving it is how you prove that",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-send-success-means-the-peer-s",
   "title": "ESP_NOW_SEND_SUCCESS means the peer's radio ACKed the frame, not that its application received it - and on broadcast it means nothing at all",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "rgb565-capture-on-the-esp32-s3-is-limited",
   "title": "RGB565 capture on the ESP32-S3 is limited by frame WIDTH, not by memory: 1280x720 fails with 6.5 MB of PSRAM free while 864x1536 succeeds",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "ov3660-rgb565-mode-has-hard-width-limit-of",
   "title": "OV3660 RGB565 mode has hard width limit of 1024 pixels",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "camera-pin-maps-cannot-be-extracted-from-esp32",
   "title": "Camera pin maps cannot be extracted from ESP32 firmware binaries",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-dl-s-memory-ceiling-not-its-speed",
   "title": "esp-dl's memory ceiling, not its speed, is what rules out on-device detection - and it overflows silently into PSRAM rather than failing",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-esp32-s3-usb-serial-jtag-console-goes",
   "title": "The ESP32-S3 USB-Serial-JTAG console goes silent under sustained load, so the absence of a panic message proves nothing",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-arduino-esp32-core-s-prebuilt-lwip-caps",
   "title": "The Arduino ESP32 core's prebuilt lwip caps device-to-host TCP at about 1.6 Mbps and turns any single loss into a 1.5 second stall",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-freenove-esp32-s3-wroom-cam-carries-a",
   "title": "The Freenove ESP32-S3-WROOM CAM carries a GC0308, which tops out at VGA and has no hardware JPEG at all",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "pixformat-rgb888-causes-integerdividebyzero-panic-in-esp-cam",
   "title": "PIXFORMAT_RGB888 causes IntegerDivideByZero panic in esp_camera_init",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "usb-serial-jtag-cdc-not-ready-until-186ms",
   "title": "USB-Serial-JTAG CDC not ready until ~186ms; early prints silently lost",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "gc0308-lacks-hardware-jpeg-software-encode-cost-by",
   "title": "GC0308 lacks hardware JPEG; software encode cost by framesize",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "runtime-sensor-set-framesize-on-gc0308-causes-stack",
   "title": "Runtime sensor->set_framesize() on GC0308 causes stack canary reboot",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "prove-an-esp32-s3-is-not-executing-its",
   "title": "Prove an ESP32-S3 is not executing its firmware without any serial output, by counting USB re-enumerations",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "on-esp32-s3-the-pull-resistors-for-rtc",
   "title": "On ESP32-S3 the pull resistors for RTC-capable pads live in RTC_IO, so an IO_MUX pull test on those pins returns a confident wrong answer",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-stale-rtc-domain-pull-down-on-gpio0",
   "title": "A stale RTC-domain pull-down on GPIO0 straps an ESP32-S3 into ROM download mode on every boot, and no reset clears it",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-cpu-stall-on-an-esp32-s3-is",
   "title": "esp_cpu_stall on an ESP32-S3 is unrecoverable over USB: the stall bits live in the RTC domain and survive the USB-JTAG chip reset",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "two-comms-loss-detectors-that-look-useful-and",
   "title": "Two comms-loss detectors that look useful and never fire: a TCP read waiting for EOF, and RSSI",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-wifi-driver-s-own-disconnect-event-beats",
   "title": "The WiFi driver's own disconnect event beats every application-level detector, and an application heartbeat cannot catch it at any interval",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "test-a-control-link-at-10-hz-not",
   "title": "Test a control link at 10 Hz, not 100 Hz: a fast loop hides a sleep bug that a slow loop fails half the time",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-now-loses-up-to-95-percent-of",
   "title": "ESP-NOW loses up to 95 percent of messages, in runs of 19 consecutive, when the receiving node is also an associated station with power save on",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-wifi-sleep-penalty-is-paid-by-the",
   "title": "The WiFi sleep penalty is paid by the station that sleeps, not by the access point that beacons, and swapping the roles proves it",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "wifi-latency-on-an-idle-link-is-a",
   "title": "WiFi latency on an idle link is a deterministic sawtooth, not noise: gap plus RTT locks to a whole number of beacon intervals",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-udp-throughput-number-without-a-loss-number",
   "title": "A UDP throughput number without a loss number can hide two thirds of the traffic going missing",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "scanning-dominates-wifi-cold-start-so-pinning-the",
   "title": "Scanning dominates WiFi cold start, so pinning the channel and BSSID is worth more than any throughput tuning",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "association-is-what-unlocks-the-high-phy-rates",
   "title": "Association is what unlocks the high PHY rates, and reading the negotiated rate from the driver is what proves it",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "wifi-association-beats-esp-now-only-past-a",
   "title": "WiFi association beats ESP-NOW only past a few hundred kilobytes per session, and the break-even moves by sixty times depending on whether you pin the channel",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "esp-wifi-set-ps-power-save-mode-increases",
   "title": "A WiFi station that sleeps pays up to a full beacon interval per sporadic exchange, and esp_wifi_set_ps silently reverts if you call it before association",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "softap-sta-phantom-association-after-ap-reboot",
   "title": "SoftAP STA phantom association after AP reboot",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "a-quiet-wifi-channel-still-varies-by-about",
   "title": "A quiet WiFi channel still varies by about 5 percent frame to frame, and that is the floor any detector has to clear",
   "status": "provisional"
  },
  {
   "handle": "sargbench1",
   "id": "wifi-channel-state-on-an-esp32-s3-arrives",
   "title": "WiFi channel state on an ESP32-S3 arrives at 100 frames a second and costs 4.2 megabytes per 150 seconds",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "raw-wifi-channel-state-phase-is-unusable-noise",
   "title": "Raw WiFi channel-state phase is unusable noise until you detrend it across subcarriers, which cuts its spread 48 times",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-arduino-esp32-core-renames-functions-the-current",
   "title": "The Arduino ESP32 core renames functions the current documentation uses, so build errors send you hunting a problem that is only a name",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "observe-a-coprocessor-through-shared-rtc-memory-read",
   "title": "Observe a coprocessor through shared RTC memory read live from the main processor, since it has no output of its own",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-esp32-s3-ulp-risc-v-coprocessor-runs",
   "title": "The ESP32-S3 ULP RISC-V coprocessor runs a tight loop about 482000 times a second, which is roughly a fiftieth of a main core",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "the-esp32-s3-sdk-header-claims-an-8",
   "title": "The ESP32-S3 SDK header claims an 8-way data cache and the hardware register says 4, and the hardware is right",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "finding-a-model-s-minimum-arena-size-means",
   "title": "Finding a model's minimum arena size means crashing the device repeatedly, so keep the search state where a reset cannot reach it",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-setting-that-survives-the-event-you-are",
   "title": "A setting that survives the event you are testing will contaminate every trial after the first",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "a-display-keeps-its-last-frame-across-a",
   "title": "A display keeps its last frame across a soft reset, so a crashed device shows confident stale data",
   "status": "working"
  },
  {
   "handle": "sargbench1",
   "id": "after-deep-sleep-the-oled-bus-is-unreachable",
   "title": "After deep sleep the OLED bus is unreachable unless GPIO hold is enabled, and the panel keeps showing a stale frame either way",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "bootstrap-once-uart-then-ota-deploy-forever",
   "title": "Bootstrap once over UART, then OTA forever: make ota-deploy with espressif/idf Docker build and short-interval firmware polling",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "build-esp-tflite-micro-hermetically-in-docker-espressif-idf-image",
   "title": "Build ESP-IDF person_detection hermetically with the espressif/idf:release-v5.5 Docker image \u2014 no host toolchain installs",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "capture-mode-burst-training-data-collection",
   "title": "Capture mode for training-data collection: transmit every wake at wake_s=60, burst ~1 fps for 30 s on motion, keep config/OTA live in the post-upload branch",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "codified-bringup-checklist-camlogger-worked-first-boot",
   "title": "Codified lessons compound: camera firmware written from the prior board's checklist (zero-init camera_config_t, warm-up frames, OTA-first) worked on first boot",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "deep-sleep-wake-rolls-back-pending-verify-ota-image",
   "title": "Deep-sleep wake rolls back a pending-verify OTA image on ESP-IDF \u2014 mark app valid before the first sleep",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "esp-https-ota-main-task-stack-overflow-reboot-loop-bricks-ota",
   "title": "Fix for rst:0xc (RTC_SW_CPU_RST) 'stack overflow in task main' reboot loop during esp_https_ota \u2014 raise CONFIG_ESP_MAIN_TASK_STACK_SIZE in sdkconfig, not just sdkconfig.defaults",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "esp-tflite-micro-person-detection-cannot-build-in-tree-override-path",
   "title": "Fix for \"Failed to resolve component ... unknown name\" building esp-tflite-micro person_detection in-tree (IDF 5.3/5.5 override_path)",
   "status": "working"
  },
  {
   "handle": "sarg",
   "id": "esp32-s3-dropped-off-usb-but-kept-running-on-wifi",
   "title": "ESP32-S3 board spontaneously dropped off USB (enumeration gone, power retained) but kept running on WiFi for 9+ hours",
   "status": "working"
  }
 ]
}