Skip to content

Add exact Waveshare S3 updater target - #70

Closed
theysayheygreg wants to merge 4 commits into
SteveEisner:mainfrom
theysayheygreg:agent/p2p-updater-targets-clean
Closed

Add exact Waveshare S3 updater target#70
theysayheygreg wants to merge 4 commits into
SteveEisner:mainfrom
theysayheygreg:agent/p2p-updater-targets-clean

Conversation

@theysayheygreg

@theysayheygreg theysayheygreg commented Aug 16, 2026

Copy link
Copy Markdown

Idea

Add a fail-closed, exact-target updater contract for the Waveshare ESP32-S3-Touch-AMOLED-2.16 device, with byte-pinned USB merged and OTA application artifacts.

Three-commit map

  1. 8b015680 — updater foundations and bounded admission.
  2. 02abdd5d — exact Athom C3 target.
  3. 6a1299e5 — exact Waveshare S3 target-only contract, generated projections, migration fixture, PlatformIO environment, tests, and clean artifacts.

Scope and independence

This PR is intentionally S3 target-only. Home, Conductor, Surveyor, touch/display product development remains independent and is not coupled or superseded by this updater target contract. No product UI files or platformio.ini changes are included.

Verification

  • npm ci && npm run build && npm test — pass (31 tests)
  • node tools/update-contract/validate.mjs — pass
  • node tools/update-contract/generate.mjs --check — pass
  • pio run -e waveshare_s3_tubes_target — pass
  • pio run -e esp32-c3-athom_tubes — pass
  • pio run -e esp32_quinled_dig2go_tubes — pass
  • git diff --check — pass
  • clean build artifact bytes and hashes pinned in the contract

Limitations

No Easy Flash push/deploy, physical device flash, network, Vercel, or DNS actions were performed.

Follow-up fix

Commit a17370b8 makes the S3 OTA artifact byte-identical to the application embedded in the pinned merged USB image. The contract now requires full commit SHAs, matching compiled release identity, and an exact merged/OTA application pair for each build; the migration fixture, generated projections, and documentation were updated from that single byte source.

The PlatformIO configuration test now uses the repository's composed project configuration and skips only when PlatformIO is not installed. Validation passes with PlatformIO present and absent.

Additional verification:

  • npm test — pass (31 passed, one optional PlatformIO test skipped)
  • PlatformIO-enabled update-contract suite — pass (14/14)
  • Tubes mesh host tests — pass
  • Tubes upgrade workflow tests — pass
  • esp32dev, esp32_quinled_dig2go_tubes, esp32-c3-athom_tubes, and waveshare_s3_tubes_target firmware builds — pass
  • generated projection checks and git diff --check — pass

@SteveEisner SteveEisner left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Reviewed the corrected S3 artifact, provenance metadata, validation rules, and regression coverage. USB and OTA now install one verified application image, and the contract rejects future drift between the two delivery paths.

"path": "contracts/update/artifacts/waveshare-s3-v14/ota/firmware.bin",
"buildOffset": 65536,
"lengthBytes": 1219728,
"sha256": "247c26185d61d75e372dc3cf91299f82f2749f85c5a4857ffbc2818a08d94ba2"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This corrects the critical S3 artifact mismatch: the OTA file now has the same 1,219,728-byte application payload and SHA-256 as the application embedded at offset 65,536 in the merged USB image. Choosing USB or OTA will therefore install the same firmware build.

"tubesRelease": "14",
"wledBaseVersion": "16.0.1",
"releaseIdentity": "WAVESHARE_S3_TUBES_TARGET",
"buildCommit": "02abdd5d53aeabbcb8eed1bc36b29a1c340afa44",

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Recording the full 40-character build commit makes this artifact traceable to one exact source revision instead of an abbreviated prefix. That matters when validating or reproducing firmware months later, when a short identifier could be ambiguous or accepted accidentally.

&& artifactsShareBuild(merged, item));
fail(errors, !!ota, `${merged.id} is missing matching OTA application`);
if (ota) fail(errors,
application.lengthBytes === ota.lengthBytes && application.sha256 === ota.sha256,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This is the durable protection against the original failure: every merged USB image must have a matching OTA artifact for the same target, release, identity, commit, and source state, and their application size and hash must agree. A future build can no longer publish two different firmwares as interchangeable delivery formats.


// A merged image and its OTA artifact represent one build, so their application
// bytes must remain identical even when both individual files are internally valid.
test('merged and OTA artifacts from one build share exact application bytes', () => {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This regression test independently proves both failure modes that matter: validation rejects an OTA image whose hash differs from the USB application, and it rejects a USB build with no corresponding OTA artifact. It keeps the cross-artifact guarantee covered even when each individual file is internally valid.

@theysayheygreg

Copy link
Copy Markdown
Author

We’re parking this multi-target updater-contract experiment. Physical S3 work converged on a much smaller device-only target, which will be proposed separately as one focused commit. This PR is being closed rather than rewritten so its updater/C3/migration review history remains accurate.

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.

2 participants