Repository navigation
pico_w_test: serve the licence page from LittleFS, for 3,699 B of room under the OTA ceiling - #297
Merged
Merged
Conversation
…tleFS, for 3,699 B of room under the OTA ceiling pico_w_test (the bench image with the full CLI, not published; its manifest comment says to take room from this image, never from the release) signs at 1,040,309 B on main 9f4da77 against the OTA ceiling of 1,040,384 B: 75 B of room (763 B at 2075b84; #294 and #295 took 688 B). The UI-drivers branch, after its sync with main, is 101 B over. The maintainer chose "open room in pico_w_test" by the means #288 used for pico_w_test_https (2075b84): LICENSE_PAGE in custom_fs_pages, so the page's gzip is served from /web/ on LittleFS. pico_w_test_https extends this profile and keeps its own list, which already had the page: its generated section is byte for byte main's. Measured, all nine built from scratch on 9f4da77 plus this change (the pio shim of this machine, one build at a time, check_flash_budget.py right after each): - pico_w_test: flash used 1,028,036 -> 1,024,412 B (-3,624), .bin 1,040,068 -> 1,036,444 B (sha256 c92bd240 -> 87dac855), signed 1,036,685 B, room under the ceiling 75 -> 3,699 B (the branch's 101 B over would become 3,523 B of room: arithmetic, not a build). RAM 109,212 B unchanged. Two builds of the tree give one sha256. Still under one 4 KiB sector, so the gate's WARN stays. - Why -3,624 B and not the page's 4,260 B: nothing in this image was served from a file before, so the linker had dropped serveProtectedFsPage( ). nm -S -C of main's ELF against this one: LICENSE_PAGE_GZ -4,260 B (gone), serveProtectedFsPage( ) +428 B (linked now), handleLicense( ) 24 -> 16 B; no other symbol changes size. Those make -3,840 B; the other +216 B are the "Page asset missing" notice and the file name in .rodata (+212 B, from a diff of the strings of the two .bin) and 4 B of .text outside any symbol (size -A: .text +424, .rodata -4,048). pico_w_test_https lost 4,256 B in #288 because it already linked the route. - The other eight are byte for byte main's (sha256 of firmware.bin against the table of the base build; their ELFs equal its ELFs, too): pico_w_release af3711c7c27df592b77ca7163c783471f6e7d9c8ad906ce8ebc089f872f84233 1035620 pico_w_test_https c67194e81d3552af57a0b630d5314b666331ae6b5a589d4ba16dd397ffd631ec 1040876 pico_w_asserts 81aa53d861273deb8ce04aed110442f21385ad66c79355fae5dcb4d0ac8f7cf7 1037924 pico_w_alpha b5d7d079db25cab25e37e2f60df2319f2018383324e35dfad4495d064adaa2d8 990380 pico_w_air 4291184e6e1609db51bf820819ddcacdd628901052a5a1f2b74031a000cd8555 1035340 pico2_w_release 42564ce8e0be271887da13d1b3d6f925c6d43ed8702458d77909e7b18c5d9c8c 999720 pico_wire 3438b89af5e3036564e323430a417a0f1455cb26562941349b38b346cf6cee03 604336 pico_wiretft 471e41929fa44bd0dd7ae82ff0134590238d8fbd53ce175ebcd185ead1c91157 787336 - tools/flash_budget.json: pico_w_test budget and measured -> 1,024,412, bin -> 1,036,444; the row of PLANO_STABLE 3.1 reads 1.036.685 / 3.699. - check_flash_budget.py on all nine (pico_w_test OK, with the WARN above; the other eight with their records unchanged), --table, test_flash_budget.py (24 ok), gen_features.py --check (rc 1 with features.toml edited and profiles.ini stale, rc 0 after regenerating; profiles.ini gains one line, in [env:pico_w_test]), check_features.py, test_build_custom.py, check_readme_numbers.py, check_angulo.py, and the 41 python commands of the CI gates job (rc 0 each, as on main) pass. The pio test suites were not run: no source file changed. The deploy step grows with it, for both bench images. The build leaves data/web/license.html.gz (4,260 B) and, for pico_w_test_https, alarms, files and telemetry besides; the env built last decides what is left there. Until now the requirement was written in the manifest comment of pico_w_test_https only; AGENTS.md (Gravar firmware) says it once for both: upload to /web/ with POST /api/upload?uploadDir=/web, never uploadfs; without the file the route answers 200 with "Page asset missing", which web_test_suite.py reports; an OTA reformats the LittleFS, so upload again after it. Not verified on hardware: no Pico W on the rig (the rig's board is a Pico 2 W since 2026-10-22). The check for when one is: flash this image, upload data/web/license.html.gz, and run web_test_suite.py: /license must load from the file, and without the upload it must report "Page asset missing". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
…ml.gz, the file the build writes
The comment of pico_w_test_https told the bench to upload data/web/{alarms,files,tel,license}.html.gz;
tools/build_webui_gz.py:180 writes TEL_PAGE as telemetry.html.gz, so "tel.html.gz" never exists. One word,
found while moving pico_w_test's licence page to LittleFS in the commit before.
A comment of the manifest: gen_features.py --check passes with the generated files untouched (comments do
not reach profiles.ini), check_features.py passes (with this machine's pio shim in PATH), check_angulo.py
passes. No image byte can change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
angeloINTJ
pushed a commit
that referenced
this pull request
Oct 28, 2026
First parent: abf43e3 (C5). What lands from main: PR #297 (9eb4252, 8a38cbc): pico_w_test serves its licence page from LittleFS (custom_fs_pages = ["LICENSE_PAGE"] in tools/features.toml, generated into tools/generated/profiles.ini), which opens room under the OTA ceiling; the AGENTS.md bullet on the pages that pico_w_test and pico_w_test_https keep on LittleFS; main's row and numbers for the image in PLANO_STABLE.md and flash_budget.json. Conflicts (2), as resolved - docs/analysis/PLANO_STABLE.md: both sides changed the pico_w_test row of section 3.1 (C1's -101 B; main's 3.699 B of room, measured on main's own tree). The table is the branch's, and the row is the one tools_s10c/budget_set.py writes from this merge's build: | pico_w_test | 1.036.853 | 3.531 |, the line the gate itself prints. C5's bullet ("over the ceiling on this branch") is now one dated line in the past: 101 B over after C1, cleared by #297 at this merge. - tools/flash_budget.json: the branch's file, then main's two added sentences (measured_on, measured_at_commit), then this merge's (budget_set.py's sentence and a measured_at_commit entry). pico_w_test's budget, measured and bin come from this merge's build, not from either side: main's were measured on main's tree (1,024,412 and .bin 1,036,444), the branch's before #297 (1,028,212 and .bin 1,040,244). Merged clean: AGENTS.md (main's bullet is about pico_w_test and pico_w_test_https only; re-read, nothing on this branch contradicts it), tools/features.toml and tools/generated/profiles.ini. profiles.ini is not edited here: python3 tools/gen_features.py --check says the generated files are up to date. pico_w_test's numbers (from the build, 2026-10-28; the expectation written before it was about -3,624 B) - .bin 1,040,244 -> 1,036,612 B (-3,632; main's own pair was 1,040,068 -> 1,036,444, -3,624); flash used 1,028,212 -> 1,024,580; signed 1,036,853 B, 3,531 B under the OTA ceiling of 1,040,384 B (it was 101 B over from C1 to C5). The gate's WARN stays: under one 4 KiB sector. - By nm -S exactly three symbols differ from C5's image, main's three: WebManager::handleLicense() 24 -> 16 B, WebManager::serveProtectedFsPage(unsigned short, char const*) new, 428 B, WebUI_GZ::LICENSE_PAGE_GZ 4,267 B gone. elf_funcoes + reloc_only name the same, plus _fini's padding (2 -> 3 instructions, a link artifact); the notice "Page asset missing" and "/web/license.html.gz" are the new text in .rodata (cmp_c5/summary.txt). Proofs (host only; records in stages/sync6b) - The eleven images from scratch (shim first in PATH, no PLATFORMIO_*, under flock): ten sha256-equal to C5's, pico_w_test_https included (#297 left its generated section as it was); pico_w_test is the only one that changed. - check_flash_budget.py right after each of the eleven builds: exit 0 for all eleven. pico_w_test exited 1 from C1 to C5; it exits 0 now, with the WARN above. - After budget_set.py: check_flash_budget.py pico_w_test exit 0 with no NOTE; --table OK (11 images, 1 exempt); test_flash_budget.py 24 ok; gen_features.py --check, check_features.py (it calls pio: the shim), check_readme_numbers.py (764 cases) and check_angulo.py exit 0; git diff --cached --check clean; no conflict marker anywhere. - The instrument: budget_set.py could not read a row with a negative headroom (its row regex took digits only, and the table had -101); the regex now takes a minus sign (the old file is tools_s10c/budget_set.py.antes_sync6b), and the row it writes equals the one the gate prints. - Not done here: pico_w_test now answers /license with "Page asset missing" until data/web/license.html.gz is uploaded to /web/ (AGENTS.md's new bullet). Not verified on hardware. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
Merged
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.
What
pico_w_test, the bench image with the full CLI (not published), serves its licence page from LittleFS instead of carrying it in flash:LICENSE_PAGEjoins itscustom_fs_pages, as #288 did forpico_w_test_https. The second commit fixes a file name in the https profile's comment (telemetry.html.gz, nottel.html.gz).Why
On main 9f4da77
pico_w_testsigns at 1,040,309 B against the OTA ceiling of 1,040,384 B: 75 B of room (763 B at 2075b84; #294 and #295 took 688 B). The UI-drivers branch, after syncing with main, is 101 B over. The profile's own comment says to take room from this image, never from the release; the maintainer chose this cut on 2026-10-28.Measured
All nine images built from scratch on 9f4da77 plus this change,
check_flash_budget.pyright after each build:pico_w_testflash usedpico_w_test.binserveProtectedFsPage( )(+428 B) and the "Page asset missing" strings (+212 B).nm -S -Cshows these, plushandleLicense( )going from 24 B to 16 B; no other symbol changes size.pico_w_release,pico_w_test_https,pico_w_asserts,pico_w_alpha,pico_w_air,pico2_w_release,pico_wire,pico_wiretft) are sha256-identical to main's; the commit message lists the hashes.tools/flash_budget.jsonand the section 3.1 row ofPLANO_STABLE.mdrecord the new figures.--table,test_flash_budget.py(24 ok),gen_features.py --check,check_features.py,check_readme_numbers.py,check_angulo.pyand the 41 Python commands of the CI gates job all pass.Bench impact
The deploy step grows, for both bench images.
AGENTS.md(Gravar firmware) now says once for the two of them:.gzthat the build leaves indata/web/to/web/withPOST /api/upload?uploadDir=/web, and never useuploadfs;web_test_suite.pyreports;Not verified on hardware
There is no Pico W on the rig; its board is a Pico 2 W since 2026-10-22. When one is on the rig:
data/web/license.html.gz, and runweb_test_suite.py:/licensemust load from the file;🤖 Generated with Claude Code
https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu