Files
ESP32_Serial_Swiss_Army_Knife/docs/dependency_licenses.md
T
Commander1024 797d2681ac Migrate to IDF 5.5.3 candidate
Pin PlatformIO packages and toolchains, rebase protected SDK
overrides, and add WebSocket receive regression coverage. Document
isolated candidate validation, archive provenance, and remaining gates.
2026-09-18 14:23:13 +02:00

31 KiB
Raw Blame History

Dependency license inventory — Phase 9D

Implementation addendum — updated 2026-09-18

Missing generated modification/date notices: resolved; current count is nine C sources plus one header. tools/security_overrides.py prepends the baseline project modification notice dated 2026-09-15, identifying the editable generator and warning against editing derived copies. The wolfSSH internal.c, added ssh.c and generated wolfssh/internal.h also receive a prominent 2026-09-16 ordering-profile/provenance notice. Exact original hashes and exact-once edits remain required; upstream notices are retained. The header is a PUBLIC forced build input, not a C source. Both new mbedTLS copies retain their original Mbed TLS Contributors copyright and Apache-2.0 OR GPL-2.0-or-later SPDX header; the Apache-2.0 selection in this inventory is unchanged. This resolves the narrow notice-generation finding, not release packaging or license clearance.

Offline notice assembly tooling is implemented; actual firmware/device/browser delivery, radio-blob corresponding-source/exception questions, preferred-source packaging, wolfSSH license-package discrepancy, manual bitmap/mockup provenance limits and release-specific runtime/bootloader review remain open; exact retained SVG provenance is resolved. Offline notice assembly is implemented by tools/release_notices.py: 75 mandatory hash/size-pinned inputs (nine IDF/toolchain notice entries semantically rebased for the candidate; the other 66 unchanged), deterministic bounded outputs, fail-closed preflight and no overwrite/fetch/build/device access. Supplied agent evidence: 36 notice fixture tests PASS; two actual bundles verified deterministic, each 77 files / 4,433,930 bytes. This includes retained SVGs and exact icon provenance, not corresponding-source delivery or legal clearance. These are agent measurements, not a parent rebuild or reassembly in this documentation turn. Include cmake/wolf_crypto_policy.{cmake,h} and the ordering inputs described below with the reproducible build/source package. The IDF 5.5.3 migration is now integrated in the isolated validated candidate; this documentation update performs no upgrade, asset regeneration or device operation. Root pins select platform 6.13.0 / framework 3.50503.0 / both toolchains 14.2.0+20251107; see integration and build/closure limits. The detailed 5.5.0 SDK/runtime inventory below remains historical, not a newly exhaustive 5.5.3 license audit.

Historical inventory baseline — 2026-09-15

The original audit scope and artifact counts below describe the audit-time snapshot; generated-source status and the release checklist are updated explicitly where noted. Original research evidence is retained, not a claim that all artifacts were rebuilt or re-audited here.

Local, bounded audit: 2026-09-15. This is an engineering inventory and release checklist, not legal advice, a legal compatibility opinion, an upstream currency check, or exhaustive file-by-file coverage. No network requests, dependency changes, asset regeneration, firmware build, tests, or device operations were performed. Hardware validation remains deferred for Phase 9 as a whole.

Evidence and counting boundaries

  • Project license: root LICENSE, README license declaration, and representative src/ SPDX headers establish GPL-3.0-only, not “or later.” Dependencies keep their own notices and grants.
  • Resolution: application manifest, dependencies.lock, platformio.ini, all six installed managed manifests and top-level license files.
  • 7 lock entries = 6 managed packages + IDF. Managed packages comprise 5 direct + 1 transitive. IDF is also a direct requirement. wolfSSH uses wolfSSL in this integration, although its resolved manifest declares no dependency edge; both are explicitly pinned by the application.
  • Platform: platformio/espressif32@6.12.0; installed SDK package framework-espidf 3.50500.0, SDK 5.5.0, compiler package toolchain-xtensa-esp-elf 14.2.0+20241119. Installed package metadata, not merely requested ranges, was checked.
  • Existing .pio/build/esp32-s3-devkitc-1-n16r8/project_description.json names 113 nonempty configured components. Its adjacent esp32_serial_swiss_army_knife.map has 68 distinct archive basenames in the initial “Archive member included” region, before “Discarded input sections.” These are build-selection evidence, not 113 independently audited packages or proof all selected bytes survive section garbage collection. These pre-existing artifacts were not rebuilt or certified fresh.
  • Below: 6 managed rows, 18 SDK/runtime inventory groups, 2 browser packages, and 1 icon collection containing 2 SVGs. Groups are not a complete SBOM and must not be summed into a unique package count (e.g. bundled libraries are inside IDF).
  • Web provenance: all 8 recorded SHA-256 values matched (3 JS/CSS, 2 license files, 3 gzip artifacts). Two SVG IDs and the attribution in src/local_status_ui.c:158161 were inspected for provenance only. Logo ownership is the project's recorded claim, not independently established authorship.
  • Initial Git status was clean. An unrelated untracked docs/security_operations.md appeared during this audit and was left unread and untouched. This audit creates only this file.

Local path notation

Repository paths below are relative to the repository root. Installed paths are expressed using these audit-time roots, not environment variables that must already be set:

  • SDK/ = /home/mscholz/.platformio/packages/framework-espidf/
  • TC/ = /home/mscholz/.platformio/packages/toolchain-xtensa-esp-elf/
  • BUILD/ = .pio/build/esp32-s3-devkitc-1-n16r8/

SDK/package.json identifies https://github.com/espressif/esp-idf; SDK/version.txt says 5.5.0. SDK/LICENSE is Apache-2.0. There is no SDK/COPYRIGHT in this installed package, and its README.md contains no license/copyright section. Do not assume the root Apache text covers every bundled library or is a complete attribution list. Component license files and source notice headers supply important exceptions.

Managed components: complete lock-level inventory

All rows have a checked managed_components/<directory>/idf_component.yml. Versions below match the lock and installed manifests. Exact component hashes remain in dependencies.lock; a manifest-only assertion is not a cryptographic revalidation of all installed package contents.

Package / resolved version Relationship Local license evidence SPDX interpretation / disposition
espressif/esp_tinyusb 2.2.1 Direct; requires TinyUSB managed_components/espressif__esp_tinyusb/LICENSE Apache-2.0; retain notices and license.
espressif/led_strip 3.0.3 Direct managed_components/espressif__led_strip/LICENSE Apache-2.0.
espressif/mdns 1.12.0 Direct; requested ^1.8.2 managed_components/espressif__mdns/LICENSE Apache-2.0; inventory resolved 1.12.0, not minimum 1.8.2.
espressif/tinyusb 0.21.0~1 Transitive through esp_tinyusb managed_components/espressif__tinyusb/LICENSE MIT, copyright 20122026 hathach. Nested hw/bsp/espressif/components/led_strip/LICENSE is Apache-2.0: it is not a seventh lock package. Retain nested notices if distributing the full package.
wolfssl/wolfssl 5.8.2~1 Direct managed_components/wolfssl__wolfssl/LICENSE.txt, README.md, wolfssl/version.h GPL-3.0-or-later open-source option; GPLv3 can be selected with this project. The commercial alternative is not needed merely because the application is GPLv3-only.
wolfssl/wolfssh 1.4.20 Direct managed_components/wolfssl__wolfssh/LICENSE.txt, README.md, src/internal.c opening notice, wolfssh/version.h Packaging discrepancy: LICENSE/README describe wolfSSL/wolfCrypt, GPLv2-or-later, and include GPLv2 text; inspected wolfSSH headers explicitly grant GPL-3.0-or-later. Preserve both evidence sets; select GPLv3 for this integration, and seek upstream packaging clarification before release. Do not label wolfSSH GPL-2.0-only or silently rewrite vendor files.

Provenance references (not fetched): installed manifests point to esp-usb, esp-protocols, Espressif TinyUSB, wolfSSL, and wolfSSH. Installed repository metadata pins esp_tinyusb commit 8e779566ef71d43928cbf7e125e8eb54bab3f542, mDNS db06b19b7be729c163d346f62ec0eba01047b7f1, and TinyUSB 7049c58a0e895acc92c6407574b05b5536eddfc8. Use the LED strip manifest's repository metadata rather than infer a repository from its package name.

SDK core, bundled libraries, and compiler runtime

“Selected” means archive-selection evidence in the existing application map, not a full object/license attribution trace. Unversioned rows mean the installed IDF 5.5.0 snapshot, not an invented upstream release. Header versions do not identify every Espressif patch; preserve the resolved SDK package itself.

Group / version evidence Checked local license / notice paths SPDX / scope and action
IDF core and Espressif drivers 5.5.0 SDK/LICENSE, SDK/package.json, SDK/version.txt; original notices retained in the SDK overlays below Apache-2.0 baseline, not an umbrella claim over bundled code. Core archives selected. Include attribution and relevant notices, including bootloader distribution inputs.
FreeRTOS 10.5.1, Espressif port SDK/components/freertos/FreeRTOS-Kernel/LICENSE.md; version in include/freertos/task.h under that kernel directory MIT; selected. License text does not substitute for copyright notices in individual files.
lwIP 2.2.0 development, Espressif fork SDK/components/lwip/lwip/COPYING; src/include/lwip/init.h under that directory has LWIP_RC_DEVELOPMENT BSD-3-Clause; selected. Preserve Swedish Institute of Computer Science attribution; do not call it stock release 2.2.0.
Mbed TLS 3.6.3 SDK/components/mbedtls/mbedtls/LICENSE; include/mbedtls/build_info.h under that directory Apache-2.0 OR GPL-2.0-or-later; choose Apache-2.0 here. libmbedtls.a, libmbedcrypto.a, libmbedx509.a selected. Framework has a separate framework/LICENSE when shipping the full source tree.
HTTP parser 2.7.0 SDK/components/http_parser/LICENSE.txt, http_parser.h in that component MIT; selected. Preserve NGINX/Igor Sysoev and Joyent/Node attribution in the actual text.
argtable3, IDF snapshot SDK/components/console/argtable3/LICENSE Aggregate, including BSD-3-Clause, BSD-2-Clause, and TCL terms. It includes Stewart Heitmann, NetBSD getopt, Tcl, C Hash Table, and Better String notices. Do not reduce the entire file to one BSD label. libconsole.a selected; sublibrary/object attribution not exhaustively traced.
linenoise, IDF snapshot SDK/components/console/linenoise/LICENSE BSD-2-Clause, Salvatore Sanfilippo and Pieter Noordhuis; console selected.
TLSF allocator, IDF snapshot SDK/components/heap/tlsf/include/tlsf.h, SDK/components/heap/tlsf/tlsf_block_functions.h BSD-3-Clause SPDX headers, Matthew Conte 20062016; heap selected. No standalone TLSF license text appeared in the historical inventory; offline assembly now retains a scoped full TLSF rendering and provenance. Final object coverage/delivery still require review, not a generic BSD text with another author's name.
Xtensa HAL, IDF snapshot SDK/components/xtensa/include/xtensa/hal.h opening notice MIT-style full permission notice, Cadence 19992015; libxt_hal.a/libxtensa.a selected. Header evidence is not an audit of every HAL object or ROM implementation.
Espressif prebuilt radio libraries, IDF snapshot SDK/components/esp_wifi/lib/LICENSE, SDK/components/esp_phy/lib/LICENSE, SDK/components/esp_coex/lib/LICENSE All three files are byte-identical to SDK/LICENSE (Apache-2.0). Map selects Wi-Fi libcore.a, libespnow.a, libmesh.a, libnet80211.a, libpp.a, and PHY libbtbb.a, libphy.a. libesp_coex.a is selected but that does not prove libcoexist.a was selected. Corresponding-source/system-library question remains open, despite permissive binary redistribution terms.
Newlib 4.3.0 and IDF libc integration TC/xtensa-esp-elf/include/_newlib_version.h; TC/share/licenses/newlib/COPYING.NEWLIB; SDK/components/newlib/COPYING.NEWLIB Mixed per-file licenses; no single SPDX expression established. Toolchain notice file has 1,293 lines vs SDK copy's 952; preserve the actual runtime package's notices, not just the older SDK summary. libc.a and libnewlib.a selected. Target-specific LGPL/GPL sections for other architectures/Linux are not proof they apply to ESP32-S3; trace selected objects before making that claim.
GCC runtime / libstdc++ 14.2.0, package 14.2.0+20241119 TC/share/licenses/gcc/COPYING.RUNTIME, TC/share/licenses/gcc/gcc/COPYING3; TC/xtensa-esp-elf/include/c++/14.2.0/xtensa-esp-elf/esp32s3/bits/c++config.h Header explicitly supports GPL-3.0-or-later WITH GCC-exception-3.1; libgcc.a/libstdc++.a selected. Check exception eligibility and per-object terms; preserve exception and GPL notices. Package-level GPL-2.0-or-later metadata is not a runtime license inventory. COPYING3.LIB is LGPL text, not the GCC runtime exception.
cJSON 1.7.18 SDK/components/json/cJSON/LICENSE, cJSON.h there MIT; configured SDK component, no libjson.a selection in the inspected initial map region. Retain when distributing the SDK source; not asserted live in this image.
FatFs R0.15 w/patch2 SDK/components/fatfs/src/ff.c opening full notice LicenseRef-FatFs-local-notice (descriptive local identifier, not an official SPDX ID): source-retention permission/disclaimer, ChaN 2022. Configured, no libfatfs.a selection observed.
SPIFFS, IDF snapshot SDK/components/spiffs/spiffs/LICENSE MIT, Peter Andersson; configured, no libspiffs.a selection observed.
protobuf-c, IDF snapshot SDK/components/protobuf-c/protobuf-c/LICENSE BSD-2-Clause; configured, no libprotobuf-c.a selection observed.
ESP-MQTT, IDF snapshot SDK/components/mqtt/esp-mqtt/LICENSE Apache-2.0; configured, no libmqtt.a selection observed.

The eighteenth group is wpa_supplicant, recorded separately because its license requires reading two files: SDK/components/wpa_supplicant/COPYING redirects to SDK/components/wpa_supplicant/README, whose full grant is BSD-3-Clause. The historical GPLv2 option was retired in 2012 according to COPYING; do not flag a GPLv2-only conflict. libwpa_supplicant.a is selected; an independent upstream version was not established (use the IDF snapshot).

The installed license-path inventory also found OpenThread, NimBLE/Bluetooth, micro-ecc, Unity/CMock, and tool/test-specific licenses and NOTICE files. They were not promoted to fully reviewed linked dependencies. A full SDK/source or toolchain redistribution must preserve their applicable texts too. No inference that all of these are absent from every bootloader, ROM, or future build is made. The bootloader map, every bundled file, and every selected runtime object were not audited. Newlib, argtable3, radio blobs, ROM attribution, and nested package contents remain aggregation boundaries needing release-specific review.

Checked-in assets and existing notice sufficiency

Asset Version / local evidence Finding
@xterm/xterm 5.5.0; web_assets/xterm.js, xterm.css, xterm.LICENSE; SOURCES.md provides exact npm URLs/hashes MIT. Full notice retained in repository; CSS also retains a notice. Minified JS has no copyright, permission is hereby, or license marker.
@xterm/addon-fit 0.10.0; web_assets/addon-fit.js, addon-fit.LICENSE; same provenance document MIT. Full notice retained in repository; minified JS lacks those notice markers.
Pictogrammers Material Design Icons Official 7.4.47, immutable commit 9e04201d4557e729822fb57f62a316c3dea1d4a8; exact evidence Retained SVGs are byte-identical to upstream; metadata credits Google (USB) and Simran (Wi-Fi). Apache-2.0 package evidence, full license text and a pinned-tree check finding no NOTICE are retained. Manual firmware bitmap derivation and the distinct Wi-Fi mockup path remain unresolved; source identity is not complete derivative or release clearance.
Project logo web_assets/logo.png, derived from images/logo.png per SOURCES.md Project-owned according to provenance document; no independent third-party license assigned. Generator's MIT banner must not be treated as proof that the logo was separately relicensed MIT.

Historical 2026-09-15 git ls-files '*LICENSE*' '*COPYING*' '*NOTICE*' found 4 tracked license files: root GPLv3, two web MIT texts, and the icon summary. That historical count predates the retained upstream icon evidence and full Apache text now included in the 75-input catalog. Neither repository retention nor assembly proves recipient delivery or release compliance.

web_assets/generate_embedded_assets.py embeds three gzip files and the logo, not either MIT license file. Its generated-source banner points back to provenance/licenses; it is not the upstream MIT notice itself. This proves the embedding path does not carry the separate notice texts, not that every possible product-delivery channel lacks notices. Coordinate a release notice bundle and a way for recipients of the browser assets to obtain the notices (for example a bundled/served third-party license resource); verify the actual delivery path. Do not assume repository-only notices accompany a standalone firmware/device or a downloaded JS response. No assets or web endpoints were changed in this audit.

