Skip to content

fix(runbook): C6 build command produced a 4MB image on 16MB hardware, and 4MB boards had no command of their own - #1925

Open
clonea1 wants to merge 4 commits into
ruvnet:mainfrom
clonea1:contrib/runbook-build-order
Open

clonea1 wants to merge 4 commits into
ruvnet:mainfrom
clonea1:contrib/runbook-build-order

Conversation

@clonea1

@clonea1 clonea1 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

The copy-paste build command in firmware/esp32-csi-node/RUNBOOK.md concatenates the three sdkconfig.defaults* files in the order defaults -> .16mb -> .esp32c6. In a single concatenated file the last assignment wins, and .esp32c6 sets FLASHSIZE "4MB" with partitions_4mb.csv — so it overrode the 16MB layer and the command silently produced a 4MB image on 16MB hardware. Not a broken build, just the wrong one, which is why it survived.

What made it hard to spot: .esp32c6 does not set BOOTLOADER_APP_ROLLBACK_ENABLE, so the rollback flag survived from .16mb. The one symptom the runbook told you to check for was the one symptom that did not appear.

MEASURED both ways — same worktree, same container, only the order changed:

.16mb then .esp32c6  ->  FLASHSIZE "4MB"   partitions_4mb.csv    ROLLBACK=y
.esp32c6 then .16mb  ->  FLASHSIZE "16MB"  partitions_16mb.csv   ROLLBACK=y

Second half: 4MB and 8MB boards had no command of their own

The section contained exactly one command and it was the 16MB one. Anyone on a stock 4MB or 8MB C6 dev board had to infer their path from a correction notice written for a different flash size, and the surrounding text framed a 4MB image as the failure mode rather than as a supported target.

There are now two commands. The 4MB/8MB one simply omits sdkconfig.defaults.16mb, so sdkconfig.defaults.esp32c6 is the last word and no override ordering is needed at all. That yields partitions_4mb.csv — two 1.875MB OTA slots against a ~978KB binary.

One behavioural difference, documented not changed

CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is set only in sdkconfig.defaults.16mb, so a 4MB build has no automatic rollback: an OTA'd image does not boot PENDING_VERIFY and the bootloader will not revert it. Nothing about 4MB flash forces this — partitions_4mb.csv has an otadata partition and two OTA slots — it is only which layer the flag lives in. Left as documentation rather than a config change, because moving that flag needs a hardware test on a 4MB board.

Also flags an open question found while verifying: even with the corrected order the build yields CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=64 while the fleet is documented at 128, and no combination of the three files produces 128. Marked OPEN rather than "fixed", since it should be read off running silicon first.

Docs only. One file.

🤖 Generated with claude-flow

Joe and others added 4 commits September 13, 2026 21:54
… it warns against

The three sdkconfig.defaults files disagree about flash geometry, and in a
single concatenated file the LAST assignment wins:

    sdkconfig.defaults          FLASHSIZE "8MB",  partitions_display.csv
    sdkconfig.defaults.16mb     FLASHSIZE "16MB", partitions_16mb.csv, ROLLBACK=y
    sdkconfig.defaults.esp32c6  FLASHSIZE "4MB",  partitions_4mb.csv

The command concatenated `.16mb` then `.esp32c6`, so `.esp32c6` overrode
`.16mb` and every build came out 4MB with partitions_4mb.csv. Swapping the
last two fixes it: `.16mb` is the override layer describing the fleet's real
flash geometry, so it must come last.

MEASURED both ways, same worktree and container, only the order changed:

    .16mb then .esp32c6  ->  "4MB"   partitions_4mb.csv    ROLLBACK=y
    .esp32c6 then .16mb  ->  "16MB"  partitions_16mb.csv   ROLLBACK=y

Why it survived this long: the only symptom the old text told you to watch for
was a missing CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE, and that flag was the one
thing the broken order got RIGHT -- `.esp32c6` does not set it, so it came
through from `.16mb` either way. The build reported success, the rollback
warning did not fire, and the flash size was wrong. Found only by running the
runbook's own verification grep against the artifact instead of trusting the
build's exit code.

Also records an open question rather than papering over it: even corrected,
the build yields CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=64, while the fleet is
documented at 128 -- and no combination of these three files produces 128. Read
it off a running node before editing any defaults file.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01PVWMiHQifoYXL7uL3bphrZ
…e file itself

sdkconfig.defaults.16mb's own header comment says:

    idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.defaults.esp32c6;sdkconfig.defaults.16mb" build

which is the swapped order. The runbook's `cat` had the last two arguments
transposed relative to the instructions sitting inside the very file it was
concatenating.

So the fix in 5835cb4b is not a hypothesis that happened to measure well -- it
restores documented intent. Two independent confirmations now stand behind it:
the A/B build (order the only variable, 4MB vs 16MB) and this docstring.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01PVWMiHQifoYXL7uL3bphrZ
The build section had one command in it and that command was the 16MB fleet's.
Anyone on a stock 4MB or 8MB C6 dev board had to infer their own path from a
correction notice written for a different flash size, and the surrounding text
framed a 4MB image as the failure mode rather than as a supported target.

Now there are two commands. The 4MB/8MB one omits sdkconfig.defaults.16mb, so
the target overlay is the last word and no override ordering is needed at all.
That yields partitions_4mb.csv: two 1.875MB OTA slots against a ~978KB binary.

Also records the one real difference, which was not written down anywhere:
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is set only in sdkconfig.defaults.16mb,
so a 4MB build has no automatic rollback and an OTA'd image will not be
reverted by the bootloader. Nothing about 4MB flash forces that --
partitions_4mb.csv has otadata and two OTA slots -- it is only which layer the
flag lives in. Documented rather than changed, because changing it needs a
hardware test on a 4MB board.

Co-Authored-By: claude-flow <ruv@ruv.net>
… KiB

Unblocks the "Verify binary size budget" step of Build firmware
(esp32s3 / 8mb) -- this branch's head already carries the image growth
from 130afab but was still checked against the old 1152 KiB limit.

Co-Authored-By: claude-flow <ruv@ruv.net>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant