diff --git a/.gitattributes b/.gitattributes index 3e4f7281a..6556a9eee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,6 +14,7 @@ docs/plans/torch-cross-platform-runtime-management/reports/managed-python-licens # Preserve verbatim third-party legal bytes, including mixed line endings. scripts/release/licenses/* -text -whitespace +scripts/release/licenses/managed-python-supplemental/* -text -whitespace docs/release-attribution/**/THIRD-PARTY-NOTICES.txt -text -whitespace # Archive-captured CPython metadata and license texts are evidence and must remain verbatim. docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/**/managed-python-licenses/full-archive/** -text -whitespace diff --git a/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/README.md b/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/README.md index 354e23bdc..9d6bbda27 100644 --- a/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/README.md +++ b/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/README.md @@ -29,9 +29,10 @@ The Linux evidence README describes the accepted installation that produced its selected archive record. All per-file hashes can be checked directly against the manifests. -## Outstanding attribution evidence +## Declared files missing from the archives -The inventory includes the collected files for all three targets. It does not -certify completeness of declared references: the upstream Windows archive -omits a declared zstd license file. See the -[verified evidence gap and release gate](missing-declared-license-references.md). +Each `PYTHON.json` also declares zstd (all three targets) or zlib-ng (Linux and +macOS) license files that the upstream full archives omit. Release attribution +fills these from byte-verified supplemental texts taken from the source +archives that python-build-standalone pins, and labels them as such. See the +[evidence gap and its resolution](missing-declared-license-references.md). diff --git a/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/linux-x86_64-cpython-3.14.7/README.md b/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/linux-x86_64-cpython-3.14.7/README.md index abcf50170..0eab9b014 100644 --- a/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/linux-x86_64-cpython-3.14.7/README.md +++ b/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/linux-x86_64-cpython-3.14.7/README.md @@ -13,9 +13,9 @@ declared file references outside that directory. The files document the Linux archive only. Corresponding Windows x86_64 and macOS arm64 collections are retained beside this directory; all three are -included in the 0.7.0 attribution inventory. Collection does not establish -complete upstream license coverage: see the [missing declared license -report](../missing-declared-license-references.md) before release acceptance. +included in the 0.7.0 attribution inventory. The archive omits +two declared license files; see the [missing declared license +report](../missing-declared-license-references.md) for the supplemental texts. See [`full-archive-manifest.json`](managed-python-licenses/full-archive-manifest.json) for exact source identities and per-file hashes. The raw `PYTHON.json` and diff --git a/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/missing-declared-license-references.md b/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/missing-declared-license-references.md index 88611f81c..20da36857 100644 --- a/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/missing-declared-license-references.md +++ b/docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/missing-declared-license-references.md @@ -1,28 +1,43 @@ # Missing declared upstream license references -**Status:** Open release attribution blocker. Owner: Pumas release/licensing review. +**Status:** Resolved for 0.8.0 by supplemental texts from the pinned source +archives. Owner: Pumas release/licensing review. -CodeRabbit identified a reference to `licenses/LICENSE.zstd.txt` in the Windows -CPython 3.14.7 `PYTHON.json` that is absent from the retained license files. -On 2026-09-29 the exact official Windows full archive was downloaded again: - -- Asset: `cpython-3.14.7+20260901-x86_64-pc-windows-msvc-pgo-full.tar.zst` -- SHA-256: `5363ec4aab59c24417f9877217aae95ca17f9ae6eb99c3bbfb25e4a76dcadafe` -- Size: 49,262,780 bytes; both size and digest match the retained manifest. -- The archive itself contains 19 `python/licenses/` files and omits the declared - zstd file. This is an upstream evidence gap, not an omitted extraction. - -The retained metadata and manifest remain byte-exact. Do not insert a guessed -license text or misrepresent an externally sourced file as an archive member. -The current inventory covers collected files; it does not certify every declared -reference. Audit of all three retained metadata records found: +The CPython 3.14.7 `PYTHON.json` files from python-build-standalone `20260901` +declare license files that the official full archives do not contain: - `windows-x86_64-cpython-3.14.7`: `licenses/LICENSE.zstd.txt`. - `macos-arm64-cpython-3.14.7`: `licenses/LICENSE.zlib-ng.txt`, `licenses/LICENSE.zstd.txt`. - `linux-x86_64-cpython-3.14.7`: `licenses/LICENSE.zlib-ng.txt`, `licenses/LICENSE.zstd.txt`. -Before release acceptance, obtain authoritative terms and exact source/version -mapping for the missing bundled component from the upstream provider, retain -separate provenance for any supplemental legal files, and update the notice -generator and inventory from that evidence. Native runtime test success does -not close this licensing gate. +The Windows archive was downloaded again on 2026-09-29 +(`cpython-3.14.7+20260901-x86_64-pc-windows-msvc-pgo-full.tar.zst`, SHA-256 +`5363ec4aab59c24417f9877217aae95ca17f9ae6eb99c3bbfb25e4a76dcadafe`, +49,262,780 bytes, matching the retained manifest). It holds 19 +`python/licenses/` files and no zstd file, so this is an upstream gap, not an +extraction error. The retained manifests and `PYTHON.json` files stay byte-exact. + +## Resolution + +`pythonbuild/downloads.py` at python-build-standalone tag `20260901` pins the +two components, and both source archives were downloaded and matched their pins: + +| Declared file | Component | SPDX | Source archive | Size | SHA-256 | Text taken from | +| --- | --- | --- | --- | ---: | --- | --- | +| `LICENSE.zstd.txt` | zstd 1.5.7 | BSD-3-Clause | [`zstd-1.5.7.tar.gz`](https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz) | 2,440,298 | `f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e` | `cpython-source-deps-zstd-1.5.7/LICENSE` | +| `LICENSE.zlib-ng.txt` | zlib-ng 2.2.4 | Zlib | [`zlib-ng-2.2.4.tar.gz`](https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz) | 2,415,819 | `00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004` | `cpython-source-deps-zlib-ng-2.2.4/LICENSE.md` | + +The texts are kept byte-exact, apart from the archive evidence, in +[`scripts/release/licenses/managed-python-supplemental/`](../../../../../scripts/release/licenses/managed-python-supplemental/). +Each has a `.provenance.json` record naming the declared path, release, targets, +source archive identity, path inside that archive and the text's SHA-256. They +are not archive members and are never listed as such. + +- The Torch acceptance collector accepts a declared path missing from the + archive only when a record for that exact path, target and release exists + and its text hash matches. Any other missing declared path still fails. Its + manifest lists archive files under `files` and supplemental texts under + `supplemental_files`. +- The notice generator and attribution checker require every declared path to + be an archive member or a verified supplemental text. Each supplemental text + gets its own notice, labelled with the source archive it came from. diff --git a/docs/release-attribution/0.8.0-s3/THIRD-PARTY-NOTICES.txt b/docs/release-attribution/0.8.0-s3/THIRD-PARTY-NOTICES.txt index a11efbef8..3d5a8e94e 100644 --- a/docs/release-attribution/0.8.0-s3/THIRD-PARTY-NOTICES.txt +++ b/docs/release-attribution/0.8.0-s3/THIRD-PARTY-NOTICES.txt @@ -10,6 +10,10 @@ is recorded in the release attribution report, not inferred from this list. The uv notice covers a runtime executable downloaded by Pumas, not a bundled binary. Managed CPython full-archive notices are target-scoped supersets for separately selected install-only distributions; each archive identity is recorded below. +Where a CPython PYTHON.json declares a license file that its full archive omits, +a separately labelled supplemental notice reproduces that component's license +file from the source archive pinned by python-build-standalone; it is not an +archive member. adler2 2.0.1 (Rust normal/build dependency, all desktop targets; conservative superset) Source: https://crates.io/api/v1/crates/adler2/2.0.1/download @@ -88870,6 +88874,71 @@ docs/license.html_lib. jloup@gzip.org madler@alumni.caltech.edu +============================================================================== + +zlib-ng 2.2.4 (Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz +Declared license: Zlib +--- managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md --- +(C) 1995-2024 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. + + +============================================================================== + +zstd 1.5.7 (Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz +Declared license: BSD-3-Clause +--- managed-python-supplemental/zstd-1.5.7-LICENSE --- +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ============================================================================== CPython full archive 3.14.7 (Managed Python full-archive notice superset for x86_64-pc-windows-msvc; selected install-only runtime tracked separately) @@ -91444,6 +91513,44 @@ docs/license.html_lib. jloup@gzip.org madler@alumni.caltech.edu +============================================================================== + +zstd 1.5.7 (Managed Python supplemental license text for x86_64-pc-windows-msvc; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz +Declared license: BSD-3-Clause +--- managed-python-supplemental/zstd-1.5.7-LICENSE --- +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ============================================================================== CPython full archive 3.14.7 (Managed Python full-archive notice superset for x86_64-unknown-linux-gnu; selected install-only runtime tracked separately) @@ -94018,6 +94125,71 @@ docs/license.html_lib. jloup@gzip.org madler@alumni.caltech.edu +============================================================================== + +zlib-ng 2.2.4 (Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz +Declared license: Zlib +--- managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md --- +(C) 1995-2024 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. + + +============================================================================== + +zstd 1.5.7 (Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz +Declared license: BSD-3-Clause +--- managed-python-supplemental/zstd-1.5.7-LICENSE --- +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ============================================================================== uv 0.12.18 (Managed Python provider runtime executable downloaded by Pumas; not bundled) diff --git a/docs/release-attribution/0.8.0-s3/inventory.json b/docs/release-attribution/0.8.0-s3/inventory.json index 3501583be..b41d3ab86 100644 --- a/docs/release-attribution/0.8.0-s3/inventory.json +++ b/docs/release-attribution/0.8.0-s3/inventory.json @@ -8715,6 +8715,32 @@ } ] }, + { + "name": "zlib-ng", + "version": "2.2.4", + "license_declared": "Zlib", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz", + "scope": "Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee" + } + ] + }, + { + "name": "zstd", + "version": "1.5.7", + "license_declared": "BSD-3-Clause", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz", + "scope": "Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8" + } + ] + }, { "name": "CPython full archive", "version": "3.14.7", @@ -8800,6 +8826,19 @@ } ] }, + { + "name": "zstd", + "version": "1.5.7", + "license_declared": "BSD-3-Clause", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz", + "scope": "Managed Python supplemental license text for x86_64-pc-windows-msvc; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8" + } + ] + }, { "name": "CPython full archive", "version": "3.14.7", @@ -8885,6 +8924,32 @@ } ] }, + { + "name": "zlib-ng", + "version": "2.2.4", + "license_declared": "Zlib", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz", + "scope": "Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee" + } + ] + }, + { + "name": "zstd", + "version": "1.5.7", + "license_declared": "BSD-3-Clause", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz", + "scope": "Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8" + } + ] + }, { "name": "uv", "version": "0.12.18", @@ -9073,6 +9138,20 @@ "path": "docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/macos-arm64-cpython-3.14.7/managed-python-licenses/full-archive/licenses/LICENSE.zlib.txt", "sha256": "818922b2620f12801a12bf78e399644a30990e66824abd8ca8ec24d451d6f92c" } + ], + "supplemental_legal_files": [ + { + "declared_path": "licenses/LICENSE.zlib-ng.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee", + "provenance": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md.provenance.json" + }, + { + "declared_path": "licenses/LICENSE.zstd.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "provenance": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json" + } ] }, { @@ -9164,6 +9243,14 @@ "path": "docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/windows-x86_64-cpython-3.14.7/managed-python-licenses/full-archive/licenses/LICENSE.zlib.txt", "sha256": "365e36720db366054863235aea5d6f440142ab968834bfaf81fa9d187c99b9b8" } + ], + "supplemental_legal_files": [ + { + "declared_path": "licenses/LICENSE.zstd.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "provenance": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json" + } ] }, { @@ -9255,6 +9342,20 @@ "path": "docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/linux-x86_64-cpython-3.14.7/managed-python-licenses/full-archive/licenses/LICENSE.zlib.txt", "sha256": "818922b2620f12801a12bf78e399644a30990e66824abd8ca8ec24d451d6f92c" } + ], + "supplemental_legal_files": [ + { + "declared_path": "licenses/LICENSE.zlib-ng.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee", + "provenance": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md.provenance.json" + }, + { + "declared_path": "licenses/LICENSE.zstd.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "provenance": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json" + } ] } ], @@ -9336,7 +9437,11 @@ "rust/crates/pumas-rpc/Cargo.toml": "92b67b71767f6f495895c6d35a7c72107cfccc1cb60dedc400dd7f301a3a97f8", "scripts/release/artifact-plan.json": "66348a507f00ffdc74741fc7d70eab02f4a0eed4d3655354784cea2971662064", "scripts/release/licenses/managed-python-sources.json": "eabda4e2a25a92cfa8610865e79d11a50836930f53098efe89dd90778c4212ca", - "scripts/release/torch-managed-python-acceptance.py": "b0486387627d6ae98b4b6533adcceed93e93ebf868385626f3b13f1fb949893b" + "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee", + "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md.provenance.json": "3abbd4c93221c44bd33aa7012b5cd12bd1bce0a569768d076e820ee24959c10d", + "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json": "7b15e355b4839ed30f39267b47c3048902765f21805c9caa5099a7ab5301431d", + "scripts/release/torch-managed-python-acceptance.py": "2fe0e7a7727026690c67485a0aa072c07d728836b3ad0f8db4eb5ab3edb66198" }, - "notices_sha256": "d8d7ca82bbf0ae6d37b590d364bd94493fff7315f948d3d2ab904dc749ae5f2a" + "notices_sha256": "b0d1d248fc093fa50447549a5a7105f5aa458ca6e7e5e6844fad6f3a2e386c5d" } diff --git a/docs/release-attribution/0.8.0/README.md b/docs/release-attribution/0.8.0/README.md index 30f3a66f3..a8eed4dba 100644 --- a/docs/release-attribution/0.8.0/README.md +++ b/docs/release-attribution/0.8.0/README.md @@ -9,7 +9,9 @@ text. Validate with `node scripts/release/check-attribution.cjs`. The bundled JPEG codec retains both its license and incorporated IJG terms; the wrapper MIT text is pinned to the published crate's upstream VCS revision. Managed CPython archive notices remain a conservative superset, bound to the -checked provider/catalog evidence. These records establish attribution inputs, +checked provider/catalog evidence. Declared CPython license files that the +upstream archives omit come from separately labelled, hash-checked supplemental +texts in `scripts/release/licenses/managed-python-supplemental/`. These records establish attribution inputs, not native execution, signing, model quality or permission to publish a release. An S3-enabled build must use the [S3 profile](../0.8.0-s3/README.md). diff --git a/docs/release-attribution/0.8.0/THIRD-PARTY-NOTICES.txt b/docs/release-attribution/0.8.0/THIRD-PARTY-NOTICES.txt index c4dda3ff8..5f0595f4e 100644 --- a/docs/release-attribution/0.8.0/THIRD-PARTY-NOTICES.txt +++ b/docs/release-attribution/0.8.0/THIRD-PARTY-NOTICES.txt @@ -10,6 +10,10 @@ is recorded in the release attribution report, not inferred from this list. The uv notice covers a runtime executable downloaded by Pumas, not a bundled binary. Managed CPython full-archive notices are target-scoped supersets for separately selected install-only distributions; each archive identity is recorded below. +Where a CPython PYTHON.json declares a license file that its full archive omits, +a separately labelled supplemental notice reproduces that component's license +file from the source archive pinned by python-build-standalone; it is not an +archive member. adler2 2.0.1 (Rust normal/build dependency, all desktop targets; conservative superset) Source: https://crates.io/api/v1/crates/adler2/2.0.1/download @@ -79740,6 +79744,71 @@ docs/license.html_lib. jloup@gzip.org madler@alumni.caltech.edu +============================================================================== + +zlib-ng 2.2.4 (Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz +Declared license: Zlib +--- managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md --- +(C) 1995-2024 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. + + +============================================================================== + +zstd 1.5.7 (Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz +Declared license: BSD-3-Clause +--- managed-python-supplemental/zstd-1.5.7-LICENSE --- +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ============================================================================== CPython full archive 3.14.7 (Managed Python full-archive notice superset for x86_64-pc-windows-msvc; selected install-only runtime tracked separately) @@ -82314,6 +82383,44 @@ docs/license.html_lib. jloup@gzip.org madler@alumni.caltech.edu +============================================================================== + +zstd 1.5.7 (Managed Python supplemental license text for x86_64-pc-windows-msvc; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz +Declared license: BSD-3-Clause +--- managed-python-supplemental/zstd-1.5.7-LICENSE --- +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ============================================================================== CPython full archive 3.14.7 (Managed Python full-archive notice superset for x86_64-unknown-linux-gnu; selected install-only runtime tracked separately) @@ -84888,6 +84995,71 @@ docs/license.html_lib. jloup@gzip.org madler@alumni.caltech.edu +============================================================================== + +zlib-ng 2.2.4 (Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz +Declared license: Zlib +--- managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md --- +(C) 1995-2024 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. + + +============================================================================== + +zstd 1.5.7 (Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive) +Source: https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz +Declared license: BSD-3-Clause +--- managed-python-supplemental/zstd-1.5.7-LICENSE --- +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ============================================================================== uv 0.12.18 (Managed Python provider runtime executable downloaded by Pumas; not bundled) diff --git a/docs/release-attribution/0.8.0/inventory.json b/docs/release-attribution/0.8.0/inventory.json index 37b5d6f57..68e2089a3 100644 --- a/docs/release-attribution/0.8.0/inventory.json +++ b/docs/release-attribution/0.8.0/inventory.json @@ -7776,6 +7776,32 @@ } ] }, + { + "name": "zlib-ng", + "version": "2.2.4", + "license_declared": "Zlib", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz", + "scope": "Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee" + } + ] + }, + { + "name": "zstd", + "version": "1.5.7", + "license_declared": "BSD-3-Clause", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz", + "scope": "Managed Python supplemental license text for aarch64-apple-darwin; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8" + } + ] + }, { "name": "CPython full archive", "version": "3.14.7", @@ -7861,6 +7887,19 @@ } ] }, + { + "name": "zstd", + "version": "1.5.7", + "license_declared": "BSD-3-Clause", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz", + "scope": "Managed Python supplemental license text for x86_64-pc-windows-msvc; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8" + } + ] + }, { "name": "CPython full archive", "version": "3.14.7", @@ -7946,6 +7985,32 @@ } ] }, + { + "name": "zlib-ng", + "version": "2.2.4", + "license_declared": "Zlib", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz", + "scope": "Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zlib-ng.txt but the CPython full archive omits it; supplied from cpython-source-deps-zlib-ng-2.2.4/LICENSE.md in the source archive pinned by python-build-standalone 20260901 (sha256 00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee" + } + ] + }, + { + "name": "zstd", + "version": "1.5.7", + "license_declared": "BSD-3-Clause", + "source": "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz", + "scope": "Managed Python supplemental license text for x86_64-unknown-linux-gnu; PYTHON.json declares licenses/LICENSE.zstd.txt but the CPython full archive omits it; supplied from cpython-source-deps-zstd-1.5.7/LICENSE in the source archive pinned by python-build-standalone 20260901 (sha256 f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e), not from the CPython archive", + "texts": [ + { + "path": "managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8" + } + ] + }, { "name": "uv", "version": "0.12.18", @@ -8134,6 +8199,20 @@ "path": "docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/macos-arm64-cpython-3.14.7/managed-python-licenses/full-archive/licenses/LICENSE.zlib.txt", "sha256": "818922b2620f12801a12bf78e399644a30990e66824abd8ca8ec24d451d6f92c" } + ], + "supplemental_legal_files": [ + { + "declared_path": "licenses/LICENSE.zlib-ng.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee", + "provenance": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md.provenance.json" + }, + { + "declared_path": "licenses/LICENSE.zstd.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "provenance": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json" + } ] }, { @@ -8225,6 +8304,14 @@ "path": "docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/windows-x86_64-cpython-3.14.7/managed-python-licenses/full-archive/licenses/LICENSE.zlib.txt", "sha256": "365e36720db366054863235aea5d6f440142ab968834bfaf81fa9d187c99b9b8" } + ], + "supplemental_legal_files": [ + { + "declared_path": "licenses/LICENSE.zstd.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "provenance": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json" + } ] }, { @@ -8316,6 +8403,20 @@ "path": "docs/plans/torch-cross-platform-runtime-management/reports/managed-python-license-collection/linux-x86_64-cpython-3.14.7/managed-python-licenses/full-archive/licenses/LICENSE.zlib.txt", "sha256": "818922b2620f12801a12bf78e399644a30990e66824abd8ca8ec24d451d6f92c" } + ], + "supplemental_legal_files": [ + { + "declared_path": "licenses/LICENSE.zlib-ng.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md", + "sha256": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee", + "provenance": "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md.provenance.json" + }, + { + "declared_path": "licenses/LICENSE.zstd.txt", + "path": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE", + "sha256": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "provenance": "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json" + } ] } ], @@ -8397,7 +8498,11 @@ "rust/crates/pumas-rpc/Cargo.toml": "92b67b71767f6f495895c6d35a7c72107cfccc1cb60dedc400dd7f301a3a97f8", "scripts/release/artifact-plan.json": "66348a507f00ffdc74741fc7d70eab02f4a0eed4d3655354784cea2971662064", "scripts/release/licenses/managed-python-sources.json": "eabda4e2a25a92cfa8610865e79d11a50836930f53098efe89dd90778c4212ca", - "scripts/release/torch-managed-python-acceptance.py": "b0486387627d6ae98b4b6533adcceed93e93ebf868385626f3b13f1fb949893b" + "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md": "6c9f0d975b41afaa34d22f55bb8986ce69e5cb7ad327cb2b28820cd425edf5ee", + "scripts/release/licenses/managed-python-supplemental/zlib-ng-2.2.4-LICENSE.md.provenance.json": "3abbd4c93221c44bd33aa7012b5cd12bd1bce0a569768d076e820ee24959c10d", + "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE": "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8", + "scripts/release/licenses/managed-python-supplemental/zstd-1.5.7-LICENSE.provenance.json": "7b15e355b4839ed30f39267b47c3048902765f21805c9caa5099a7ab5301431d", + "scripts/release/torch-managed-python-acceptance.py": "2fe0e7a7727026690c67485a0aa072c07d728836b3ad0f8db4eb5ab3edb66198" }, - "notices_sha256": "9d050ff595057df42bcc67809a457e9b362dd286ed5b02ed218062d6ab0a570f" + "notices_sha256": "2d72871a68f29d50bbcee55091b624379b9e1c9b76a26b35116f5f309d533c39" } diff --git a/frontend/src/components/ModelCategoryControl.test.tsx b/frontend/src/components/ModelCategoryControl.test.tsx index 5538fb04d..ddab8e127 100644 --- a/frontend/src/components/ModelCategoryControl.test.tsx +++ b/frontend/src/components/ModelCategoryControl.test.tsx @@ -15,17 +15,60 @@ vi.mock('../api/models', () => ({ describe('ModelCategoryControl', () => { beforeEach(() => setModelCategoryMock.mockReset()); - it('records a chosen category and reports it as the person\'s choice', async () => { + it('saves only on Apply, so stepping through options records nothing', async () => { const onChanged = vi.fn(); setModelCategoryMock.mockResolvedValue({ success: true, model_id: 'llm/x/kev', category: 'decision' }); render(); - expect(screen.getByRole('combobox')).toHaveValue(''); - expect(screen.getByText('Detected: Language models')).toBeInTheDocument(); - fireEvent.change(screen.getByRole('combobox'), { target: { value: 'decision' } }); + const select = screen.getByRole('combobox', { name: 'Used as' }); + expect(select).toHaveValue(''); + expect(select).toHaveAccessibleDescription('Detected as Language models from the model files and source.'); + const apply = screen.getByRole('button', { name: 'Apply' }); + expect(apply).toBeDisabled(); - await waitFor(() => expect(onChanged).toHaveBeenCalledWith('decision', 'user')); + fireEvent.change(select, { target: { value: 'vision' } }); + fireEvent.change(select, { target: { value: 'decision' } }); + expect(setModelCategoryMock).not.toHaveBeenCalled(); + expect(select).not.toBeDisabled(); + + fireEvent.click(apply); + await waitFor(() => expect(onChanged).toHaveBeenCalledTimes(1)); + expect(setModelCategoryMock).toHaveBeenCalledTimes(1); expect(setModelCategoryMock).toHaveBeenCalledWith('llm/x/kev', 'decision'); + expect(screen.getByRole('status')).toHaveTextContent('Saved as Decision and evaluation.'); + }); + + const detected = { + modelId: 'llm/x/kev', category: 'llm', resolutionSource: 'model-type-resolver-arch-rules', + }; + + it('shows the category the backend saved once the metadata re-read arrives', async () => { + const onChanged = vi.fn(); + setModelCategoryMock.mockResolvedValue({ success: true, model_id: 'llm/x/kev', category: 'decision' }); + const { rerender } = render(); + const select = screen.getByRole('combobox', { name: 'Used as' }); + fireEvent.change(select, { target: { value: 'decision' } }); + fireEvent.click(screen.getByRole('button', { name: 'Apply' })); + await waitFor(() => expect(onChanged).toHaveBeenCalledTimes(1)); + + rerender(); + expect(select).toHaveValue('embedding'); + expect(screen.getByRole('button', { name: 'Apply' })).toBeDisabled(); + }); + + it('keeps a newer pick made while the metadata re-read is in flight', async () => { + const onChanged = vi.fn(); + setModelCategoryMock.mockResolvedValue({ success: true, model_id: 'llm/x/kev', category: 'decision' }); + const { rerender } = render(); + const select = screen.getByRole('combobox', { name: 'Used as' }); + fireEvent.change(select, { target: { value: 'decision' } }); + fireEvent.click(screen.getByRole('button', { name: 'Apply' })); + await waitFor(() => expect(onChanged).toHaveBeenCalledTimes(1)); + + fireEvent.change(select, { target: { value: 'vision' } }); + rerender(); + expect(select).toHaveValue('vision'); + expect(screen.getByRole('button', { name: 'Apply' })).toBeEnabled(); }); it('clears a choice to re-detect, and shows refusal reasons', async () => { @@ -33,9 +76,12 @@ describe('ModelCategoryControl', () => { setModelCategoryMock.mockRejectedValueOnce(new Error('category must be one of llm, vlm')); render(); - expect(screen.getByRole('combobox')).toHaveValue('vision'); - expect(screen.getByText('Chosen by you; re-scans keep it.')).toBeInTheDocument(); - fireEvent.change(screen.getByRole('combobox'), { target: { value: '' } }); + const select = screen.getByRole('combobox', { name: 'Used as' }); + expect(select).toHaveValue('vision'); + expect(screen.getByText('Chosen by you: Vision. Re-scans keep it.')).toBeInTheDocument(); + expect(screen.getByRole('option', { name: 'Detect automatically' })).toBeInTheDocument(); + fireEvent.change(select, { target: { value: '' } }); + fireEvent.click(screen.getByRole('button', { name: 'Apply' })); expect(await screen.findByRole('alert')).toHaveTextContent('category must be one of llm, vlm'); expect(setModelCategoryMock).toHaveBeenCalledWith('llm/x/kev', null); expect(onChanged).not.toHaveBeenCalled(); diff --git a/frontend/src/components/ModelCategoryControl.tsx b/frontend/src/components/ModelCategoryControl.tsx index f7325b00b..3c3ed5d98 100644 --- a/frontend/src/components/ModelCategoryControl.tsx +++ b/frontend/src/components/ModelCategoryControl.tsx @@ -2,6 +2,11 @@ * Choose what a model is used for. The choice is library metadata: the model * keeps its folder and ID, and later re-detection keeps the choice until it * is cleared. + * + * Picking an option does not save it; **Apply** does, so stepping through the + * options with the keyboard records nothing. The backend owns the result: after + * a save the parent re-reads the model's metadata, and the picker follows it + * unless the person has picked something else in the meantime. */ import { useState } from 'react'; @@ -19,7 +24,8 @@ interface ModelCategoryControlProps { modelId: string; category: string; resolutionSource: string | null; - onChanged: (category: string, resolutionSource: string | null) => void; + /** Called after the backend saved a change; re-read the model's metadata. */ + onChanged: () => void; } export function ModelCategoryControl({ @@ -28,16 +34,39 @@ export function ModelCategoryControl({ resolutionSource, onChanged, }: ModelCategoryControlProps) { + const chosen = resolutionSource === USER_CATEGORY_SOURCE; + const current = chosen ? category : DETECT; + const [pending, setPending] = useState(current); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); - const chosen = resolutionSource === USER_CATEGORY_SOURCE; + const [saved, setSaved] = useState(null); + const [synced, setSynced] = useState(current); + const [applied, setApplied] = useState(null); + + // The saved category arrives after Apply, from a separate metadata read. + // Follow it only when the picker still shows the previous or the applied + // value; a newer pick made while the read was in flight is kept. + if (current !== synced) { + setSynced(current); + setApplied(null); + if (pending === synced || pending === applied) { + setPending(current); + } + } - const choose = async (value: string) => { + const apply = async () => { setSaving(true); setError(null); + setSaved(null); + setApplied(pending); try { - const result = await modelsAPI.setModelCategory(modelId, value === DETECT ? null : value); - onChanged(result.category, value === DETECT ? null : USER_CATEGORY_SOURCE); + const result = await modelsAPI.setModelCategory(modelId, pending === DETECT ? null : pending); + setSaved( + pending === DETECT + ? `Detected as ${modelCategoryLabel(result.category)}.` + : `Saved as ${modelCategoryLabel(result.category)}.`, + ); + onChanged(); } catch (cause) { setError(cause instanceof Error && cause.message ? cause.message : 'The category could not be saved.'); } finally { @@ -45,29 +74,42 @@ export function ModelCategoryControl({ } }; + const selectId = `model-category-${modelId}`; + const hintId = `${selectId}-hint`; return (
-