Preferred-source availability is a separate issue from retaining MIT notices. For a GPL-covered combined release, preserve exact upstream preferred-form browser sources and build inputs where required; the checked-in minified JS distributions and gzip/C arrays are not automatically the preferred form for modification. Source-map references alone do not provide that source. Whether independent browser packages are mere aggregation should be assessed for the actual distribution, not assumed either way.

GPLv3 distribution and build-overlay obligations

The inspected MIT, BSD and Apache-2.0 grants provide generally GPLv3-compatible routes; the project's GPL-3.0-only choice can use wolfSSL/wolfSSH's version-3 alternatives. This is not permission to remove upstream notices or declare all files GPL-only. No commercial wolfSSL/wolfSSH license is recommended on the evidence here. Commercial arrangements would be a separate decision if a planned distribution cannot satisfy the available open-source terms, not a cure for unrelated project/SDK obligations.

For conveyance, review GPLv3 §§1, 46, 7 and 10 in LICENSE:

  1. Supply required license/copyright/warranty notices and use a §6-compliant corresponding-source delivery method for binaries. A dependency name, registry URL, generic upstream source link, or this inventory alone is not corresponding source or a compliant written offer.
  2. Preserve exact application source, lock/manifests, relevant SDK and managed source, configuration/build/link inputs, asset preferred sources and generation scripts. Include the scripts controlling compilation/installation. Generic unmodified build tools may fall outside corresponding source, but record precise versions needed for reproduction; if distributing those tools themselves, satisfy their separate licenses.
  3. The Phase 9C9D firmware compiles pinned originals plus project edits. Include tools/security_overrides.py, cmake/security_overrides.cmake, root CMake integration, cmake/wolf_crypto_policy.{cmake,h}, the complete tools/wolfssh_order/ inputs, original hash-matching C/header sources, and the means to reproduce all nine C copies and the PUBLIC forced header. A stock IDF/wolfSSH tarball alone omits the compiled modifications. Generated copies alone are not a substitute for the preferred editable patch/generator inputs.
  4. Resolved; updated 2026-09-18: all nine generated C files plus one header below retain upstream notices and carry explicit project modification/date notices from the generator (baseline 2026-09-15, plus 2026-09-16 ordering notices on wolfSSH outputs). The historical four-file audit found the notice missing; this narrow defect is repaired. GPLv3 §5(a) calls for a relevant date, and Apache-2.0 §4(b) requires prominent change notices. Continue including notices and reproducible generator inputs in distribution; do not hand-edit generated copies or vendor sources.
  5. If distributing a GPLv3 “User Product,” assess and provide required Installation Information under §6. Do not publish device passwords, private keys, Wi-Fi material, account verifiers, tickets, NVS images, or real credential backups as build/source artifacts. Installation compliance should use appropriate documented procedures, not routine secret disclosure. Secure boot was not enabled or altered here.
  6. Prebuilt radio libraries are the principal unresolved compatibility/source risk. Apache-2.0 permits binary redistribution, but does not itself satisfy GPL corresponding-source obligations for a combined firmware. Establish whether required preferred source is obtainable, or whether a defensible GPL System Library/other exception applies to the actual linked artifacts. Static linkage is not automatically “mere aggregation.” Do not declare distribution cleared or definitely prohibited from this bounded audit. Escalate this before a public binary/device release.

Current generated paths and retained licenses (nine C sources plus one header). Here BUILD/ denotes the validated candidate build, .pio/idf-candidate-5.5.3/app-validated/.pio/build/esp32-s3-devkitc-1-n16r8/, rather than the historical audit root:

  • BUILD/security_overrides/https_server/https_server.c — Espressif Apache-2.0.
  • BUILD/security_overrides/httpd_parse/httpd_parse.c — Espressif Apache-2.0.
  • BUILD/security_overrides/httpd_ws/httpd_ws.c — Espressif Apache-2.0; five signed fixed-header receive-size comparisons, with generated modification/rebase notices.
  • BUILD/security_overrides/esp_tls_mbedtls/esp_tls_mbedtls.c — Espressif Apache-2.0.
  • BUILD/security_overrides/wolfssh_internal/internal.c — wolfSSH GPL-3.0-or-later header.
  • BUILD/security_overrides/wolfssh_ssh/ssh.c — wolfSSH GPL-3.0-or-later header.
  • BUILD/security_overrides/wolfssh_include/wolfssh/internal.h — wolfSSH GPL-3.0-or-later header; ABI overlay propagated BEFORE PUBLIC and as a PUBLIC forced include, not a C compilation unit.
  • BUILD/security_overrides/dhcpserver/dhcpserver.c — retained Espressif Apache-2.0 header.
  • BUILD/security_overrides/mbedtls_ssl_tls/ssl_tls.c — retained Mbed TLS Contributors, Apache-2.0 OR GPL-2.0-or-later.
  • BUILD/security_overrides/mbedtls_x509_create/x509_create.c — retained Mbed TLS Contributors, Apache-2.0 OR GPL-2.0-or-later.

