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 3 commits into
ruvnet:mainfrom
clonea1:contrib/runbook-build-order
Open

clonea1 wants to merge 3 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

@aepod aepod left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hit the same thing. Following RUNBOOK §1's C6 command left my C6 (an 8 MB module) on the 4 MB layout, visible as max_size: 1900544 (0x1D0000, the partitions_4mb.csv app slot) in /ota/status. MEASURED. That the concatenation order was the cause is CLAIMED, from my 2026-09-29 build notes; I kept no A/B log.

Putting .16mb last fixes the order, and the separate 4 MB/8 MB commands are clearer. I'll build and boot the new 4 MB command on that C6 and confirm. I dropped my own copy of this fix. +1.

@clonea1

clonea1 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for testing it. To make the result easy to read, these are the /ota/status max_size values each layout should report (the OTA slot size from the partition table):

command layout max_size
16MB boards partitions_16mb.csv 4194304 (0x400000)
4MB and 8MB C6 dev boards partitions_4mb.csv 1900544 (0x1D0000)

On your 8 MB module, the "4MB and 8MB" command is expected to give 1900544: the C6 target overlay carries 4 MB geometry, so this command builds the 4 MB layout on both sizes by design. Seeing that number means the command worked. The bug this PR fixes is a 16 MB board reporting 1900544, which should report 4194304.

One more thing to check while you're there: a 4 MB/8 MB build has no app rollback (BOOTLOADER_APP_ROLLBACK_ENABLE is only set in sdkconfig.defaults.16mb), so a bad OTA on that board won't revert by itself.

🤖 Generated with Claude Code

@clonea1
clonea1 force-pushed the contrib/runbook-build-order branch from b335f45 to 620985b Compare October 10, 2026 05:16
Joe and others added 3 commits October 10, 2026 17:08
… 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>
@clonea1
clonea1 force-pushed the contrib/runbook-build-order branch from 620985b to fd5d367 Compare October 10, 2026 21:15

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.

3 participants