Skip to content

fix(tools): the flash budget gate fails when it cannot see the firmware.bin - #290

Merged
angeloINTJ merged 1 commit into
mainfrom
fix/flash-budget-missing-bin
Oct 24, 2026
Merged

angeloINTJ merged 1 commit into
mainfrom
fix/flash-budget-missing-bin

Conversation

@angeloINTJ

Copy link
Copy Markdown
Owner

What

tools/check_flash_budget.py <env> <log> holds each image's firmware.bin, signed, to the OTA ceiling and to the size recorded for it ("bin"). When .pio/build/<env>/firmware.bin was not there, it printed a NOTE and exited 0: a run in a tree whose .pio/build had been cleaned passed without reading any .bin. Found in the review of S10c D5 (2026-10-23, on the UI-drivers branch). The same happened when OTA_APP_SAFE_MAX_SIZE could not be read out of src/ota/ota_layout.h, which --table already treats as a failure.

Both are failures now, and the message names what was not checked. An image under ota_exempt (pico_w_test_https) still needs no .bin. CI is unaffected: its firmware job builds the image and runs the gate in the same tree (.github/workflows/build.yml, "Build" then "Check flash budget"). The old NOTE said "no firmware.bin next to the log", while the gate looks under .pio/build/<env>/; the message names that path now.

Proof

Reproduction on real data: pico_w_release's build log and .bin from main at a8ccf4c (#288, the one PR since, changed only pico_w_test_https).

.pio/build/pico_w_release/firmware.bin main's gate this gate
present exit 0, "firmware.bin signed 1035181 B, 5203 B under the OTA ceiling" exit 0, the same
cleaned exit 0, NOTE exit 1, FAIL naming the path

New cases in tools/test_flash_budget.py. They run a copy of the gate the way CI does (the env and its log), in a temporary tree:

case main's gate this gate
A no .pio/build exit 0 (fails the case) exit 1
B a .bin of its recorded size exit 0 exit 0
C a .bin 1 B over its record exit 1 exit 1
D an exempt image, no .bin exit 0 exit 0
E an ota_layout.h the gate cannot read exit 0 (fails the case) exit 1

Against main's gate the suite gives 22 ok and 2 failed (A and E); with the fix, 24 ok.

CI gates run locally in a depth-1 clone, the way CI checks out: 36 of 36 steps pass, static analysis included (quick mode: native suites, sanitizers and fuzz skipped). check_flash_budget.py --table passes (9 images, 1 exempt).

Host only: no image changes, nothing here runs on a board.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LyLm7Q1o7kCHngE63BnoTx

…re.bin

tools/check_flash_budget.py <env> <log> holds the image's firmware.bin,
signed, to the OTA ceiling and to the size recorded for it ("bin"). When
.pio/build/<env>/firmware.bin was not there, it printed a NOTE and exited
0, so a run in a tree whose .pio/build had been cleaned passed without
reading any .bin. Found in the review of S10c D5 (2026-10-23, on the
UI-drivers branch). It did the same when OTA_APP_SAFE_MAX_SIZE could not
be read out of src/ota/ota_layout.h, a condition --table already fails on.

Both are failures now, and the message names what was not checked. An
image under "ota_exempt" (pico_w_test_https) still needs no .bin. CI is
unaffected: its firmware job builds the image and runs the gate in the
same tree. The NOTE said "no firmware.bin next to the log" while the gate
looks under .pio/build/<env>/; the message names that path now.

Reproduction, on pico_w_release's log and .bin built from main at a8ccf4c
(#288, the one PR since, changed only pico_w_test_https):
- with .pio/build/pico_w_release/firmware.bin in place, main's gate and
  this one both pass ("firmware.bin signed 1035181 B, 5203 B under the
  OTA ceiling");
- with .pio/build cleaned, main's gate prints the NOTE and exits 0; this
  one fails and exits 1.

tools/test_flash_budget.py gains five cases that run a copy of the gate
the way CI does, in a temporary tree: no .pio/build fails (A), a .bin of
its recorded size passes (B), one 1 B over its record fails (C), an
exempt image needs no .bin (D), and an ota_layout.h the gate cannot read
fails (E). Against main's gate, A and E fail and B, C and D pass (22 ok,
2 failed); with the fix, 24 ok. The CI gates, run locally in a depth-1
clone (static analysis included; native suites, sanitizers and fuzz
skipped): 36 of 36 steps pass. Host only: nothing here runs on a board.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyLm7Q1o7kCHngE63BnoTx
@github-actions github-actions Bot added documentation Improvements or additions to documentation tools Build tools, scripts, and developer tooling labels Oct 24, 2026
@angeloINTJ
angeloINTJ merged commit be56633 into main Oct 24, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation tools Build tools, scripts, and developer tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant