Repository navigation
chore: v2.12.0 - #300
Merged
Merged
chore: v2.12.0#300
Conversation
The only source line of the v2.12.0 release chore: SIMUT_VERSION "2.11.1" -> "2.12.0" (src/SystemDefs_Limits.h). CONFIG_VERSION stays at 26 and the security version at 1 (keys/ota_policy.json, series 1); git diff v2.11.1 HEAD -- keys src/ota/ota_layout.h is empty (2026-10-28). Proof, 2026-10-28, on this tree (origin/main 96a5af0 plus this line), host only: - git diff --stat origin/main -- src WebUI.h data keys platformio.ini 'tools/*.py': one file, one line. - The nine images built after rm -rf .pio/build/<env> (pio shim, under the shared lock), tools/check_flash_budget.py <env> <log> right after each: nine exit 0. The version has as many characters as 2.11.1 and nothing moved: the flash used of all nine equals its record, and the eight .bin that have a record equal it (pico_w_test_https has none: it is exempt from the OTA ceiling), so tools/flash_budget.json and docs/analysis/PLANO_STABLE.md section 3.1 are untouched; --table and tools/test_flash_budget.py pass. Signed .bin (bin + 241 B): release 1,036,133 (4,251 B under the OTA ceiling), alpha 990,621 (49,763), Air 1,035,581 (4,803), Pico 2 W 1,000,241. Against the published v2.11.1: +2,776, 0, +4,096 and +2,824 B. "2.12.0" is in the four published images and "2.11.1" is not (grep -c -a). - The eleven native suites, 0 failures: 328 + 17 + 54 + 34 + 62 + 14 + 59 + 51 + 83 + 13 + 19 = 734 cases; the same eleven under AddressSanitizer and UBSan (the gates job's last step): exit 0. Not verified on hardware: nothing here ran on a board. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
"Unreleased" becomes "v2.12.0 (2026-10-28)" in CHANGELOG.md and CHANGELOG.pt-BR.md, each with 19 sections in the same order. - The header says what the release is, and that CONFIG_VERSION stays at 26 and the security version at 1. - Each of the 35 pull requests merged since v2.11.1 (#260 to #299) is named in a section, and the headings of the existing sections carry their numbers now. New sections: the link inside the wait for the time (#269, #271); the reply that lost its framing (#189, by #272 and #273); the plain client on the TLS port (#274, by #277); the injected touch (#280); the SIMUT Wire and the network as a driver (#260-#265, #267, #268, #275, #276); Under the hood; Flash; The bench, a placeholder the gate's docs change fills in; Upgrading; and Known, item by item against v2.11.1's: out with the configurator for the Pico 2 W (#260), #189 and the alpha's empty event names (#286); in with the six the maintainer listed. - The #294 bullet that said "139 B of OTA headroom left of 763" says it was that day's room and that #297 gave it back: check_flash_budget.py says 3,427 B for pico_w_test today. - Measured here, 2026-10-28: Flash against the published v2.11.1 (release +2,776 B, alpha 0, Air +4,096, Pico 2 W +2,824), 734 host test cases in 11 suites, 62 routes (52 gated, 10 public by design). Proof: chore/check_changelog.py (scratchpad) finds 35 of 35 in both entries, the same PR numbers in the headings of both, the same last five sections, no Unreleased heading and no placeholder; its three negative controls (a PR number removed, a heading removed, an Unreleased heading put back) give exactly one finding each. The digit runs of the two entries are identical once the locale's separators are removed. No pictograph in either entry. Not verified on hardware; the entry says which claims are by the code and which were measured, and where. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
The places the number lives, as the v2.11.1 chore found them (git show f1bfd13 --stat): the current-release row and the manual row of the three READMEs, docs/MANUAL.md and docs/MANUAL.pt-BR.md, docs/README.md, the manual's chapters 1 (the versions, with the v2.12.0 list), 3, 4, 9, 13, 14 and 28 and Appendix C (a "Linha 2.12" with its row), and docs/index.html with its pt and es dictionaries (a new release article, the oldest dropped, the keys shifted). The panel's 66.5 MHz is written as a setting ("ajustado a"), 24 MHz as the measured before (bench, 2026-10-15): the clock after the change was measured only on a study build (#278), and the gate checks it. docs/MANUAL.pt-BR.html is the one deviation from "a generated file is never edited by hand", recorded the way 501b7ac (PR #298) and 6dbea49 (PR #299) recorded it. With pandoc 3.7.0.2, build_manual.py no longer writes class="header|odd|even" on table rows, so a plain regeneration rewrites 3,081 lines this change has no business with. The diff is the substance only: 56 insertions, 30 deletions. Checked, not assumed: (i) the committed file with its row classes stripped equals the generator's output for the old sources; (ii) the committed file equals that output with the classes put back by position (thead rows "header", tbody rows "odd"/"even"), so the new file is the new output with the same rule; (iii) the file after this change equals the regeneration from the final sources (cmp, a fresh copy of the tree). python3 tools/build_manual.py --check passes. Proof, 2026-10-28: git grep -n "2\.11\.1" -- . ':!CHANGELOG*' ':!*.html' leaves 19 files, all history phrasing (the VERIFICATION rows, "until v2.11.1" and "since v2.11.1" sentences, measurements labelled "release 2.11.1", the Appendix C row, the previous release's list in chapter 1, a marker fixture of test_ota_sig); in the HTML, the v2.11.1 article of the site and the same history in the manual. A planted "v2.11.1" in a copy of docs/MANUAL.md is found by the same grep. The 39 steps of the CI gates job (read from build.yml, pip and pio steps left out) exit 0, among them scan_secrets.sh, check_angulo.py, check_readme_numbers.py (the READMEs quote 734 cases in 11 suites) and check_flash_budget.py --table. The es-ES text of the new site article is a proposal until a native speaker reviews it. Not verified on hardware. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
…log, one claim made honest) No file under src/ changes (git diff --stat HEAD~1 -- src is empty). - CHANGELOG.md and CHANGELOG.pt-BR.md, the same 19 sections in both: - #262's display fix, which every image with the TFT panel carries: a top panel pinned to a slot with no running sensor drew its name from heap bytes (104077d). It falls back to "Empty / Inactive" now, as the bottom panel does, and the DisplayManager constructor writes the fields it skipped. - #272's additions to the API and the console: metr.cgw in /api/status, simut_web_aborts_total{cause="short_write"} in /metrics and the short write among the send aborts of show net status; on the bench, 4 cuts in 5,000 replies were counted one for one. - #263: the Wire's emergency console has ip and dns (the Wire is not published). - The header says the panel's SPI "is set to" 66.5 MHz: only the 24 MHz before was measured on the release image; the after came from study builds (#278). The manual's cap02 and cap30 say "ajustado a 66,5 MHz" too. - Upgrading says what a Pico W shows after the apply: it keeps only /config/system.bin, /lang is gone, and the device is in English until the packs are back and it has rebooted (the comment #287 put in release-ota.yml). A Pico 2 W keeps its packs, so the labels added in this release read in English until the two new packs replace them. - pt-BR: "O console", not "A console", and "o Air" throughout. - docs/MANUAL.pt-BR.html by the hunk method of #298 and #299: 2 insertions, 2 deletions. The committed file with its row classes stripped equals the generator's output for the old sources; the committed file equals that output with the classes put back by position; the new file is the new output with the same rule. - docs/index.html (en, pt, es): the new release article set "24 of 2,000" against "0 of 6,000", a night baseline against runs at other hours, and the changelog itself says the rate moved with the hour. It cites the A/B of #273 on the same Pico W and network instead: 3 of 1,000 replies cut with #272 alone, 0 of 1,000 with #273. Proof, 2026-10-28: tools/check_*.py of the CI gates job (39 steps) exit 0, among them check_angulo.py and check_readme_numbers.py (734 cases in 11 suites); scan_secrets.sh is clean; build_manual.py --check passes. The release scratchpad's check_changelog.py finds 35 of 35 in both entries, the same sections, identical digit runs, and its three negative controls give exactly one finding each. Not verified on hardware. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
This was referenced Oct 30, 2026
angeloINTJ
pushed a commit
that referenced
this pull request
Oct 30, 2026
First parent: 22d83de. What lands from main (c902894..cf97b95): #299 (96a5af0), the Files page says a refused upload was refused: doUpload( ) in WebUI.h, fil_up_refused in both packs' @webdict, tools/test_webui_upload_result.py; #300 (229d5d5), chore v2.12.0: the version in src/SystemDefs_Limits.h, both CHANGELOGs, the READMEs, the manual and the site; #301 (e776822), the release gate's docs; #302 (cf97b95), the savings floor without the linker's alignment fill: tools/measure_savings.py (flash_fill( ), FLASH_TOL = 8), tools/test_measure_savings.py (45 cases), tools/feature_savings.json re-recorded (16 floors), AGENTS.md, tools/README.md, docs/analysis/ECONOMIA_DE_RECURSOS.md, a step's comment and name in build.yml. Conflicts (7), as resolved - data/lang/language_pt-BR.lng, data/lang/language_es-ES.lng (one line each, the @webdict): the union by key against the base (c902894's): 557 keys = the branch's 556 (538 + the 18 thm_) + main's fil_up_refused, put after fil_up_err where main put it; every other line the branch's (main changed that line only). check_lang_packs.py OK, pt-BR 52,706 B and es-ES 54,727 B of the 65,536 B file ceiling. - docs/analysis/PLANO_STABLE.md 3.1: the branch's table (ten rows, the two Angulo images included); every row is what tools_s10c/budget_set.py writes from this merge's builds. - tools/flash_budget.json (five hunks): the branch's file; measured_on = the branch's string + the 633 characters main appended to the base's (measured_at_commit: main appended none) + this merge's sentence; every number from the builds (budget_set.py for ten images; pico_w_test_https is unchanged, 1,029,188 B used = its budget). - tools/features.toml (one comment): the pico_w_test headroom with both figures, main's 3.427 B on cf97b95 (3.539 B before the refused-upload message) and this tree's 3.267 B, which PLANO_STABLE's row now says. - tools/README.md: the branch's rows; measure_savings.py = the branch's row with main's "Desde 30/10" sentence in the place of its "Desde 22/10" one, and the date; test_measure_savings.py = main's row (the branch left it as the base). - tools/test_measure_savings.py: main's rewrite with the branch's cases kept inside it: the SIMUT_SAVINGS_PIO block after main's tagged [g3] line in pio_run_cases( ), flips_cases( ) beside table_cases( ), and main( ) runs it last. 21 cases at the base, 42 on the branch, 45 on main, 66 merged = 45 + (42 - 21): none dropped, none duplicated. Merged clean: WebUI.h, tools/measure_savings.py (below), src/SystemDefs_Limits.h, AGENTS.md, build.yml, both CHANGELOGs, the READMEs, the manual, ECONOMIA_DE_RECURSOS.md, tools/feature_savings.json. tools/measure_savings.py, how the two halves meet (the merged file read whole) - Main's half (201 changed lines) is the floor: flash_fill( ), FLASH_TOL, pio_build( ) returning 'fill', gate_flash( ) = flash - fill, measure( ) keeping fill_base/fill_off, print_table( ), cmd_check( ) letting a drop of FLASH_TOL pass. The branch's half (98 changed lines) is the matrix: the ui=<id> flips (CHOICES, flip_key, cost_env, flips_of, plan_flip), env_text( ) naming the Angulo's static-RAM budget, the 13th check, SIMUT_SAVINGS_PIO. The matrix builds through pio_build_full( ), which keeps the whole `used` (the slot holds the fill), so the halves share no function body: the changed lines of the merged file against main's are exactly the branch's 98, and against the branch's exactly main's 201 (compared as sets of added and removed lines: identical both ways). They meet in pio_run( ): pio_build( ) asks for the map through it and the branch picks the pio binary in it; the suite holds both in pio_run_cases( ). --check/--update never take the ui= branch, --matrix/--checks never read 'fill'; no code that uses bank_pad, a 'pad' key or BANK_SECTION is left in tools/ (the label of main's case [e5] still says "it was 0 for bank_pad", as history). - test_measure_savings.py 66/66. Main's 15 mutations (sav_20261029/mutate.py) on the merged file: each caught by exactly the cases its table names (m1..m15 "== expected"). Its harness copies only tools/, and the branch's flips_cases( ) read src/ and the manifest, so the unmutated copy crashed (rc=1) after main's cases; stages/sync8/scripts/mutate_merged.py links the rest of the tree beside the copy and the unmutated copy is rc=0, none failed. The eleven images (from scratch, the shim first in PATH, no PLATFORMIO_*, under flock; the baseline is the same eleven at 22d83de built first the same way: sha256-equal to sync 7's in all eleven, the instrument's control) image 22d83de -> merge main's pair (c902894 -> cf97b95) pico_w_release 1,035,956 -> 1,036,060 +104 +112 pico_w_test 1,036,772 -> 1,036,876 +104 +112 pico_w_test_https 1,041,220 -> 1,041,220 0 0 (other sha256) pico_w_asserts 1,038,260 -> 1,038,364 +104 +112 pico_w_alpha 990,380 -> 990,380 0 0 (other sha256) pico_w_air 1,035,340 -> 1,035,340 0 0 (other sha256) pico2_w_release 999,936 -> 1,000,048 +112 +112 pico_wire 604,312 -> 604,424 +112 +112 pico_wiretft 787,664 -> 787,776 +112 +112 pico_wiretft_angulo 827,504 -> 827,616 +112 (not a main image: like pico_wiretft) pico2_w_angulo 1,036,752 -> 1,036,864 +112 (not a main image: like pico2_w_release) Decoded (nm -S, objdump -h, stages/sync8/decode): in every image that carries the Files page exactly two symbols move, WebUI_GZ::FILE_PAGE_GZ (+109..+112 B, #299) and WebUI_GZ::LOGIN_PAGE_GZ (+1 B, the version string of #300), and only .rodata changes. The three Pico W images that grow 104 B where main's grow 112 B (pico_w_release, pico_w_test, pico_w_asserts) are the same two symbols: .rodata = the symbols (+110 B) + the bytes no symbol covers (-6 B here, +2 B on main's tree), counted per ELF (pico_w_release 414,288 -> 414,392 = +110 - 6; main's 414,296 -> 414,408 = +110 + 2; pico2_w_release +113 - 1 here, +111 + 1 on main's): the alignment of the entries behind the page blobs, not a symbol. pico_w_alpha and pico_w_air carry the page too (the same two symbols grow, +109 and +1 B, and no section changes size: the bytes no symbol covers give back what they take) and pico_w_test_https has no Files page (LOGIN_PAGE_GZ +1 B, no section changes size): the three keep their size with another sha256, as main's do. The savings floors (tools/measure_savings.py --check, SIMUT_SAVINGS_PIO = the shim's pio): 15 of 16 hold. Measured - floor in flash: 0 for twelve, web_history -6 (inside FLASH_TOL), tel_mqtt +2, syslog +3; RAM +0 for all. tft_graph saves 20,365 B against its floor of 20,433 B: 68 B below, 60 past the tolerance. It is not this merge: the same tool on main's tree (cf97b95) gives 20,433 B (main's floor, to the byte), and on 22d83de, before the merge, 20,365 B (stages/sync8/tg_*.txt). It is the branch's UI-as-driver code in the release images: what the switch takes out of DisplayManager::handleTouch( ) is 1,804 B here against 1,832 B on main and out of DisplayManager::loopCore1( ) 436 B against 484 B (-28, -48), and a few compiler switch tables differ (CSWTCH.*, 116 B on main's side). feature_savings.json is NOT updated here: the floor is main's number and the nightly runs on main; the --update, with this explanation, belongs to the merge that takes the branch into main. A first run of the floors let PlatformIO's library installer start a git clone of one of the project's own libraries for a temporary environment (network, which this step does not allow): it was interrupted (SIGINT; TempEnvs put profiles.ini back, tools/generated unchanged) and the run was repeated with GIT_ALLOW_PROTOCOL=file and the proxies on a closed port. The figures above are from the repeat. Proofs (host only; records in stages/sync8) - check_flash_budget.py <env> <log> right after each build: eight over their budgets by 104..112 B before budget_set.py (pico_w_alpha, pico_w_air and pico_w_test_https at 0), exit 0 for all eleven after it (run on the saved images: the floors had rewritten .pio/build by then); --table OK (11 images, 1 exempt); test_flash_budget.py 24 ok; gen_features.py --check; check_readme_numbers.py (772 cases in 11 suites, unchanged: main adds no native case); git diff --check; no conflict marker anywhere. pico_w_test is 3,267 B and pico_w_asserts 1,779 B under the OTA ceiling (the gate's WARN: under one sector, as before). - tools/test_webui_upload_result.py PASS and tools/test_webui_theme_names.py PASS with the union in both packs. V-PIX: 951 of 951 frames equal to the records, six contact sheets and base en/es equal, its control bites. tsv_check.py: 394 rows, 0 findings. tools/tft_ui tests: 8 files, 0 fail. check_lang_packs.py, check_ui_texts.py (0 findings): clean. - ci_gates_local.py --raso (the shim first in PATH, a depth-1 clone with the working tree laid over it): 68 of 69 steps passed; 1 skipped (the AddressSanitizer/UBSan host suites: they need PLATFORMIO_BUILD_FLAGS, CI only); the one failure is the fuzz step (clang++ cannot load libclang-cpp.so.18.1 on this host, as in the sync 6 and 7 records). The eleven native suites: 366 + 62 + 34 + 14 + 59 + 54 + 17 + 13 + 51 + 19 + 83 = 772 cases, all succeeded. The host proofs above (V-PIX, tsv_check, the tft_ui tests, the packs, check_ui_texts, the authorization matrix) ran on the tree before budget_set.py rewrote PLANO_STABLE section 3.1, flash_budget.json and two comment lines of features.toml, files none of them reads. The review re-ran tsv_check (394 rows, 0 findings), check_ui_texts, check_lang_packs, the two web tests, check_readme_numbers (772 cases), test_flash_budget (24 ok), check_flash_budget.py --table and gen_features.py --check on the committed tree: all pass. Floor run: tft_graph saves 20,365 B here against main's floor of 20,433 B; the tree before the merge (22d83de) gives the same 20,365 B and main's tree 20,433 B. That is the branch's UI-as-driver code in six DisplayManager symbols, not the merge. It is left for the branch's merge into main; feature_savings.json is main's, unchanged. Not verified on hardware. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu
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.
chore: v2.12.0
The release chore for v2.12.0, cut from
main96a5af0 (the merge of #299). Host only: nothing ran on a board, and nothing here is signed, tagged or published. The gate on both boards follows this change, and "The bench" section of both CHANGELOGs is a placeholder that the gate's documentation change fills in (said so in the entry itself).Decisions of the maintainer (2026-10-28)
security_versionstays 1 (series 1):git diff v2.11.1 HEAD -- keys src/ota/ota_layout.his empty.CONFIG_VERSIONstays 26. Both are in the entry's header.Commits (one proof each)
3df4dce0chore: SIMUT_VERSION 2.12.0, the only source line.f983f082docs: the v2.12.0 changelog, in English and in Portuguese.7a679374docs: v2.12.0 in the READMEs, the manual and the site.3025339ddocs: the review's fixes (the changelog's gaps and a measured claim made honest); no file undersrc/.The 35 pull requests since v2.11.1, and the section each one is in
The section of each PR was chosen by hand, and the script that builds this table checks that the PR's number is named in that section of both entries (the check scripts are kept in the release scratchpad, outside the repository); it fails if one of the 35 is missing from either entry.
lanswitch for the SIMUT Wire, its CI image, and a PIO and pin budgetCoverage: 35 of 35 in both languages. Both entries have 19
###sections in the same order, and the digit runs of the two entries are identical once the locale's separators are removed.Known and Upgrading, item by item
The six items the maintainer listed are in (a refused file followed by an accepted one in the same upload; the four panel events without Core 0's check;
data/themes/*.thmagainsttools/gen_theme_collection.py; the es-ES proposals; the emergency console withoutlanguage; the theme select that ignores the answer of/api/save_sys).build_custom.pyhands out the trial-flagged.binand the factory.uf2; the README already says "for the Pico 2 W too"git diff --stat v2.11.1 origin/main -- src)src/andWebUI.hmatchheartbeat?LatinorUTF-8are #294's Idioma screen503in theWebUI.hdiff is a comment of #299configure terminalneeds noenablesensor_wipedo not restart the historygit grep provisionEpoch origin/main -- src: writers only, no reader% 5"Kept" rests on a changed-lines search of
src/andWebUI.h, which says the code the v2.11.1 entry read has not moved; none was exercised again. The v2.11.1 bullet "simut-rx does not knowreleasetwo" stays: its pull request #14 is still open and its latest release is 1.9.1 (gh, read only, 2026-10-28).Measured on this tree (2026-10-28, host only)
git diff --stat origin/main -- src WebUI.h data keys platformio.ini 'tools/*.py'showssrc/SystemDefs_Limits.h | 2 +-.rm -rf .pio/build/<env>, with the pio shim under the shared lock,check_flash_budget.py <env> <log>right after each build; every one exits 0; the flash used of all nine equals its record intools/flash_budget.json("0 B under budget") and the eight.binthat have a record equal it (pico_w_test_httpshas none: it is exempt from the OTA ceiling). The version string has the same length and the login page's gzip did not move, soflash_budget.jsonand PLANO_STABLE section 3.1 are untouched.--tableandtest_flash_budget.pypass. "2.12.0" is in the four published images and "2.11.1" is not (grep -c -a).pico_w_releasepico_w_alphapico_w_airpico2_w_releasepico_w_testpico_w_test_httpspico_w_assertspico_wirepico_wiretftbancada_20261028_rel2120/old/, signed.bin): release 1,033,357 to 1,036,133 B (+2,776); alpha 990,621 to 990,621; Air 1,031,485 to 1,035,581 (+4,096); Pico 2 W 997,417 to 1,000,241 (+2,824).check_readme_numbers.pypasses). Under AddressSanitizer and UBSan (the gates job's last step): all eleven suites exit 0 (finished 21:33:23 on 2026-10-28).tools/check_authz.pyreports 62 routes, 52 gated and 10 public by design, with the four panel-event warnings the Known list names..github/workflows/build.yml,pip installandpio teststeps left out): 39 steps, 0 failed, among themscan_secrets.sh,check_angulo.py,check_readme_numbers.py,check_flash_budget.py --table,gen_logcodes.py --check,check_authz.py.python3 tools/build_manual.py --checkpasses.check_changelog.py, in the release scratchpad) with three negative controls, each giving exactly one finding (a PR number removed, a###removed, an Unreleased heading put back).Deviations and things to decide
docs/MANUAL.pt-BR.html) was not regenerated whole: with pandoc 3.7.0.2 the generator no longer writesclass="header|odd|even"on table rows, and a plain regeneration rewrites ~3,081 lines. As in Web: theme names in the device's language (the device sends English and a code; the page translates) #298 and Web: the Files page no longer says "Upload complete." for an upload the device refused (F5) #299, the diff is the substance only (56 insertions, 30 deletions). Checked: the committed file with its row classes stripped equals the generator's output for the old sources; the committed file equals that output with the classes put back by position (thead rowsheader, tbody rowsodd/even), so the new file is the new output with the same rule; and the committed file after the change equals the regeneration from the final sources (cmp).## v2.12.0 (2026-10-28), the format of the previous entries (## v2.11.1 (2026-10-12)). The date is the chore's; the READMEs, the manual and the site carry the same date. If publication is on another day, the gate's documentation change sets it./api/statusclk_peri,tft_hz).pico_w_testhas 3,427 B of OTA room today (check_flash_budget.pyand PLANO_STABLE section 3.1 agree). The fix(panel): after a boot in English the Idioma screen lists the pack in /lang again, so the language has a way back #294 bullet that said "139 B of OTA headroom left of 763" now says that was that day's room and that pico_w_test: serve the licence page from LittleFS, for 3,699 B of room under the OTA ceiling #297 gave it back.check_flash_budget.pywarns (the Air has 4,803 B). The next addition to either is a decision, not a surprise.docs/index.html(the new release article) is a proposal awaiting a native review, like the theme names andfil_up_refused.pico_w_releaselog shows 318 compile steps; there is no ccache here andplatformio.inisets no build cache. The sizes equal the records that CI's builds produced.Review
A revisor reviewed the three first commits (COM RESSALVAS, no blocker): it rebuilt
pico_w_releasefrom scratch byte for byte (sha256 dd41318a…, signed 1,036,133 B, 4,251 B under the OTA ceiling,stringsshows 2.12.0 and no 2.11.1), ran the eleven native suites (734), checked 35 of 35 merges in both entries and every Known item against the code. Its findings (two changelog gaps: #262's top-panel fix and #272'smetr.cgw/short_writeseries; "set to" for the 66.5 MHz the release image never measured; the Upgrading note on English until the packs return; an hour-skewed pair of numbers on the site; Portuguese agreement) are fixed in3025339d.Not done here
The jobs of CI (this PR runs them), the signed candidate, both gates on hardware, and the gate's documentation PR, which fills "The bench" and moves the entry's date to the publication day (the gate takes hours: the publication will not be on 2026-10-28).
🤖 Generated with Claude Code
https://claude.ai/code/session_01Uy7K2mzEmmjBnpxpdYNDFu