Files
ESP32_Serial_Swiss_Army_Knife/docs/release_packaging.md
T
Commander1024 cdc4d4a8df Add Phase 9 validation and advisory review
Record the finite dependency search, Wi-Fi maintenance blocker, and
pinned
icon provenance. Add bounded host orchestration and fixture coverage,
and
update release documentation with current evidence.
2026-09-16 16:26:46 +02:00

168 lines
10 KiB
Markdown

# 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](dependency_licenses.md) for the original review and
[the retained scope/provenance statement](../third_party/release-notices/README.md)
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):
```sh
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 **75 inputs**, including the retained SVGs and pinned
[icon provenance evidence](icon_provenance.md). Overview documents edited in this
integration are not catalog inputs; `docs/icon_provenance.md` **is pinned**.
Coordinate any change to that record with the catalog owner; never silently repin.
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 and official 7.4.47
SVG/license/metadata evidence, 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. SDK `LICENSE` supplies 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.txt` appended; 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):
```sh
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.
## Supplied execution evidence — 2026-09-16
Agent results: **36 notice fixture tests PASS**, and **two actual 75-input
bundles verified deterministic**, each **77 files / 4,433,930 bytes**. These
replace the earlier 62-input / 64-file / 541,147-byte snapshot, not its historical
record. No parent rebuild or bundle reassembly was run in this documentation
turn; firmware source is unchanged. Assembly is not legal clearance or Phase 9
acceptance. The [unfixed Wi-Fi blocker](wifi_security_update_plan.md) also remains
a separate security gate; a future coherent vendor update requires catalog review.
## Separate work before distribution
1. 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.
2. Resolve the wolfSSH package/header discrepancy and remaining icon derivative
questions. [Exact retained SVG provenance](icon_provenance.md) is verified at
official 7.4.47, commit `9e04201d4557e729822fb57f62a316c3dea1d4a8`: Google
USB and Simran Wi-Fi. Full Apache text is retained; no NOTICE was found in
that pinned distribution. Manual firmware bitmap derivation and the distinct
mockup Wi-Fi path remain unresolved. No artwork was regenerated.
3. 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.
4. 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 complete
`tools/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.
5. 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.
6. 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.