- Enforce exact service and channel names with bounded failure parsing - Add hash-pinned offline notice assembly and regression coverage - Record advisory dispositions, provenance, integration evidence, and remaining gates
9.0 KiB
Offline release notice packaging
This procedure produces a bounded notice/provenance bundle, not a firmware release, corresponding-source archive, complete SBOM, or legal clearance. The radio-blob corresponding-source/System Library question remains open. See the license inventory for the original review and the retained scope/provenance statement for license choices, mixed notices, wolfSSH packaging discrepancy, TLSF text assembly, icon limits, and remaining release gates.
Run against the installed reviewed snapshot
Requirements: Python 3.9+ on Linux/POSIX with O_NOFOLLOW, directory descriptors
and dir_fd operations; already installed matching managed components,
ESP-IDF and Xtensa toolchain. Standard library only. The tool never fetches,
installs, builds, runs PlatformIO, accesses a device, or regenerates assets.
Run from the repository root. Supply an explicit, not-yet-existing output directory outside all three input roots, with an existing parent. Example for the inventory's local installation (choose a fresh final directory name):
python3 tools/release_notices.py \
--sdk-root /home/mscholz/.platformio/packages/framework-espidf \
--toolchain-root /home/mscholz/.platformio/packages/toolchain-xtensa-esp-elf \
--output /tmp/esp32-release-notices-review-01
--project-root optionally selects a different checkout containing the exact
reviewed inputs; by default it is the script's repository. The trusted catalog
always comes from the script's repository, not from that alternate checkout.
Paths to SDK/toolchain packages are explicit; no installation is guessed.
There is no user catalog option, force/overwrite mode, automatic repinning,
recursive collection, archive command, or automatic release upload.
Every input in third_party/release-notices/inputs.json is mandatory and pinned
by full-file SHA-256 and size. Missing sources, altered bytes, bad excerpts,
empty files, directories, FIFOs, symlinks (even to identical files), parent
traversal, binary notice payloads and exhausted bounds fail closed. Symlinks in
input-root or output-parent ancestry are rejected too: pass real non-symlinked
paths, not a convenience symlink. All input preflight completes before creating
output. The limits are 128 inputs, 4 MiB per input/catalog and 32 MiB cumulative
source bytes. The current catalog has 62 inputs (about 2.1 MB read and 0.51 MB
copied before the generated manifest/introduction).
An existing output file, directory (even empty) or dangling symlink is never overwritten. Parent directories are not automatically created. Output uses private directory/file modes (0700/0600, subject to umask). On a write failure, the tool deliberately leaves any partial directory for inspection and never recursively deletes it. A successful exit plus a valid manifest and matching payload hashes is required; presence of a partial manifest is not success. Use another fresh path for a retry. Do not put output into a tree that an untrusted process can concurrently rename or modify; descriptor/no-follow checks prevent symlink traversal but are not isolation from the same OS user.
Bundle layout and reproducibility
README.txt: limitations and entry point for recipients.inputs/project/…: project GPL text, resolved lock, managed licenses and manifests, wolfSSL/wolfSSH README evidence, original wolfSSH header excerpts, xterm MIT texts and recorded provenance, icon summary, TLSF full rendering and scope/provenance statement.inputs/sdk/…: complete scoped SDK license documents, mixed Newlib/argtable3 notices, radio license files, package/version identity and original source notice excerpts. SDKLICENSEsupplies full Apache-2.0 text; it does not authenticate individual icons or cover all SDK files.inputs/toolchain/…: actual toolchain Newlib text, GPLv3, GCC Runtime Library Exception 3.1 and package identity. No toolchain executable is copied.manifest.json: schema/snapshot, catalog SHA-256, logical root/path, full-source size/hash, optional zero-based half-open byte range, purpose, output path/size/hash, and the generated introduction's hash. Excerpts have.notice.txtappended; null ranges retain whole original files unchanged.
Whole mixed documents are preserved, not converted into guessed SPDX labels. The longer toolchain Newlib notice does not replace the distinct SDK text. The wolfSSH package GPLv2-or-later text and GPLv3-or-later source headers remain separate and unmodified; upstream packaging clarification is still needed.
Generated metadata contains no collection timestamps or absolute host paths; original notices retain their own dates and text. For identical catalog and inputs, file names and file contents are deterministic across output locations, input-root locations and source mtimes. Directory/file mtimes are not normalized, and no reproducible tar/zip archive is claimed. The manifest hashes all payloads but not itself; retain its hash in your separate release evidence if needed. The catalog is trusted reviewed policy, not a cryptographic signature or proof of package-wide integrity/authorship.
Only explicit catalog paths are read. No application config, sdkconfig, build tree, ELF/map/binary, key, credential backup, NVS/flash dump or whole repository is collected. Hash-pinned source implementations are read only to validate original header excerpts, not copied as implementations. The lock and installed package/component manifests are dependency identity metadata, not build configuration. A hash pin is not a general-purpose secret scanner: review additions to this trusted list before accepting them.
Validate and inspect
Temporary-fixture regression suite (does not need installed packages):
python3 tests/release_notices/run.py
The suite tests missing/changed sources (including changes outside a notice excerpt), exact mixed-text retention, byte ranges, path traversal, source/root/ output symlinks, existing user data, nonregular files, bounds, output failures, secret/config exclusion, determinism, and CLI behavior. No hardware tests are implied.
For a real bundle, check the successful process exit, parse manifest.json,
recompute every payload hash/size, check no unlisted files are present, and
read the scope statement. Compare two independently created fresh outputs by
relative names and bytes (not mtimes). Inspect at least both Newlib files,
argtable3, wpa_supplicant COPYING/README, GCC exception, wolfSSH LICENSE/README
and header excerpts, TLSF text/provenance, both xterm notices and the icon
summary. These checks establish scoped assembly, not release compliance.
If a pinned input differs, stop and review the changed package/license/source. There is deliberately no update-catalog command. Review versions, new/nested NOTICEs, original source notice ranges and hashes, then deliberately update catalog policy and test it. The runtime does not discover added notices or packages outside its finite list; this limitation makes its reads bounded and prevents opportunistic collection of user files.
Separate work before distribution
- Resolve or obtain qualified review of radio-blob corresponding-source or exception basis for the actual linked firmware. Apache binary permissions alone do not settle this question. No legal clearance is claimed.
- Resolve the wolfSSH package/header discrepancy and verify exact two-icon provenance/licensing (recorded 7.4.47), including any applicable NOTICE. Supplying the full Apache text is not provenance verification. No icon assets or generated data were changed by this packaging work.
- Audit the final application/bootloader/runtime object set and aggregation boundaries. Full SDK/toolchain redistribution needs broader nested/tool/test notice coverage; this is not an all-files license scanner.
- Prepare and validate a separate, deliberately reviewed corresponding-source
delivery. Preserve exact required sources and safe build/install inputs,
asset preferred sources and scripts, original hash-matching overlay inputs,
tools/security_overrides.py,cmake/security_overrides.cmake, root CMake integration,cmake/wolf_crypto_policy.{cmake,h}, and the completetools/wolfssh_order/inputs/provenance/archives. Preserve upstream notices and generated dated change notices on eight C sources and one PUBLIC forced header. A stock vendor tarball or this notice bundle is not sufficient. Do not automatically archive the working repository or real configurations. - Assess GPLv3 source delivery/offer and User Product Installation Information. Protect device passwords, Wi-Fi credentials, private keys, verifiers, tickets, credential backups and flash/NVS images throughout that process.
- Arrange and verify actual notice delivery with firmware, devices and browser assets. This command does not add a license endpoint, change browser assets, or prove that a recipient of a JS response or standalone device receives notices. Keep these gates open until the real delivery path is validated.