docs: add CLAUDE.md with project gotchas#55
Draft
skialpine wants to merge 3 commits into
Draft
Conversation
Captures project-specific knowledge that isn't obvious from the code:
* Build / flash / serial commands (including the pyserial workaround
when pio device monitor can't get a PTY).
* Code layout: explains the unusual "headers contain implementations"
pattern, where setup() / loop() live, what's in config.h.
* Threading model: WS event callback runs on the AsyncTCP task on a
different core; what's safe / unsafe to share with the main loop;
the wsPendingMask deferral pattern; why cross-task globals need to
be marked volatile.
* WiFi/BLE coexistence: do NOT call WiFi.setSleep(false); the BT
coex layer needs WiFi's sleep windows for BLE slots.
* ESPAsyncWebServer ordering rules (server.begin() last, server.end()
doesn't clear handlers, single WS client cap).
* macOS curl AAAA workaround (curl -4 or --resolve) — saves 5s per
request when debugging.
* AP-mode fallback credentials (DecentScale / 12345678 / 192.168.1.1).
* "When X is broken, check Y" troubleshooting table.
* Naming conventions (b_, i_, t_, f_ Hungarian-ish prefixes).
* .gitattributes LF-normalization note for bisect across that commit.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fact-check on PR decentespresso#55 caught two loose phrasings: * "races the OLED draws in loop()" understated the issue. The races are against any draws issued from the main-loop task, which includes button callbacks and menu/display helpers, not just code literally inside loop(). * "just bool + uint32_t writes" mis-described StopWatch (it has an enum + multiple uint32_t fields plus a function pointer). The actual safety argument is that each individual field write is atomic on ESP32, so start/stop/reset can't tear a reader on the main-loop task. No semantic change to the threading model the doc is describing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CLAUDE.md is a living document; future sessions should update it when they hit a new footgun or workflow shift. Add explicit guidance on what to add, what to skip, and when to prune, so it doesn't decay into stale advice. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a
CLAUDE.mdat the repo root documenting project-specific knowledge that isn't obvious from the source: build/flash commands, code layout (the headers-with-implementations pattern, wheresetup()andloop()live, whatconfig.hdoes), the AsyncTCP-task vs main-loop threading model and thewsPendingMaskdeferral pattern, whyWiFi.setSleep(false)is the wrong call with BLE active, ESPAsyncWebServer init ordering, the macOScurl -4AAAA workaround, AP-mode fallback credentials, a "when X is broken, check Y" table, naming conventions, and a.gitattributesLF-normalization note for bisects.Distilled from the debugging session that produced #54. Split out as its own PR so #54 stays focused on the firmware change.
Merge order
Land #54 first. This PR documents the WebSocket protocol, deferral pattern (
wsReplacePending/processWsPendingCmds/WSP_*bits), WS frame-guard snippet, and corresponding line refs that are introduced by #54. Against baremainthe references look forward; againstmainafter #54 lands they're accurate.Test plan
Generated with Claude Code