copilot-instructions rework, new C++ coding guide for AI reviews - #5480
Conversation
Initial commit based on WLED-MM version * shorten previous instructions, by removing duplicated information and shortening wording * move agent instructions into a separate file * added coding conventions for C++, webUI, CI/CD (based on WLED-MM, needs adjustment for WLED) * added .coderabbit.yaml so the rabbits picks the same instructions for reviews. more information: * MoonModules#353 * MoonModules#354 * MoonModules#356
WalkthroughAdds a repository-root CodeRabbit config plus multiple new or updated docs and instruction files (C++ conventions, web UI rules, CI/CD guidance, agent-build workflow, condensed setup), updates CONTRIBUTING links, and adds rules preventing edits to generated web headers. No source or public API changes. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Clarify float-to-unsigned conversion behavior and update semaphore return note.
These files are auto-generated, too
Emphasize the importance of avoiding heap fragmentation and suggest strategies for memory allocation.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Clarify heap fragmentation concerns and provide guidelines for memory allocation.
... and making some "actionable decision rules" visible to AI for review
Added guidelines for supporting reviews and discussions in PRs.
Add notes on LittleFS filenames and float-to-unsigned conversion.
Updated the LittleFS filename path in instructions to reflect the correct directory structure.
example file path: don't use directories
Corrected a typo in the LittleFS filenames caveat.
Avoid that AI reviews over-apply the F() rule.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
1 similar comment
This comment was marked as duplicate.
This comment was marked as duplicate.
* Math and trigonometric function usage guidelines for WLED, replacing deprecated FastLED aliases with new function names and providing a comparison table. * Minor re-styling
was jumping from H2 -> H4
|
@softhack can you give a summary on what it does? I can not judge if this is good or not but it probably is a lot better than what we had. |
@DedeHai Yes, sure.
I've tried to structure everything so that copilot "agent" tasks will not be forced pre-load the coding guidelines (would make agent mode requests very slow), but just use very generic statements to guide work. The rabbit has a new .coderabbit.yaml that makes the generic copilot-instructions.md plus coding style in "docs/" applicable = adds our rules for each PR code review. The rabbit will still do all other stuff it did before. For optimization, i've added this HUMAN_ONLY_START / HUMAN_ONLY_END mechanism.
I know the C++ file is quite big - just read over it and say if there is stuff you don't like (will remove), or important stuff missing (will add). Overall idea: an "automated" database of coding rules and best practices. The rabbit will automatically use parts of them for reviews, but contributors don't need to read through anything. There are a few caveats and quick "recovery steps" in case that too much low-prio BS pop up during reviews, or in case that copiliot tasks are producing worse results. We needs to have an eye on it initially. I'll talk to netmindz to share my "brain dump" just in case. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/cpp.instructions.md`:
- Line 511: The docs currently hardcode WLED_MAX_SEGNAME_LEN = 64 in the
LittleFS filename-length guidance; update the wording around the LFS_NAME_MAX /
file.open() guidance to avoid a single platform-specific value by referring to
the platform default (e.g., "platform default WLED_MAX_SEGNAME_LEN") or
explicitly noting the common targets (ESP8266 vs ESP32, e.g., 32/64) and ensure
the example for constructed paths (like "/ledmap_" + segment name + ".json")
states to validate against LFS_NAME_MAX rather than a hardcoded 64; keep
references to LFS_NAME_MAX and file.open() so readers can locate the guidance.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 1368e382-1410-444b-822c-e2d3c93ff05f
📒 Files selected for processing (1)
docs/cpp.instructions.md
|
|
||
| ## Caveats and Pitfalls | ||
|
|
||
| - **LittleFS filenames**: File paths passed to `file.open()` must not exceed 255 bytes (`LFS_NAME_MAX`). Validate constructed paths (e.g., `/ledmap_` + segment name + `.json`) stay within this limit (assume standard configurations, like WLED_MAX_SEGNAME_LEN = 64). |
There was a problem hiding this comment.
Avoid hardcoding WLED_MAX_SEGNAME_LEN = 64 in cross-platform guidance.
Line 511 is otherwise correct, but pinning the example to 64 can mislead ESP8266 reviewers (where the practical segment-name limit differs). Prefer neutral wording like “platform default WLED_MAX_SEGNAME_LEN” or explicitly mention 32/64 by target.
Suggested doc tweak
-- **LittleFS filenames**: File paths passed to `file.open()` must not exceed 255 bytes (`LFS_NAME_MAX`). Validate constructed paths (e.g., `/ledmap_` + segment name + `.json`) stay within this limit (assume standard configurations, like WLED_MAX_SEGNAME_LEN = 64).
+- **LittleFS filenames**: File paths passed to `file.open()` must not exceed 255 bytes (`LFS_NAME_MAX`). Validate constructed paths (e.g., `/ledmap_` + segment name + `.json`) stay within this limit (assume standard platform defaults for `WLED_MAX_SEGNAME_LEN`).Based on learnings: In WLED, segment name limits are platform-dependent (ESP8266 vs ESP32), and filename-length checks should assume standard default configurations rather than a single hardcoded value.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - **LittleFS filenames**: File paths passed to `file.open()` must not exceed 255 bytes (`LFS_NAME_MAX`). Validate constructed paths (e.g., `/ledmap_` + segment name + `.json`) stay within this limit (assume standard configurations, like WLED_MAX_SEGNAME_LEN = 64). | |
| - **LittleFS filenames**: File paths passed to `file.open()` must not exceed 255 bytes (`LFS_NAME_MAX`). Validate constructed paths (e.g., `/ledmap_` + segment name + `.json`) stay within this limit (assume standard platform defaults for `WLED_MAX_SEGNAME_LEN`). |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/cpp.instructions.md` at line 511, The docs currently hardcode
WLED_MAX_SEGNAME_LEN = 64 in the LittleFS filename-length guidance; update the
wording around the LFS_NAME_MAX / file.open() guidance to avoid a single
platform-specific value by referring to the platform default (e.g., "platform
default WLED_MAX_SEGNAME_LEN") or explicitly noting the common targets (ESP8266
vs ESP32, e.g., 32/64) and ensure the example for constructed paths (like
"/ledmap_" + segment name + ".json") states to validate against LFS_NAME_MAX
rather than a hardcoded 64; keep references to LFS_NAME_MAX and file.open() so
readers can locate the guidance.
There was a problem hiding this comment.
This is intentional - the rule is about "max filename limits" and "assume default configurations". In this sense, its safe to check with WLED_MAX_SEGNAME_LEN=64 even when esp8266 only has 32 chars for segments. We don't have esp8266-only features in the WLED core, so running on esp32 with 64 chars segment must be safe, too.
There was a problem hiding this comment.
@softhack007, that's clear — thank you for the explanation. Using 64 (ESP32's default) as the example is the correct conservative choice: any path that fits with a 64-character segment name is trivially safe on ESP8266 where segment names are limited to 32 characters. My concern was misplaced.
✏️ Learnings added
Learnt from: softhack007
Repo: wled/WLED PR: 5480
File: docs/cpp.instructions.md:511-511
Timestamp: 2026-04-08T19:10:48.754Z
Learning: In WLED documentation and review guidance (`docs/cpp.instructions.md`), using `WLED_MAX_SEGNAME_LEN = 64` as the example value in LittleFS filename-length checks is intentional and correct. The reasoning: ESP32 uses 64-char segment names (the larger default), and if a constructed path (e.g. `/ledmap_` + segment name + `.json`) stays within 255 bytes when the name is 64 chars, it is trivially safe on ESP8266 where segment names are limited to 32 chars. WLED core has no ESP8266-only features, so validating against the larger ESP32 default is the right cross-platform conservative choice. Do NOT flag `WLED_MAX_SEGNAME_LEN = 64` in this guidance as misleading or platform-specific.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED PR: 5435
File: wled00/FX_fcn.cpp:1484-1498
Timestamp: 2026-03-21T22:29:23.438Z
Learning: In WLED (wled00/FX_fcn.cpp), `WS2812FX::waitForLEDs(unsigned maxWaitMS)` is intentionally a const wait-only helper — it does NOT call `strip.suspend()` or `strip.resume()`. When a caller needs to protect a critical OS section (e.g. `file.close()`, `ESP.getFreeHeap()`) from concurrent LED DMA/RMT output, the caller must own the full `strip.suspend()` → `strip.waitForLEDs()` → critical section → `strip.resume()` sequence. Putting `resume()` inside `waitForLEDs()` would release the lock before the critical call and defeat the purpose.
Learnt from: softhack007
Repo: wled/WLED PR: 5435
File: wled00/file.cpp:43-43
Timestamp: 2026-03-22T00:49:53.727Z
Learning: In WLED (wled00/file.cpp and related), all callers of writeObjectToFile(), writeObjectToFileUsingId(), readObjectFromFile(), and readObjectFromFileUsingId() execute exclusively on the main Arduino loop task. No async webserver callback (which runs on a separate FreeRTOS task on ESP32) directly calls any of these file functions — async handlers either set flags or delegate to the main loop. This means the static File f in file.cpp is never concurrently accessed from multiple tasks, and the window between doCloseFile=false and f.close() in closeFile() cannot be exploited by a parallel open() call.
Learnt from: softhack007
Repo: wled/WLED PR: 5435
File: wled00/file.cpp:42-55
Timestamp: 2026-03-21T22:55:37.522Z
Learning: In WLED (wled00/file.cpp), `closeFile()` intentionally clears `doCloseFile = false` *before* the `strip.suspend()` / `strip.waitForLEDs()` / `f.close()` / `strip.resume()` sequence. This is the correct design: it prevents a concurrent or re-entrant call (via `if (doCloseFile) closeFile()` at lines 287 and 353) from attempting a double-close of the shared static `f` during the wait window. The inverse risk — another task reopening `f` via `WLED_FS.open()` while the wait is in progress — is not realistic because: (1) on ESP8266 (single-core), `delay(1)` only yields to lwIP/TCP callbacks which never call `writeObjectToFile`/`readObjectFromFile`; (2) on standard ESP32 without shared RMT, the wait block is not compiled so `f.close()` is immediate; (3) in WLED's architecture, file operations are dispatched from the main loop task only. Do not recommend moving the `doCloseFile = false` assignment to after `f.close()`.
Learnt from: softhack007
Repo: wled/WLED PR: 5457
File: usermods/zigbee_rgb_light/usermod_zigbee_rgb_light.h:283-292
Timestamp: 2026-03-31T17:33:09.706Z
Learning: In the WLED Zigbee RGB Light usermod (`usermods/zigbee_rgb_light/usermod_zigbee_rgb_light.h`), mutex timeouts used with `xSemaphoreTake(zbStateMutex, ...)` should be at least 100–200 ms (not 10 ms), because the Zigbee FreeRTOS task can be busy for longer than 10 ms during ZCL frame construction, NWK encryption, and ZBOSS scheduler operations on ESP32-C6.
Learnt from: softhack007
Repo: wled/WLED PR: 5457
File: usermods/zigbee_rgb_light/usermod_zigbee_rgb_light.h:0-0
Timestamp: 2026-03-31T17:31:01.023Z
Learning: In WLED PR `#5457` (zigbee_rgb_light usermod): The WLED_MAX_DIGITAL_CHANNELS=0 build flag used in the esp32c6_zigbee environment is a temporary workaround for rmt_tx_wait_all_done() timeout spam when the Zigbee/802.15.4 stack is active. The root cause is under investigation and is likely related to Zigbee light-sleep (CONFIG_PM_ENABLE) disrupting RMT's internal time base, or ISR latency due to cache-disable during flash ops — NOT the 802.15.4 radio "sharing" the RMT peripheral (they are separate hardware). Because a proper fix (rmt_enable()/rmt_disable() PM-lock wrapping, allow_pd=0, CONFIG_RMT_TX_ISR_CACHE_SAFE) may eliminate the need to disable digital channels entirely, do NOT add a compile-time `#error` guard requiring WLED_MAX_DIGITAL_CHANNELS=0; doing so would prematurely bake in a constraint that may be lifted once the investigation concludes.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/set.cpp:551-555
Timestamp: 2026-03-27T21:00:25.902Z
Learning: In WLED PR `#5048` (wled00/set.cpp lines 551-555), the CONFIG_IDF_TARGET_ESP32C5 block that unconditionally forces ntpEnabled = false is an intentional **temporary hotfix** by softhack007 for a known ESP32-C5 crash: `assert failed: udp_new_ip_type udp.c:1278 (Required to lock TCPIP core functionality!)`. Do not flag this as a permanent design issue; the TODO comment in the code already notes it should be resolved properly once the underlying IDF/TCPIP bug on C5 is fixed. A future permanent solution should use a target capability flag rather than overwriting the user's setting.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/cfg.cpp:673-673
Timestamp: 2026-03-27T21:17:51.985Z
Learning: In WLED PR `#5048`, the NTP/UDP crash on ESP32-C5 (pioarduino IDF 5.5.x): CONFIG_LWIP_TCPIP_CORE_LOCKING defaults to n (disabled) in arduino-esp32/pioarduino, while CONFIG_LWIP_CHECK_THREAD_SAFETY=y is what actually causes the "Required to lock TCPIP core functionality!" assertion. LOCK_TCPIP_CORE() / UNLOCK_TCPIP_CORE() macros are only functional when CONFIG_LWIP_TCPIP_CORE_LOCKING=y; using them without enabling that config has no effect. The correct fix without sdkconfig changes is to use tcpip_callback() to schedule ntpUdp.begin() (and other raw lwIP API calls) on the TCPIP thread, which works regardless of the locking mode setting. The tasmota core (IDF 5.3.x, used for C6) likely has CONFIG_LWIP_CHECK_THREAD_SAFETY=n, which is why the same violation does not crash on C6.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/wled.h:336-339
Timestamp: 2026-03-28T01:36:54.706Z
Learning: In WLED (wled00/wled.h), the RX/TX hardware pin guard `#if defined(ARDUINO_ARCH_ESP32) && (!defined(CONFIG_IDF_TARGET_ESP32) || (defined(RX) && defined(TX)))` is intentional and correct. For all non-classic ESP32 targets (C3, C5, C6, S2, S3, P4, C61), the arduino-esp32 framework always defines RX and TX according to the target's native UART pins, so the unconditional entry into the hardwareRX/hardwareTX branch for `!defined(CONFIG_IDF_TARGET_ESP32)` is safe. The `|| (defined(RX) && defined(TX))` arm handles classic ESP32 boards that provide custom framework-defined UART pins. Do not flag this condition as potentially undefined-macro unsafe.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/cfg.cpp:673-673
Timestamp: 2026-03-27T21:17:51.985Z
Learning: In WLED PR `#5048` (wled00/cfg.cpp), the NTP crash on ESP32-C5 (pioarduino + IDF 5.5.x) is caused by both CONFIG_LWIP_TCPIP_CORE_LOCKING=y AND CONFIG_LWIP_CHECK_THREAD_SAFETY=y being enabled by default in the pioarduino/arduino-esp32 IDF 5.x sdkconfig. The tasmota core (IDF 5.3.x, used for C6) likely has CONFIG_LWIP_CHECK_THREAD_SAFETY=n, which is why the same violation does not crash on C6. Since pioarduino already has TCPIP_CORE_LOCKING enabled, wrapping ntpUdp.begin() (and any other raw lwIP API call) with LOCK_TCPIP_CORE()/UNLOCK_TCPIP_CORE() from lwip/tcpip.h is directly applicable without sdkconfig changes in platformio.ini.
Learnt from: softhack007
Repo: wled/WLED PR: 4838
File: platformio.ini:149-150
Timestamp: 2026-03-29T16:47:56.452Z
Learning: In WLED PR `#4838` (ESP-IDF V5 branch, platformio.ini): The original FastLED library has been replaced with a custom `fastled-slim` fork. As a result, the `[v5_pioarduino_workaround]` section (containing `lib_archive = yes`) and the commented-out `post:pio-scripts/fastled_cxx_workaround.py` extra script are intentional dead code pending removal after back-to-back testing. Do NOT flag `lib_archive = yes` in `[v5_pioarduino_workaround]` as unreferenced or suggest moving it to active env blocks — the entire section is slated for removal.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, verify that file operations (especially file.open()) respect LittleFS filename limitations. Assume default WLED configuration with LittleFS default filename limit of 255 bytes. Do not assume extreme configuration values like WLED_MAX_SEGNAME_LEN = 512 which would not be standard configurations.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, file operations (especially file.open()) should be checked to ensure they respect LittleFS filename limitations. The default LittleFS filename limit is 255 bytes (LFS_NAME_MAX). Reviews should assume default WLED configuration defines and not extreme edge-case values (e.g., WLED_MAX_SEGNAME_LEN = 512 would not be standard). File paths should be validated to stay within the 255-byte limit.
Learnt from: DedeHai
Repo: wled/WLED PR: 4793
File: wled00/file.cpp:481-513
Timestamp: 2025-07-31T18:21:49.868Z
Learning: In WLED, essential configuration files that require backup have short, controlled names (like "/cfg.json", "/presets.json") that are well within a 32-character buffer limit. The file naming is controlled by developers, making buffer overflow in backup filename construction highly unlikely.
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/data/index.js:2406-2413
Timestamp: 2025-09-28T09:53:42.670Z
Learning: In WLED, code paths that appear unreachable may actually be safety fallbacks for low-heap conditions. These fallbacks are intentional defensive programming measures to ensure UI functionality is preserved when system resources are constrained.
Learnt from: blazoncek
Repo: wled/WLED PR: 4482
File: wled00/udp.cpp:147-149
Timestamp: 2025-02-19T12:43:34.199Z
Learning: ESP8266 and ESP32 platforms have different maximum segment name lengths in WLED, which can cause truncation when syncing segment names between devices. This platform difference affects the user experience when using the segment name sync feature.
Learnt from: DedeHai
Repo: wled/WLED PR: 4956
File: wled00/data/edit.htm:295-303
Timestamp: 2025-09-24T18:52:34.117Z
Learning: WLED file system stores all files in the root directory only (flat structure), so file paths don't have subdirectories. When working with WLED file editors, using just the filename (name) rather than full path is correct since there are no nested directories.
Learnt from: blazoncek
Repo: wled/WLED PR: 4482
File: wled00/udp.cpp:147-149
Timestamp: 2025-02-19T12:43:34.200Z
Learning: In WLED, maximum segment name length varies by platform:
- ESP8266: 32 characters (WLED_MAX_SEGNAME_LEN = 32)
- ESP32: 64 characters (WLED_MAX_SEGNAME_LEN = 64)
This platform difference can cause truncation when syncing longer names from ESP32 to ESP8266. Additionally, the WLED UI has limitations regarding modified maximum segment name lengths.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.
Learnt from: willmmiles
Repo: wled/WLED PR: 5462
File: wled00/json.cpp:1189-1198
Timestamp: 2026-03-30T15:32:08.847Z
Learning: In WLED's `respondModeData()` (wled00/json.cpp), the 256-character `lineBuffer` limit for effect descriptor strings (getModeData) is an intentional constraint that matches the same 256-char limit used ~6 other places in the codebase. It is not new to this PR and should not be flagged as a regression. Lifting it requires a future refactor (better type system or dynamic buffer).
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-03-29T21:50:15.920Z
Learning: In WLED 0.15.x (0_15_x branch, e.g. commit 4fb5fbeafbc6d2593d8428d6bfd554894a3ca921), `MAX_LEDS` in `wled00/const.h` is defined as: ESP8266=1664, ESP32-S2=2048, all other ESP32 variants (classic, S3, C3, etc., with or without PSRAM)=8192. The PSRAM-based MAX_LEDS split (PSRAM=2048, no PSRAM=1664 for ESP32) exists only in the 0.16/main branch, NOT in 0.15.x. Do not apply 0.16 MAX_LEDS values when analyzing 0.15.x code.
Learnt from: blazoncek
Repo: wled/WLED PR: 4995
File: wled00/FX.cpp:5223-5226
Timestamp: 2025-10-20T09:38:51.997Z
Learning: WLED matrices: each dimension (SEG_W, SEG_H) is limited to ≤255; 256 or larger per side is not supported/feasible on ESP32, so effects should assume per-dimension max 255.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.
Learnt from: DedeHai
Repo: wled/WLED PR: 4682
File: wled00/FX.cpp:8997-9005
Timestamp: 2025-05-09T18:43:15.355Z
Learning: In the WLED codebase, SEGMENT.custom3 is always constrained to the range 0-31 and will not exceed this range.
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-08T19:07:13.970Z
Learning: Applies to **/*.cpp,**/*.h : Mark larger blocks of AI-generated code with an `// AI: below section was generated by an AI` comment
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-02-11T17:17:04.657Z
Learning: In WLED code reviews, when C-style functions or variables are added or modified, check if they are globally visible (not static). If the function/variable is not declared in any global header file (like fcn_declare.h), suggest either: (1) making it static (visible only within the translation unit) with a forward declaration if needed, or (2) adding a comment to clarify that the function/variable is intentionally global. This helps reduce global namespace pollution and enables better compiler optimizations.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-02-11T11:14:24.395Z
Learning: In WLED code reviews, verify that all global variables in .cpp files are properly declared: check that they are defined via .h file or via "extern" declaration, verify that declarations are not duplicated, and ensure they are not implicitly declared as "int" (which can happen when the type is omitted).
Learnt from: softhack007
Repo: wled/WLED PR: 5456
File: platformio.ini:794-830
Timestamp: 2026-03-31T13:42:00.444Z
Learning: In WLED PR `#5456` (Matter over WiFi usermod, CMakeLists.txt + platformio.ini): The GCC 14 chip::to_underlying compatibility issue with CHIP SDK's TypeTraits.h is fixed by building in gnu++20 mode (not gnu++2b/gnu++23). CMakeLists.txt uses `idf_build_replace_option_from_property` to swap `-std=gnu++2b` for `-std=gnu++20` when the matter usermod is present. The `matter_gcc14_compat.h` shim file (which pre-defines `chip::to_underlying` and sets `CHIP_TO_UNDERLYING_DEFINED`) is dead code under this configuration — it is never included anywhere. TypeTraits.h's broken C++23 `using std::to_underlying` alias path is only taken in gnu++23 mode; in gnu++20 mode CHIP defines its own `chip::to_underlying` function template normally, so no shim is needed. Do NOT flag the missing `-include` for `matter_gcc14_compat.h` as a build issue.
Learnt from: softhack007
Repo: wled/WLED PR: 5456
File: platformio.ini:794-830
Timestamp: 2026-03-31T13:42:00.444Z
Learning: In WLED PR `#5456` (Matter over WiFi usermod, CMakeLists.txt + platformio.ini): The GCC 14 chip::to_underlying compatibility issue with CHIP SDK's TypeTraits.h is fixed by building in gnu++20 mode (not gnu++2b/gnu++23). CMakeLists.txt uses `idf_build_replace_option_from_property` to swap `-std=gnu++2b` for `-std=gnu++20` when the matter usermod is present. The `matter_gcc14_compat.h` shim file (which pre-defines `chip::to_underlying` and sets `CHIP_TO_UNDERLYING_DEFINED`) is dead code under this configuration — it is never included anywhere. TypeTraits.h's broken C++23 `using std::to_underlying` alias path is only taken in gnu++23 mode; in gnu++20 mode CHIP defines its own `chip::to_underlying` function template normally, so no shim is needed. Additionally, upstream connectedhomeip TypeTraits.h already has the fix built-in. ESP-IDF v5.5 uses GCC 14.2.0. Do NOT flag the missing `-include` for `matter_gcc14_compat.h` as a build issue.
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-08T19:07:13.970Z
Learning: Applies to **/*.cpp,**/*.h : Every non-trivial AI-generated function should have a brief comment describing what it does and explaining parameters when their names alone are not self-explanatory
Learnt from: softhack007
Repo: wled/WLED PR: 5480
File: docs/cpp.instructions.md:85-87
Timestamp: 2026-04-07T22:49:49.796Z
Learning: In WLED C++ code reviews and documentation (docs/cpp.instructions.md), the F() macro and PROGMEM/FlashStringHelper behavior is platform-specific:
- On ESP8266: F() / PROGMEM explicitly stores string literals in flash, saving RAM. This is important because ESP8266 has very limited RAM and string literals default to RAM. Always recommend F() for print-only string literals on ESP8266.
- On ESP32: PROGMEM is defined as a no-op, PSTR(s) is just (s), and string literals already reside in flash/rodata. F() yields little to no RAM savings on ESP32 but is harmless and may be needed to satisfy __FlashStringHelper* overloads. Do not expect RAM savings from F() on ESP32.
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-04-08T19:07:13.970Z
Learning: Applies to wled00/html_*.h,wled00/js_*.h : Never edit or commit auto-generated headers `wled00/html_*.h` and `wled00/js_*.h`
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR `#4798`, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-01-03T14:38:09.949Z
Learning: In WLED code reviews, check that FastLED trigonometric function aliases are not used. Replace `sin8()` and `cos8()` with `sin8_t()` and `cos8_t()`. Replace `sin16()` and `cos16()` with `sin16_t()` and `cos16_t()`. For float versions, replace `sinf()` and `cosf()` with `sin_approx()` and `cos_approx()`. See wled_math.cpp for the proper WLED implementations.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-03-15T13:21:32.008Z
Learning: In WLED code reviews (and generally), when a PR discussion involves "is this worth doing?" uncertainty about a proposed reliability, safety, or data-integrity mechanism (e.g. CRC checks, backups, power-loss protection), suggest performing a software FMEA (Failure Mode and Effects Analysis). The FMEA should: enumerate failure modes for the feared event, assess each mitigation's effectiveness per failure mode, note common-cause/common-mode failures, and rate credibility for the typical WLED use case. This was successfully used in PR `#5421` to evaluate CRC-based config file protection and was well-received by the WLED maintainers (softhack007 explicitly requested this be remembered for future reviews).
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/wled_metadata.cpp:6-8
Timestamp: 2026-03-27T21:02:06.756Z
Learning: In WLED PR `#5048` (pio-scripts/set_metadata.py + wled00/wled_metadata.cpp): The hardcoded `#define WLED_VERSION 16.0.0-alphaV5` in `wled_metadata.cpp` is an intentional **temporary hotfix** by softhack007. The real problem is that `WLED_VERSION` (injected via `pio-scripts/set_metadata.py` as a CPPDEFINE) is not reaching `wled_metadata.cpp` at compile time. The set_metadata.py change in this PR switched from `env.Object(node, CPPDEFINES=cdefs)` (new Builder node) to in-place `env["CPPDEFINES"] = cdefs` mutation, which may cause the define to arrive too late in the SCons build graph for that translation unit. The TODO comment in the code already marks this for removal. Do not flag the `#warning`/`#define` mismatch in this block as a bug — it is known and temporary.
…d#5480) * comprehensive C++, Web UI, and CI/CD conventions, a condensed setup/build guide, and a new agent-mode build/test workflow with ordered commands, timeouts, validation gates, manual web validation, and troubleshooting steps. * repository-level AI review/configuration rules, workflow best-practices, safeguards to detect and flag edits to generated web assets, and alignment checks linking AI-facing rules with human-only reference sections. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
…d#5480) * comprehensive C++, Web UI, and CI/CD conventions, a condensed setup/build guide, and a new agent-mode build/test workflow with ordered commands, timeouts, validation gates, manual web validation, and troubleshooting steps. * repository-level AI review/configuration rules, workflow best-practices, safeguards to detect and flag edits to generated web assets, and alignment checks linking AI-facing rules with human-only reference sections. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
…d#5480) * comprehensive C++, Web UI, and CI/CD conventions, a condensed setup/build guide, and a new agent-mode build/test workflow with ordered commands, timeouts, validation gates, manual web validation, and troubleshooting steps. * repository-level AI review/configuration rules, workflow best-practices, safeguards to detect and flag edits to generated web assets, and alignment checks linking AI-facing rules with human-only reference sections. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
…d#5480) * comprehensive C++, Web UI, and CI/CD conventions, a condensed setup/build guide, and a new agent-mode build/test workflow with ordered commands, timeouts, validation gates, manual web validation, and troubleshooting steps. * repository-level AI review/configuration rules, workflow best-practices, safeguards to detect and flag edits to generated web assets, and alignment checks linking AI-facing rules with human-only reference sections. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
…d#5480) * comprehensive C++, Web UI, and CI/CD conventions, a condensed setup/build guide, and a new agent-mode build/test workflow with ordered commands, timeouts, validation gates, manual web validation, and troubleshooting steps. * repository-level AI review/configuration rules, workflow best-practices, safeguards to detect and flag edits to generated web assets, and alignment checks linking AI-facing rules with human-only reference sections. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
…d#5480) * comprehensive C++, Web UI, and CI/CD conventions, a condensed setup/build guide, and a new agent-mode build/test workflow with ordered commands, timeouts, validation gates, manual web validation, and troubleshooting steps. * repository-level AI review/configuration rules, workflow best-practices, safeguards to detect and flag edits to generated web assets, and alignment checks linking AI-facing rules with human-only reference sections. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Reworks AI instructions, to separate "coding agent" from "code review" instructions.
Adds C++ coding guidelines that were extracted from the WLED source code (mainly by AI). The new guides can be used both for contributor information, and as a "best practice" database in automated code reviews by the rabbit.
Update: I've moved the coding style guides into their own directory /docs, and "out of the way" for non-review agent tasks. It seems that AI agent tasks ("I need a new bus driver for my Daimler") work faster without the "code review" add-on guides - the agent will still find docs when it needs help. Code reviews (coderabbitAI) with detailed guides are still much better.
Details
HUMAN_ONLYmechanism that hides generic information from the AI, to increase "attention layer excitement"Example for a coderabbit review with the new instructions: MoonModules#324 (comment)
(notice that recommendations refer to the new guidelines, and there is a "things done well" section, too)
This is a request for discussions
The new instructions already work well in WLED-MM, but we need to adjust them for WLED. Most importantly, optimization guides for ESP8266 still need to be added.
more information:
Revising AI review instructions:
Guiding Principles for Efficient AI Instruction Files
Only document what can't be inferred from the code or from general training.
If the AI would get it right without instruction 95% of the time, the instruction probably isn't worth the extra space in context memory.
Prefer short, actionable rules over explanations.
"Do not flag
uint8_t x = int(f)as a bug when the comment says// float→int wrapping" is more useful than a paragraph explaining why. The paragraph is for humans; the rule is for AI.Keep the total injected instruction size per file type low (<1000 lines, best under ~500 words).
With lots of instructions, the value of additional instructions drops rapidly and the distraction cost rises.
Encode "false positive suppressors" first, feature guidance second.
"Don't flag pattern X as a bug" is more impactful than "always do Y" because it directly prevents noise.
Treat instruction files like tests — they need maintenance when the code changes.
If you wouldn't update the instruction file when refactoring the relevant code, don't write the instruction.
Large language models already have extensive general knowledge about C++, ESP-IDF, GitHub Actions, etc. The genuine value of instruction files is narrow but real:
delay()works in FreeRTOSWLED_DISABLE_2D,d_malloc)The key insight: instruction files are most valuable when they prevent false positives (AI flagging intentional patterns as bugs) and encode decisions that can't be inferred from the code alone.
Summary by CodeRabbit
Documentation
Chores