Archived ordering patches and license context

Ordering provenance documents the restricted CVE-2025-14942 correction, not a complete upstream backport or upgrade. delta.json is the preferred editable, executable consolidated delta; archived upstream mail patches are provenance/prerequisite evidence, not a statement that all their hunks compile into the firmware. provenance.json retains the original URLs and every full embedded commit ID. Archived bytes fetched 2026-09-16 are pinned as follows; future PR responses may differ:

Archive under tools/wolfssh_order/ SHA-256
793.patch 66aa999521800371f97b340db2bff162be4e8ffab4b4b953f9d32b8e33f56cea
819.patch 8e63c2b24679a7d831f7dba12e412d2f8a7fdc391fc4e8fd33f029487110219b
840.patch 23e25873cb4dfa36063357111019e0960dfc008a68cc29d6e2d5c37bde47ec94
855.patch b94393df9528f66f6df1aba94015331fee3110c9ea2007a0eff369d8887b4b29
921.patch f6c88598d7f3c94d92c31cecc4ef1e6d779b49f9eff6556ac1c57426d272d504

Preserve upstream mail authorship, commit metadata and applicable file notices with these archives. They contain upstream wolfSSH code/context, not newly project-authored material automatically relicensed by the generator's GPL-3.0-only SPDX line. The compiled wolfSSH C/header derivatives retain the upstream GPL-3.0-or-later grants; select GPLv3 for this integration. Patch hashes prove identity, not license permission or full archive-level clearance. Retain the upstream license texts and package discrepancy evidence, and review applicable per-file terms for any archived but unapplied example/test/workflow content when assembling the source package. No standalone blanket license grant for every patch byte is inferred from mail-patch format. Source/notice delivery and release packaging remain open.

For Apache-2.0 components, retain required attribution and any applicable upstream NOTICE contents under §4(d), if present; do not fabricate NOTICE text or assert every Apache package must have a NOTICE file. For MIT/BSD components, distribute the actual copyright, permission/conditions and disclaimer, not merely an SPDX name. Preserve mixed notices such as argtable3 and Newlib rather than replacing them with generic templates.

Actionable release work (not performed)

Notice assembly is implemented; the remaining release actions below have not been completed.

Priority Action / completion evidence
Release blocker to resolve Document a defensible corresponding-source/exception basis for the selected radio blobs and other source-unavailable linked content. This is an unresolved question, not a legal verdict.
Assembly tooling implemented; delivery pending Offline tool and procedure assemble 75 pinned inputs, retaining GPL/Apache/MIT/BSD texts, mixed SDK/toolchain Newlib and argtable3 notices, GCC exception and a scoped full TLSF rendering. Supplied agent fixture suite: 36 PASS; two actual bundles independently verified deterministic, each 77 files / 4,433,930 bytes. Validate final firmware/device/browser recipient delivery; assembly is not corresponding-source delivery or legal clearance.
Before distributing icon derivatives Exact retained SVG provenance is resolved at official 7.4.47; full Apache-2.0 text and attribution are retained, with no NOTICE found in the pinned distribution. Preserve manual bitmap preferred sources and resolve the distinct mockup Wi-Fi path/derivation limits. Recipient delivery remains open; do not invent a NOTICE or rasterizer.
Resolved in generator; retain in distribution Prominent modification notices cover nine C sources plus one header (baseline 2026-09-15, wolfSSH ordering 2026-09-16), with original notices retained. Release packaging must still include them, archived patches/provenance, consolidated delta and reproducible build inputs.
Upstream clarification Record/resolve wolfSSH 1.4.20 package LICENSE/README vs source-header mismatch without editing the managed package in place. GPLv3 is supported by the inspected headers and is also within the package prose's “or later” wording.
Release packaging verification Archive exact corresponding source/build inputs and required asset preferred sources; validate source delivery/offer and any User Product installation information. Recheck bootloader, runtime objects and aggregation boundaries against the final release map.

