Skip to content

Commit e563713

Browse files
authored
[docs] Publish hardware-tested firmware v0.4.2 beta (#6)
Preserve the exact tested v0.4.2 release lineage and publish its scoped production-browser attestation. Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
2 parents 98c8722 + 2863c94 commit e563713

48 files changed

Lines changed: 2331 additions & 630 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,18 @@ are released independently from this monorepo.
88
- Established `PyBLE-dev/PyBLE` as the canonical public monorepo.
99
- Added public contributor, security, architecture, protocol, and validation
1010
documentation.
11-
- Selected firmware agent `0.4.2` for fresh reproducible builds and
12-
two-profile qualification from the canonical public history.
11+
12+
## Firmware 0.4.2 — 2026-07-31
13+
14+
- Published the exact hardware-tested beta for `esp32-4mb` and
15+
`esp32-s3-n16r8`; ESP32-C3 remains unavailable.
16+
- Validated production Chrome installation, deliberate interruption,
17+
interrupted-flash recovery, and reset on real hardware for both exact
18+
profiles.
19+
- Bound the public release to its annotated source tag, immutable metadata,
20+
binary hashes, and post-release production-browser attestation.
21+
- The complete release qualification remains pending across the app, PBLE/1,
22+
resource, and remaining firmware matrices.
1323

1424
## App 0.1.0-beta — 2026-07-30
1525

README.md

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,21 @@ BLE GATT peripheral. It supports:
6262
- board naming and identify support; and
6363
- upstream MicroPython’s standard `neopixel` module.
6464

65-
The public browser installer is currently unavailable pending v0.4.2 HIL on
66-
both exact current profiles:
67-
68-
| Installer profile | Exact target constraint | Public status |
69-
| ----------------- | ------------------------------------------------------------ | --------------------------------------------------- |
70-
| `esp32-4mb` | Classic ESP32, 4 MiB external SPI flash; no PSRAM assumed | v0.4.2 HIL pending; installer unavailable |
71-
| `esp32-s3-n16r8` | ESP32-S3, 16 MiB flash / 8 MiB Octal PSRAM; N16R8-class only | v0.4.2 HIL pending; installer unavailable |
72-
| `esp32-c3-4mb` | ESP32-C3, 4 MiB external SPI flash; no PSRAM assumed | Planned; no public image; exact-profile HIL pending |
65+
The public browser installer currently offers the exact v0.4.2 hardware-tested
66+
beta for both current profiles. Production Chrome erase/install and deliberately
67+
interrupted-flash recovery passed on real hardware for both exact profiles.
68+
Complete release qualification continues across the app, PBLE/1, resource, and
69+
remaining firmware matrices:
70+
71+
| Installer profile | Exact target constraint | Public status |
72+
| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
73+
| `esp32-4mb` | Classic ESP32, 4 MiB external SPI flash; no PSRAM assumed | v0.4.2 hardware-tested beta; browser install/recovery passed |
74+
| `esp32-s3-n16r8` | ESP32-S3, 16 MiB flash / 8 MiB Octal PSRAM; N16R8-class only | v0.4.2 hardware-tested beta; browser install/recovery passed |
75+
| `esp32-c3-4mb` | ESP32-C3, 4 MiB external SPI flash; no PSRAM assumed | Planned; unavailable; no public image |
76+
77+
See the
78+
[post-release production-browser attestation](docs/validation/browser-flashing/v0.4.2-production.md)
79+
for the exact hashes, completed checks, and deliberately bounded claim.
7380

7481
These are the initial port targets, not a chip-family allowlist. A future board
7582
is compatible when it has a maintained PyBLE agent port, BLE GATT
@@ -106,12 +113,14 @@ shared conformance corpus, documentation, and CI atomically.
106113
1. Install the iPad beta from
107114
[TestFlight](https://testflight.apple.com/join/yU4e8s6d), or build the
108115
Flutter app locally.
109-
2. Check [pyble.dev/flash](https://pyble.dev/flash) in desktop Chrome or Edge.
110-
The public installer is currently unavailable pending v0.4.2 HIL. Wait for
111-
that page to show an active release version, your exact profile, and an
112-
enabled install action.
113-
3. Only after that gate opens, back up the board, confirm its exact memory
114-
profile, and use the one-time wired installer. Flashing erases the board.
116+
2. Open [pyble.dev/flash](https://pyble.dev/flash) in desktop Chrome or Edge.
117+
The exact v0.4.2 hardware-tested beta is active. Browser installation and
118+
interrupted-flash recovery passed on both exact profiles; complete release
119+
qualification continues. Confirm the active version, your exact profile,
120+
and the enabled install action.
121+
3. Before flashing, back up the board, confirm its exact memory profile, and
122+
accept every safety acknowledgement before using the one-time wired
123+
installer. Flashing erases the board.
115124
4. Open PyBLE, scan for the provisioned board, connect, and run an example over
116125
BLE.
117126

docs/ROADMAP.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ promising dates; accepted work is tracked through GitHub issues and milestones.
88
- iPad external beta through TestFlight
99
- PBLE/1 editing, run/stop, console, and file workflows over BLE
1010
- Offline Blockly with beginner GPIO and NeoPixel examples
11-
- Browser installation for qualified `esp32-4mb` and `esp32-s3-n16r8`
12-
profiles
11+
- Browser installation for the exact `esp32-4mb` and `esp32-s3-n16r8` profiles
12+
as the v0.4.2 hardware-tested beta; production Chrome install/recovery passed
13+
on both profiles
1314
- MIT-licensed app, agent firmware, protocol, website, tests, and release tools
1415

1516
## Near term
1617

17-
- Re-establish firmware release provenance from the canonical public history
18+
- Complete the app, PBLE/1, resource, and remaining firmware release
19+
qualification for the exact v0.4.2 bytes
1820
- Complete real-hardware qualification before enabling the ESP32-C3 installer
1921
- Expand user-facing setup, recovery, and board-specific wiring guidance
2022
- Open and document the Android beta distribution path

docs/specifications/firmware.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# PyBLE — Agent Firmware
22

3-
Status: **DRAFT** · Last updated: 2026-07-30
3+
Status: **DRAFT** · Last updated: 2026-08-01
44

55
The PyBLE agent is small board-side firmware that turns a compatible
66
MicroPython target into a PyBLE-speaking board: it advertises the BLE service,
@@ -67,14 +67,15 @@ confined to Layer 2 (board overlay: pins, flash size, USB), and the shared agent
6767
core contains no per-chip product logic.
6868

6969
The browser installer does not publish unqualified family-wide images. The
70-
v0.4.2 candidate set is `esp32-4mb` (classic ESP32, 4 MiB flash) and
71-
`esp32-s3-n16r8` (ESP32-S3, 16 MiB flash plus 8 MiB Octal PSRAM), but the
72-
public browser installer remains unavailable pending final HIL on the exact
73-
candidate bytes for both profiles. `esp32-c3-4mb` remains a known initial v1
74-
profile but is not released or selectable until exact-profile real-hardware
75-
validation is complete. ESP Web Tools detects the chip family but cannot by
76-
that fact alone prove the required flash/PSRAM topology. The full compatibility
77-
and artifact contract is frozen in
70+
exact v0.4.2 bundle is offered as a hardware-tested beta for `esp32-4mb`
71+
(classic ESP32, 4 MiB flash) and `esp32-s3-n16r8` (ESP32-S3, 16 MiB flash plus
72+
8 MiB Octal PSRAM). On both exact profiles, browser installation and interrupted-flash recovery passed;
73+
complete release qualification remains pending.
74+
`esp32-c3-4mb` remains a known initial v1 profile but is unavailable
75+
and has no public image until exact-profile real-hardware validation is
76+
complete. ESP Web Tools detects the chip family but cannot by that fact alone
77+
prove the required flash/PSRAM topology. The full compatibility, artifact, and
78+
bounded public-beta contracts are frozen in
7879
[firmware/browser-flashing.md](firmware/browser-flashing.md).
7980

8081
These targets are the initial reference/build family, not the product boundary.
@@ -118,13 +119,13 @@ MUST NOT require a known-chip allowlist.
118119
The measurement method is frozen in
119120
[firmware/specs.md §5.3](firmware/specs.md#53-footprint-gates-nfr-fp);
120121
numeric values remain provisional until derived from retained baseline samples.
121-
The v0.4.2 candidate qualification scope is profile-scoped:
122+
The current v0.4.2 qualification work remains profile-scoped:
122123

123124
| Profile | Current numeric status | Release effect |
124125
|---|---|---|
125-
| `esp32-4mb` | Measure, derive, freeze, and verify on the owned exact profile | Required before v0.4.2 candidate qualification and installer activation |
126-
| `esp32-s3-n16r8` | Measure, derive, freeze, and verify on the owned exact N16R8 profile | Required before v0.4.2 candidate qualification and installer activation |
127-
| `esp32-c3-4mb` | Deferred; no current threshold or HIL row | Blocks C3 enablement and v1.0, but not qualification of the two-profile candidate |
126+
| `esp32-4mb` | Browser install/recovery passed; numeric/resource qualification pending | Enabled only by the exact v0.4.2 public-beta exception; required for qualification |
127+
| `esp32-s3-n16r8` | Browser install/recovery passed; numeric/resource qualification pending | Enabled only by the exact v0.4.2 public-beta exception; required for qualification |
128+
| `esp32-c3-4mb` | Deferred; no current threshold or HIL row | Blocks C3 enablement and v1.0; absent from the v0.4.2 beta |
128129

129130
The enforced metrics are:
130131

docs/specifications/firmware/TDD.md

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,10 @@ Download (`FILE_GET_*`) is the symmetric streamer: `FILE_GET_BEGIN{path,offset}`
528528

529529
Static, boot-time allocation of all large buffers (D3) makes resource
530530
headroom repeatable enough to measure after HELLO and after transfer workloads.
531-
The current pre-v1 release measures the owned exact profiles
532-
`esp32-4mb` and `esp32-s3-n16r8`. The S3's PSRAM is useful Python headroom but
531+
The current v0.4.2 public-beta qualification work measures the owned exact
532+
profiles `esp32-4mb` and `esp32-s3-n16r8`. Its supplemental production-browser
533+
rows passed, while its formal resource and remaining HIL rows stay open. The
534+
S3's PSRAM is useful Python headroom but
533535
MUST NOT conceal internal-RAM pressure, so the gate records Python GC memory
534536
and internal ESP-IDF heap separately. The design still targets the
535537
**ESP32-C3 floor** for v1.0 (single-core RISC-V, ~400 KB SRAM
@@ -720,10 +722,12 @@ pipeline while retaining the shared PBLE/1 conformance gates.
720722
generate THIRD_PARTY_LICENSES.txt mechanically BLD-8/14
721723
11. run no-leak, SPDX, manifest/integrity/license/reproducibility gates CON-6,
722724
BLD-14/18
723-
12. publish identical immutable bytes to the versioned same-origin path
724-
and matching GitHub Release only after every included profile passes HIL;
725-
the current pre-v1 gate covers esp32-4mb and esp32-s3-n16r8, while C3 is
726-
unavailable until a later candidate BLD-7/21/22
725+
12. publish identical immutable bytes to the versioned same-origin path and
726+
matching GitHub Release only after every included profile passes HIL;
727+
alternatively, the exact digest-bound v0.4.2 exception may publish the two
728+
profiles as a hardware-tested beta and GitHub pre-release after both pass
729+
the scoped production-browser install/recovery run; C3 stays unavailable
730+
BLD-7/21/22
727731
```
728732

729733
### 10.2 Entry points
@@ -774,8 +778,8 @@ exact public tree, manifest, separate integrity/provenance metadata, recovery,
774778
HIL report, activation, and rollback are frozen in
775779
[browser-flashing.md](browser-flashing.md). Identical immutable bytes publish
776780
both at the versioned `pyble.dev` path and through the matching GitHub Release,
777-
with exact release-profile parity: two qualified profiles in the current
778-
pre-v1 release and all three at v1.0 (BLD-7/1722). `DEVICE_INFO`/HELLO,
781+
with exact release-profile parity: two hardware-tested beta profiles in v0.4.2
782+
and all three qualified profiles at v1.0 (BLD-7/1722). `DEVICE_INFO`/HELLO,
779783
`manifest.json`/`release.json`, tag, and release notes make agent/protocol/
780784
upstream/source/artifact versions recoverable (BLD-13); the agent follows
781785
SemVer (BLD-12).
@@ -1077,7 +1081,7 @@ Chip facts are owned by [hardware.md §1](../hardware.md#1-supported-chip-famili
10771081
frozen-Python does not fit, hot paths go native (D1,
10781082
8.6](#86-esp32-c3-mitigation)). The known `esp32-c3-4mb` provisioning
10791083
profile is defined only for C3 silicon revision v0.3 or newer but remains
1080-
unavailable in the current pre-v1 release pending exact-profile HIL. Its
1084+
unavailable in the current v0.4.2 public beta pending exact-profile HIL. Its
10811085
exact image revision window appears in release metadata only after a later
10821086
candidate qualifies it.
10831087

@@ -1155,22 +1159,27 @@ PBLE/1 **conformance** tests run against an **in-memory fake transport** shared
11551159
toolchain-distribution license bytes from the trusted ESP-IDF download cache,
11561160
exact metadata/cache/install binding with distinct archive and version roots,
11571161
absence of host-absolute paths in receipts, and profile-specific zero-input
1158-
not-shipped proof.
1162+
not-shipped proof. Supplemental source-tree digests exclude Python bytecode
1163+
cache artifacts while the audit rejects any such artifacts in the retained
1164+
checkout; release builds force bytecode generation off so checkout-local
1165+
absolute paths cannot contaminate otherwise identical source evidence.
11591166
- **size:** enforce the total application-image ceiling and derived
11601167
factory-partition headroom floor during build/candidate validation. Continue
11611168
structural application-fit checks on all three source targets, including
11621169
deferred C3. Heap, boot, goodput, and reliability are not mislabeled as
11631170
static size gates.
11641171
- **HIL:** the release-blocking bench runs on every exact profile included in
1165-
the release. For the current pre-v1 candidate that is exactly
1172+
the release. For the v0.4.2 formal candidate matrix that is exactly
11661173
`esp32-4mb` and `esp32-s3-n16r8`; it covers the frozen §8.5 resource
11671174
workload, multi-file integrity (NFR-REL-5), STOP authority (NFR-SAFE-1),
11681175
cold-boot safety (NFR-SAFE-3), candidate-browser install, and
11691176
interrupted-flash recovery from an access-controlled,
11701177
production-equivalent HTTPS deployment (BLD-20/21). C3 HIL and
11711178
footprint/goodput gates remain open, block C3 enablement, and block v1.0.
1172-
Public activation then needs only the non-destructive origin/integrity smoke
1173-
defined by BLD-22.
1179+
The later supplemental production-browser run completed only the browser
1180+
install and interrupted-recovery rows for both profiles. The other formal
1181+
rows remain open; the exact public-beta activation follows the bounded
1182+
exception in browser-flashing §10 rather than claiming BLD-21 completion.
11741183

11751184
### 14.4 Required red matrix for pre-v1 qualification
11761185

@@ -1240,12 +1249,12 @@ Design element → satisfied requirement IDs. Each `FR-*` block has at least one
12401249
- **R2 — Frozen→native trigger point.** Which paths move to C, and on which chip the budget forces it, is undecided until HIL measurement (OI-3). The module boundaries ([§4](#4-module-design)) are drawn to make the move contract-neutral (NFR-MAINT-3).
12411250
- **R3 — iOS/Android BLE MTU quirks.** Central platforms negotiate MTU differently and may not grant 247; the firmware must operate correctly across the negotiated MTU down to the default (FR-BLE-8). Fragmentation/reassembly is tested across an MTU matrix ([§14.1](#141-per-module-verification-approach)).
12421251
- **R4 — Single-core C3 STOP latency.** With one core the runner and BLE/agent task time-share; STOP must still land promptly against a tight loop ([§5.2](#52-stop-delivery)). Validate on C3 HIL first ([§11](#11-per-chip-design-notes)).
1243-
- **R5 — Candidate pins not yet selected or HIL-approved.** `versions.lock`
1244-
values (MicroPython v1.28.0 / ESP-IDF v5.5.1) remain proposed defaults until
1245-
selected as candidate-frozen inputs before the release builds and HIL
1246-
(OI-2). Candidate-freezing makes the input immutable; it does not approve
1247-
C3 compatibility or public release. A pin change creates a new candidate and
1248-
reruns all build, audit, deployment, and exact-profile HIL gates through
1252+
- **R5 — v0.4.2 candidate pins are selected but not fully HIL-approved.** The
1253+
exact `versions.lock` values (MicroPython v1.28.0 / ESP-IDF v5.5.1) are
1254+
candidate-frozen for v0.4.2 (OI-2). Candidate-freezing makes the input
1255+
immutable; it does not approve the remaining formal matrix, C3 compatibility,
1256+
or a qualified release. A pin change creates a new candidate and reruns all
1257+
build, audit, deployment, and exact-profile HIL gates through
12491258
`upgrade_micropython.sh` (BLD-9/19/21).
12501259
- **R6 — PBLE/1 still DRAFT.** Opcode/UUID/status numbers are provisional until [protocol.md](../protocol.md) §2/§4 freeze (OI-4); the single constants mirror (D6) localizes the churn.
12511260
- **R7 — Auto-run caps flag naming.** The opt-in `main.py` auto-run flag name/encoding is owned by [protocol.md §7](../protocol.md#7-hello--capabilities) and must be fixed before F-12 (OI-5).

0 commit comments

Comments
 (0)