Minimal offline repeat check

Run from the repository root against an already-resolved local environment. This only reads manifest/license/provenance metadata; it does not invoke PlatformIO, install dependencies, regenerate assets, read configuration secrets, or validate legal compliance. It requires Python 3 and PyYAML (the latter is normally available in the component-manager environment). A missing prerequisite must be reported, not automatically downloaded. Adjust the two package roots if auditing another machine.

python3 - <<'PY'
from pathlib import Path
import hashlib
import json
import re
import yaml

sdk = Path('/home/mscholz/.platformio/packages/framework-espidf')
tc = Path('/home/mscholz/.platformio/packages/toolchain-xtensa-esp-elf')
expected = {
    'espressif/esp_tinyusb': ('2.2.1', 'LICENSE'),
    'espressif/led_strip': ('3.0.3', 'LICENSE'),
    'espressif/mdns': ('1.12.0', 'LICENSE'),
    'espressif/tinyusb': ('0.21.0~1', 'LICENSE'),
    'wolfssl/wolfssh': ('1.4.20', 'LICENSE.txt'),
    'wolfssl/wolfssl': ('5.8.2~1', 'LICENSE.txt'),
}
lock = yaml.safe_load(Path('dependencies.lock').read_text())
assert set(lock['dependencies']) == set(expected) | {'idf'}
assert str(lock['dependencies']['idf']['version']) == '5.5.0'
assert sdk.joinpath('version.txt').read_text().strip() == '5.5.0'
assert json.loads(sdk.joinpath('package.json').read_text())['version'] == '3.50500.0'
assert json.loads(tc.joinpath('package.json').read_text())['version'] == '14.2.0+20241119'
for name, (version, license_name) in expected.items():
    directory = Path('managed_components') / name.replace('/', '__')
    manifest = yaml.safe_load((directory / 'idf_component.yml').read_text())
    assert str(lock['dependencies'][name]['version']) == version
    assert str(manifest['version']) == version
    license_path = directory / license_name
    assert license_path.stat().st_size > 0
    print(name, version, license_path,
          hashlib.sha256(license_path.read_bytes()).hexdigest())
for name, digest in re.findall(r'\| `([^`]+)` \| `([a-f0-9]{64})`',
                               Path('web_assets/SOURCES.md').read_text()):
    assert hashlib.sha256((Path('web_assets') / name).read_bytes()).hexdigest() == digest
for path in [Path('LICENSE'), Path('third_party/material-design-icons/LICENSE'),
             sdk / 'LICENSE', sdk / 'components/wpa_supplicant/README',
             sdk / 'components/console/argtable3/LICENSE',
             sdk / 'components/newlib/COPYING.NEWLIB',
             tc / 'share/licenses/newlib/COPYING.NEWLIB',
             tc / 'share/licenses/gcc/COPYING.RUNTIME']:
    assert path.stat().st_size > 0
    print(path, hashlib.sha256(path.read_bytes()).hexdigest())
for name, digest in {
    'dependencies.lock': '2d1c62093cafdb54cd209813c526c35e2e470b62cc6f5b0cde9a040569662726',
    'src/idf_component.yml': '7fe8cfd25db36dd23907cd1aa7645f3d5b5f34f7ed587cd2599690b5ffbda053',
    'platformio.ini': 'b0139667b13c0e254b5ffa67df6cb323f4554a3657fb100330067d6110d57518',
}.items():
    assert hashlib.sha256(Path(name).read_bytes()).hexdigest() == digest, name
print('PASS: scoped manifest versions, notice presence, and recorded hashes')
PY

This is a drift tripwire, not a full component-content verifier or complete license scanner. On changes, inspect new notices and nested components, trace final application/bootloader maps, revisit the build overlays and regenerate a release inventory deliberately. Do not simply repin expected values. Network/upstream authentication, advisory review, legal aggregation analysis, complete notice assembly and hardware validation remain outside this check.