+
+ {health && !health.mainHealthy && (
+ {health.mainError ?? t('mixer.outputMainUnavailable')}
+ )}
+ {health && !health.cueHealthy && (
+ {health.cueError ?? t('mixer.outputCueUnavailable')}
+ )}
+ {pollError && {pollError}}
+
+ {health?.canReconnect && (
+
+ )}
+
+ )
+}
diff --git a/justfile b/justfile
index 0ba2f6e..9426ceb 100644
--- a/justfile
+++ b/justfile
@@ -72,7 +72,12 @@ build:
# default `uv run` sidecar/generation commands use the backend project dir;
# override each command in dev, or point both at a freeze with LSDJ_BACKEND_BIN.
tauri-dev: build
- cd src-tauri && cargo tauri dev
+ cd src-tauri && cargo tauri dev --config tauri.macos.conf.json
+
+# Linux developer shell. Model services use source-tree overrides in dev; the
+# distributable AppImage instead compiles the fail-closed managed-runtime seam.
+tauri-linux-dev: build
+ cd src-tauri && cargo tauri dev --config tauri.linux.conf.json
# Freeze the shared Python backend into an ONEDIR binary for bundling
# (src-tauri/sidecar-dist/lsdj_backend). It serves deck inference, model tooling,
@@ -84,13 +89,20 @@ freeze-backend:
# Compatibility alias for the original packaging recipe name.
freeze-sidecar: freeze-backend
+# Resolve the separately bundled PyTorch/CUDA runtime without importing it into
+# the macOS MLX backend environment. These are installation candidates until
+# both clean-host installs and the NVIDIA qualification matrix pass.
+lock-mrt2-pytorch:
+ uv pip compile backend/mrt2-pytorch-runtime.in --python-version 3.12 --python-platform x86_64-unknown-linux-gnu --index https://download.pytorch.org/whl/cu130 --default-index https://pypi.org/simple --index-strategy unsafe-best-match --only-binary :all: --generate-hashes --output-file backend/runtime-locks/mrt2-pytorch-linux-x86_64.txt
+ uv pip compile backend/mrt2-pytorch-runtime.in --python-version 3.12 --python-platform x86_64-pc-windows-msvc --index https://download.pytorch.org/whl/cu130 --default-index https://pypi.org/simple --index-strategy unsafe-best-match --only-binary :all: --generate-hashes --output-file backend/runtime-locks/mrt2-pytorch-windows-x86_64.txt
+
# Native shell developer bundle: build the app/DMG into
# src-tauri/target/release/bundle/. The config applies an explicit ad-hoc
# signature so the app bundle is structurally valid on Apple Silicon. This is
# useful for local testing only; use `just tauri-release` for anything sent to
# another Mac.
tauri-build: build
- cd src-tauri && cargo tauri build
+ cd src-tauri && cargo tauri build --config tauri.macos.conf.json
# Distributable macOS build. Fails closed unless a Developer ID Application
# identity and Apple notarization credentials are configured, then verifies the
@@ -98,9 +110,17 @@ tauri-build: build
tauri-release:
./scripts/build-macos-release.sh
+# Linux x86_64 AppImage built on an Ubuntu 22.04-compatible host. Model
+# runtimes remain app-managed and fail closed until their verified #110/#111
+# adapters supply explicit executables; no packaged path invokes developer
+# Python/uv/Git/shell tooling.
+tauri-linux-release:
+ ./scripts/build-linux-appimage.sh
+
# Create and push the next protected vYYYY.MM.N tag from a clean, current main.
# Remote calendar-version tags are the ledger; no version file or bump is needed.
-# The tag starts the macOS signing workflow and its Engineering approval gate.
+# The tag starts the three-platform release workflow; macOS and Windows signing
+# remain behind their protected Engineering approval gates.
release:
./scripts/create-release.sh
diff --git a/mrt2-pytorch-pin.json b/mrt2-pytorch-pin.json
new file mode 100644
index 0000000..b5e138e
--- /dev/null
+++ b/mrt2-pytorch-pin.json
@@ -0,0 +1,97 @@
+{
+ "schemaVersion": 1,
+ "runtime": {
+ "python": [
+ {
+ "target":"x86_64-unknown-linux-gnu",
+ "version":"3.12.13",
+ "url":"https://github.com/astral-sh/python-build-standalone/releases/download/20260807/cpython-3.12.13%2B20260807-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz",
+ "size":34163738,
+ "sha256":"506191be3ee7bd190a8834dcdc1b3bc70aab50608deccc711935aa007239cabd",
+ "archiveRoot":"python",
+ "executable":"bin/python3",
+ "maxFiles":12000,
+ "maxExpandedBytes":536870912
+ },
+ {
+ "target":"x86_64-pc-windows-msvc",
+ "version":"3.12.13",
+ "url":"https://github.com/astral-sh/python-build-standalone/releases/download/20260807/cpython-3.12.13%2B20260807-x86_64-pc-windows-msvc-install_only_stripped.tar.gz",
+ "size":21962247,
+ "sha256":"18bcc65b17921806b72cdc88bcf000bf67a2c99a8fc381fe1629f2b9ba56858d",
+ "archiveRoot":"python",
+ "executable":"python.exe",
+ "maxFiles":12000,
+ "maxExpandedBytes":536870912
+ }
+ ],
+ "uv": [
+ {
+ "target":"x86_64-unknown-linux-gnu","version":"0.11.7",
+ "url":"https://github.com/astral-sh/uv/releases/download/0.11.7/uv-x86_64-unknown-linux-gnu.tar.gz",
+ "size":24249861,"sha256":"6681d691eb7f9c00ac6a3af54252f7ab29ae72f0c8f95bdc7f9d1401c23ea868",
+ "archiveRoot":"uv-x86_64-unknown-linux-gnu","executable":"uv","maxFiles":8,"maxExpandedBytes":67108864
+ },
+ {
+ "target":"x86_64-pc-windows-msvc","version":"0.11.7",
+ "url":"https://github.com/astral-sh/uv/releases/download/0.11.7/uv-x86_64-pc-windows-msvc.zip",
+ "size":23572531,"sha256":"fe0c7815acf4fc45f8a5eff58ed3cf7ae2e15c3cf1dceadbd10c816ec1690cc1",
+ "archiveRoot":"uv-x86_64-pc-windows-msvc","archiveFormat":"zip","executable":"uv.exe","maxFiles":8,"maxExpandedBytes":67108864
+ }
+ ],
+ "locks": {
+ "x86_64-unknown-linux-gnu":"4749398e83c72359f04081f6c0090461cec823a67845766410b7b49ae55b1785",
+ "x86_64-pc-windows-msvc":"63c86af3d4ee0efe70318539272288cb193a38a7af4096ae7c12ec2c48e5b7dc"
+ },
+ "wheelManifestSha256":"9dfd22a3f751831fcc1aaf457372d68838fd7432657dbdba2e43a8384f79b701"
+ },
+ "models": {
+ "mrt2_small": {
+ "repository": "magenta-community/magenta-realtime-2-small",
+ "revision": "7037d99551c84ac5c6afb7f1a5e58c65e7233dbb",
+ "files": [
+ {"path":"aoti.py","size":5953,"sha256":"52056e706de328df3a12637b359ce349bacdfb9793cc57ddcc756e62e4b66c86"},
+ {"path":"codec_shapes.json","size":2824,"sha256":"5df62019bd7c0f7428b34005b7de2691e8396989d98b6a295948655f13d410f5"},
+ {"path":"config.json","size":6151,"sha256":"88100af0e4a9bcb8462ce1145d902983cbdcd5ac8b9ade496aca1ad6d42109c8"},
+ {"path":"configuration_magenta_rt2.py","size":4085,"sha256":"9fdbd0564174b1f7a7b71735ab310ecd64846a08d2d006becf77301b13a1190e"},
+ {"path":"cudagraph.py","size":8624,"sha256":"68f53fe2b8578f37a6730e2c78622712b099d8d31014b946a08ab86fca15be3f"},
+ {"path":"depthformer.py","size":17995,"sha256":"36e10c6206b66992ae75c94c0f4859007e6deb8a4f7a451dee20736e358b13a7"},
+ {"path":"layers.py","size":14432,"sha256":"ea328a1f4c9a8ed2cbdabe801e5f976f2437ea8cf6c4978dcbcf09558b4644ef"},
+ {"path":"model.safetensors","size":1128837704,"sha256":"da0146d5c442f16006fde3721f7ce6584e4c8f96024887a990f36bac46a625f5"},
+ {"path":"modeling_magenta_rt2.py","size":26862,"sha256":"ea3bfbc9e998de706f36c956a8e59ea4f6313663279d5e814934e1e5668336fb"},
+ {"path":"musiccoca.py","size":8064,"sha256":"b134f8db41ef0212929fc6377812b961dcf042a0cf4aa8344a9640796635625b"},
+ {"path":"processing_musiccoca.py","size":3154,"sha256":"8293875ebac4221dcfcbfe4c795302fcf9c5360c43fb609729cb170e1199a1ef"},
+ {"path":"spectrostream.py","size":14917,"sha256":"0cd124454bda9a1ee01c33077e6c506a65e827d87b4ef01c481b86776001dfbe"}
+ ]
+ },
+ "mrt2_base": {
+ "repository": "magenta-community/magenta-realtime-2",
+ "revision": "92087988d05d0fe38b11f021f0b0d00a75afb86b",
+ "files": [
+ {"path":"aoti.py","size":5953,"sha256":"52056e706de328df3a12637b359ce349bacdfb9793cc57ddcc756e62e4b66c86"},
+ {"path":"codec_shapes.json","size":2824,"sha256":"5df62019bd7c0f7428b34005b7de2691e8396989d98b6a295948655f13d410f5"},
+ {"path":"config.json","size":6153,"sha256":"8c89a1cfe10e9f4618aded3f29d64a49aefd51e0bafd9a1aac0b26a5628e7530"},
+ {"path":"configuration_magenta_rt2.py","size":4085,"sha256":"9fdbd0564174b1f7a7b71735ab310ecd64846a08d2d006becf77301b13a1190e"},
+ {"path":"cudagraph.py","size":8624,"sha256":"68f53fe2b8578f37a6730e2c78622712b099d8d31014b946a08ab86fca15be3f"},
+ {"path":"depthformer.py","size":17995,"sha256":"36e10c6206b66992ae75c94c0f4859007e6deb8a4f7a451dee20736e358b13a7"},
+ {"path":"layers.py","size":14432,"sha256":"ea328a1f4c9a8ed2cbdabe801e5f976f2437ea8cf6c4978dcbcf09558b4644ef"},
+ {"path":"model.safetensors","size":9836752784,"sha256":"045ac86f5be520d37020c94ef13cad3a84e336f18d82166748fd6b36a305540e"},
+ {"path":"modeling_magenta_rt2.py","size":26862,"sha256":"ea3bfbc9e998de706f36c956a8e59ea4f6313663279d5e814934e1e5668336fb"},
+ {"path":"musiccoca.py","size":8064,"sha256":"b134f8db41ef0212929fc6377812b961dcf042a0cf4aa8344a9640796635625b"},
+ {"path":"processing_musiccoca.py","size":3154,"sha256":"8293875ebac4221dcfcbfe4c795302fcf9c5360c43fb609729cb170e1199a1ef"},
+ {"path":"spectrostream.py","size":14917,"sha256":"0cd124454bda9a1ee01c33077e6c506a65e827d87b4ef01c481b86776001dfbe"}
+ ]
+ }
+ },
+ "processor": {
+ "repository": "magenta-community/magenta-rt-musiccoca-torch",
+ "revision": "236c488e38aa98643805514996934d705668298b",
+ "files": [
+ {"path":"mel_params.npz","size":526388,"sha256":"8dbeb3747e1ad349c771f6bed5b1600f2be6fb361d82e996bc992d8d7e061d97"},
+ {"path":"music_encoder.pt","size":371441867,"sha256":"97af5b160739e7699c67217049e5c35d9fa95a9abaa19debc0c52ea46c0ca8de"},
+ {"path":"quantizer.pt","size":72678385,"sha256":"090e8ebab0a817d21833ca048a6ab9c3782c51890068d85d9fb14115aa1d79cf"},
+ {"path":"spm.model","size":517448,"sha256":"ff325a99b61ba5726cf6437cde6eefbb633dbaa363a684f7a97ed99b55202cca"},
+ {"path":"text_encoder.pt","size":419819353,"sha256":"d23093557e151d9cf9bdea5320434b5d5f441386d870577fc741ec5609ba5618"}
+ ]
+ }
+}
diff --git a/mrt2-pytorch-wheels.json b/mrt2-pytorch-wheels.json
new file mode 100644
index 0000000..10e7ef9
--- /dev/null
+++ b/mrt2-pytorch-wheels.json
@@ -0,0 +1,762 @@
+{
+ "schemaVersion": 1,
+ "python": "3.12",
+ "targets": {
+ "x86_64-unknown-linux-gnu": [
+ {
+ "package": "annotated-doc",
+ "version": "0.0.5",
+ "filename": "annotated_doc-0.0.5-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl",
+ "size": 5302,
+ "sha256": "117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101"
+ },
+ {
+ "package": "anyio",
+ "version": "4.14.2",
+ "filename": "anyio-4.14.2-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl",
+ "size": 125813,
+ "sha256": "9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494"
+ },
+ {
+ "package": "certifi",
+ "version": "2026.7.22",
+ "filename": "certifi-2026.7.22-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl",
+ "size": 136983,
+ "sha256": "62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775"
+ },
+ {
+ "package": "cuda-bindings",
+ "version": "13.3.1",
+ "filename": "cuda_bindings-13.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/39/2a/6d2e9047d1fb243dbaa364b01e0297534b9ed7fd27dba1c9f361519cf69b/cuda_bindings-13.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl",
+ "size": 6657965,
+ "sha256": "e32d08f71ebcdf00f0f41eab2eb37e8da94c8ed411cc9f7f7a019ce6b34abe3a"
+ },
+ {
+ "package": "cuda-pathfinder",
+ "version": "1.6.0",
+ "filename": "cuda_pathfinder-1.6.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/fc/b4/d088047afe39827556df21118cac9ffd20cc3f968c99a7681494d1eb333c/cuda_pathfinder-1.6.0-py3-none-any.whl",
+ "size": 54591,
+ "sha256": "1503af579d8379c24bdd65528379bc57039b0455be9f5f9686cf8e473a1fce51"
+ },
+ {
+ "package": "cuda-toolkit",
+ "version": "13.0.2",
+ "filename": "cuda_toolkit-13.0.2-py2.py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/57/b2/453099f5f3b698d7d0eab38916aac44c7f76229f451709e2eb9db6615dcd/cuda_toolkit-13.0.2-py2.py3-none-any.whl",
+ "size": 2364,
+ "sha256": "b198824cf2f54003f50d64ada3a0f184b42ca0846c1c94192fa269ecd97a66eb"
+ },
+ {
+ "package": "filelock",
+ "version": "3.32.2",
+ "filename": "filelock-3.32.2-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/c1/e8/72f8cef9fdfeffe06213fe8508039396ee48daa0e3259457ed766173bfd6/filelock-3.32.2-py3-none-any.whl",
+ "size": 98830,
+ "sha256": "87dd94cf281e586d135fa51132b8e3d9a598b316e90377a288663c9321036c82"
+ },
+ {
+ "package": "fsspec",
+ "version": "2026.7.0",
+ "filename": "fsspec-2026.7.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/fd/3c/6a2bf344106328fd04963664a60b9bb6496fc25df8e962fcdc1367285fb9/fsspec-2026.7.0-py3-none-any.whl",
+ "size": 206583,
+ "sha256": "b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279"
+ },
+ {
+ "package": "h11",
+ "version": "0.16.0",
+ "filename": "h11-0.16.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl",
+ "size": 37515,
+ "sha256": "63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"
+ },
+ {
+ "package": "hf-xet",
+ "version": "1.6.0",
+ "filename": "hf_xet-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/67/4e/a28359bf1c1ecf11eba22123168c138698f7cb576ac678f5a2e16cd5da08/hf_xet-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 4464663,
+ "sha256": "d62671bb130879cef0ee4c9ebe47a14af6c66ec53e6d84dc15936e5ffdfac82f"
+ },
+ {
+ "package": "httpcore",
+ "version": "1.0.9",
+ "filename": "httpcore-1.0.9-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl",
+ "size": 78784,
+ "sha256": "2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"
+ },
+ {
+ "package": "httpx",
+ "version": "0.28.1",
+ "filename": "httpx-0.28.1-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl",
+ "size": 73517,
+ "sha256": "d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"
+ },
+ {
+ "package": "huggingface-hub",
+ "version": "1.5.0",
+ "filename": "huggingface_hub-1.5.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/ec/74/2bc951622e2dbba1af9a460d93c51d15e458becd486e62c29cc0ccb08178/huggingface_hub-1.5.0-py3-none-any.whl",
+ "size": 596261,
+ "sha256": "c9c0b3ab95a777fc91666111f3b3ede71c0cdced3614c553a64e98920585c4ee"
+ },
+ {
+ "package": "idna",
+ "version": "3.18",
+ "filename": "idna-3.18-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl",
+ "size": 65455,
+ "sha256": "7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2"
+ },
+ {
+ "package": "jinja2",
+ "version": "3.1.6",
+ "filename": "jinja2-3.1.6-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl",
+ "size": 134899,
+ "sha256": "85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"
+ },
+ {
+ "package": "llvmlite",
+ "version": "0.48.0",
+ "filename": "llvmlite-0.48.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/80/f2/72409351db66d0a317ec5087e076f31fb7b773a640db8a90ce6b5cac9edd/llvmlite-0.48.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 59890118,
+ "sha256": "416fa4c2c66c2c6dc6d0a402648c19206e548efa0aa1eff01ad5cdad0af8217d"
+ },
+ {
+ "package": "markdown-it-py",
+ "version": "4.2.0",
+ "filename": "markdown_it_py-4.2.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl",
+ "size": 91687,
+ "sha256": "9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a"
+ },
+ {
+ "package": "markupsafe",
+ "version": "3.0.3",
+ "filename": "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
+ "size": 22947,
+ "sha256": "d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"
+ },
+ {
+ "package": "mdurl",
+ "version": "0.1.2",
+ "filename": "mdurl-0.1.2-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl",
+ "size": 9979,
+ "sha256": "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"
+ },
+ {
+ "package": "mpmath",
+ "version": "1.3.0",
+ "filename": "mpmath-1.3.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl",
+ "size": 536198,
+ "sha256": "a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"
+ },
+ {
+ "package": "networkx",
+ "version": "3.6.1",
+ "filename": "networkx-3.6.1-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl",
+ "size": 2068504,
+ "sha256": "d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762"
+ },
+ {
+ "package": "numba",
+ "version": "0.66.0",
+ "filename": "numba-0.66.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/2d/55/25c319845e9a4e08f16611ddbda56a192eb7b6ed13e1a2bff2da272ffb97/numba-0.66.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 3866252,
+ "sha256": "0999e3ee1b18c48e1fb51d11af35ef59852c7f4f50569c9550c25faef0616ad1"
+ },
+ {
+ "package": "numpy",
+ "version": "2.3.5",
+ "filename": "numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
+ "size": 16606086,
+ "sha256": "0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28"
+ },
+ {
+ "package": "nvidia-cublas",
+ "version": "13.1.1.3",
+ "filename": "nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/3b/cd/154ca20c38269e05eff77c1464e6c1da89f50a6390b565e9d82e06bc11e1/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_x86_64.whl",
+ "size": 423138758,
+ "sha256": "37936a16db8fe4ac1f065c2139360608a543a09275cb1a1af612e08cfa065436"
+ },
+ {
+ "package": "nvidia-cuda-cupti",
+ "version": "13.0.85",
+ "filename": "nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/33/6d/737d164b4837a9bbd202f5ae3078975f0525a55730fe871d8ed4e3b952b0/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_x86_64.whl",
+ "size": 10715597,
+ "sha256": "4eb01c08e859bf924d222250d2e8f8b8ff6d3db4721288cf35d14252a4d933c8"
+ },
+ {
+ "package": "nvidia-cuda-nvrtc",
+ "version": "13.0.88",
+ "filename": "nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/c3/68/483a78f5e8f31b08fb1bb671559968c0ca3a065ac7acabfc7cee55214fd6/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl",
+ "size": 90215200,
+ "sha256": "ad9b6d2ead2435f11cbb6868809d2adeeee302e9bb94bcf0539c7a40d80e8575"
+ },
+ {
+ "package": "nvidia-cuda-runtime",
+ "version": "13.0.96",
+ "filename": "nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/2e/24/d1558f3b68b1d26e706813b1d10aa1d785e4698c425af8db8edc3dced472/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 2243632,
+ "sha256": "7f82250d7782aa23b6cfe765ecc7db554bd3c2870c43f3d1821f1d18aebf0548"
+ },
+ {
+ "package": "nvidia-cudnn-cu13",
+ "version": "9.20.0.48",
+ "filename": "nvidia_cudnn_cu13-9.20.0.48-py3-none-manylinux_2_27_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/6e/5e/edb9c0ae051602c3ccaffe424256463636d639e27d7f302dde9975ef9e7a/nvidia_cudnn_cu13-9.20.0.48-py3-none-manylinux_2_27_x86_64.whl",
+ "size": 366173588,
+ "sha256": "0c45dd8eeb50b603f07995b1b300c62ffe6a1980482b82b3bcf94a4ca9d49304"
+ },
+ {
+ "package": "nvidia-cufft",
+ "version": "12.0.0.61",
+ "filename": "nvidia_cufft-12.0.0.61-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/a8/2f/7b57e29836ea8714f81e9898409196f47d772d5ddedddf1592eadb8ab743/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 214085489,
+ "sha256": "6c44f692dce8fd5ffd3e3df134b6cdb9c2f72d99cf40b62c32dde45eea9ddad3"
+ },
+ {
+ "package": "nvidia-cufile",
+ "version": "1.15.1.6",
+ "filename": "nvidia_cufile-1.15.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/3f/70/4f193de89a48b71714e74602ee14d04e4019ad36a5a9f20c425776e72cd6/nvidia_cufile-1.15.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 1223672,
+ "sha256": "08a3ecefae5a01c7f5117351c64f17c7c62efa5fffdbe24fc7d298da19cd0b44"
+ },
+ {
+ "package": "nvidia-curand",
+ "version": "10.4.0.35",
+ "filename": "nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/a5/9f/be0a41ca4a4917abf5cb9ae0daff1a6060cc5de950aec0396de9f3b52bc5/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_x86_64.whl",
+ "size": 59544258,
+ "sha256": "1aee33a5da6e1db083fe2b90082def8915f30f3248d5896bcec36a579d941bfc"
+ },
+ {
+ "package": "nvidia-cusolver",
+ "version": "12.0.4.66",
+ "filename": "nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/5f/67/cba3777620cdacb99102da4042883709c41c709f4b6323c10781a9c3aa34/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_x86_64.whl",
+ "size": 200941980,
+ "sha256": "0a759da5dea5c0ea10fd307de75cdeb59e7ea4fcb8add0924859b944babf1112"
+ },
+ {
+ "package": "nvidia-cusparse",
+ "version": "12.6.3.3",
+ "filename": "nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/fa/18/623c77619c31d62efd55302939756966f3ecc8d724a14dab2b75f1508850/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 145942937,
+ "sha256": "2b3c89c88d01ee0e477cb7f82ef60a11a4bcd57b6b87c33f789350b59759360b"
+ },
+ {
+ "package": "nvidia-cusparselt-cu13",
+ "version": "0.8.1",
+ "filename": "nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/34/7d/2661f2fb3ac4302f3a246f5fc030213ac60c1fe0bce84f9783dbd831dbb7/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_x86_64.whl",
+ "size": 170148586,
+ "sha256": "786ce87568c303fadb5afcc7102d454cd3040d75f6f8626f5db460d1871f4dd0"
+ },
+ {
+ "package": "nvidia-nccl-cu13",
+ "version": "2.29.7",
+ "filename": "nvidia_nccl_cu13-2.29.7-py3-none-manylinux_2_18_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/67/f4/58e4e91b6919367c7aafb8e36fce9aad1a3047e536bf7e2fd560927d3a4c/nvidia_nccl_cu13-2.29.7-py3-none-manylinux_2_18_x86_64.whl",
+ "size": 205976000,
+ "sha256": "edd81538446786ec3b73972543e53bb43bcaf0bfc8ef76cb679fcc390ffe136d"
+ },
+ {
+ "package": "nvidia-nvjitlink",
+ "version": "13.0.88",
+ "filename": "nvidia_nvjitlink-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/56/7a/123e033aaff487c77107195fa5a2b8686795ca537935a24efae476c41f05/nvidia_nvjitlink-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl",
+ "size": 40713933,
+ "sha256": "13a74f429e23b921c1109976abefacc69835f2f433ebd323d3946e11d804e47b"
+ },
+ {
+ "package": "nvidia-nvshmem-cu13",
+ "version": "3.4.5",
+ "filename": "nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/3c/35/a9bf80a609e74e3b000fef598933235c908fcefcef9026042b8e6dfde2a9/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
+ "size": 60412546,
+ "sha256": "290f0a2ee94c9f3687a02502f3b9299a9f9fe826e6d0287ee18482e78d495b80"
+ },
+ {
+ "package": "nvidia-nvtx",
+ "version": "13.0.85",
+ "filename": "nvidia_nvtx-13.0.85-py3-none-manylinux1_x86_64.manylinux_2_5_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/c2/f3/d86c845465a2723ad7e1e5c36dcd75ddb82898b3f53be47ebd429fb2fa5d/nvidia_nvtx-13.0.85-py3-none-manylinux1_x86_64.manylinux_2_5_x86_64.whl",
+ "size": 148047,
+ "sha256": "4936d1d6780fbe68db454f5e72a42ff64d1fd6397df9f363ae786930fd5c1cd4"
+ },
+ {
+ "package": "packaging",
+ "version": "26.3",
+ "filename": "packaging-26.3-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl",
+ "size": 129956,
+ "sha256": "d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c"
+ },
+ {
+ "package": "pygments",
+ "version": "2.20.0",
+ "filename": "pygments-2.20.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl",
+ "size": 1231151,
+ "sha256": "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"
+ },
+ {
+ "package": "pyyaml",
+ "version": "6.0.3",
+ "filename": "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
+ "size": 807870,
+ "sha256": "ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"
+ },
+ {
+ "package": "regex",
+ "version": "2026.7.19",
+ "filename": "regex-2026.7.19-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/2a/8e/096d00c7c480ef2ff4265349b14e2261d4ab787ba1f74e2e80d1c58079c3/regex-2026.7.19-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
+ "size": 801798,
+ "sha256": "9dce8ec9695f531a1b8a6f314fd4b393adcccf2ea861db480cdf97a301d01a68"
+ },
+ {
+ "package": "resampy",
+ "version": "0.4.3",
+ "filename": "resampy-0.4.3-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/4d/b9/3b00ac340a1aab3389ebcc52c779914a44aadf7b0cb7a3bf053195735607/resampy-0.4.3-py3-none-any.whl",
+ "size": 3076529,
+ "sha256": "ad2ed64516b140a122d96704e32bc0f92b23f45419e8b8f478e5a05f83edcebd"
+ },
+ {
+ "package": "rich",
+ "version": "15.0.0",
+ "filename": "rich-15.0.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl",
+ "size": 310654,
+ "sha256": "33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb"
+ },
+ {
+ "package": "safetensors",
+ "version": "0.7.0",
+ "filename": "safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/a0/60/429e9b1cb3fc651937727befe258ea24122d9663e4d5709a48c9cbfceecb/safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
+ "size": 507152,
+ "sha256": "dac7252938f0696ddea46f5e855dd3138444e82236e3be475f54929f0c510d48"
+ },
+ {
+ "package": "sentencepiece",
+ "version": "0.2.1",
+ "filename": "sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/04/88/14f2f4a2b922d8b39be45bf63d79e6cd3a9b2f248b2fcb98a69b12af12f5/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
+ "size": 1387881,
+ "sha256": "0cdfecef430d985f1c2bcbfff3defd1d95dae876fbd0173376012d2d7d24044b"
+ },
+ {
+ "package": "setuptools",
+ "version": "81.0.0",
+ "filename": "setuptools-81.0.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl",
+ "size": 1062021,
+ "sha256": "fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6"
+ },
+ {
+ "package": "shellingham",
+ "version": "1.5.4",
+ "filename": "shellingham-1.5.4-py2.py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl",
+ "size": 9755,
+ "sha256": "7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"
+ },
+ {
+ "package": "sympy",
+ "version": "1.14.0",
+ "filename": "sympy-1.14.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl",
+ "size": 6299353,
+ "sha256": "e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5"
+ },
+ {
+ "package": "tokenizers",
+ "version": "0.22.2",
+ "filename": "tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
+ "size": 3274982,
+ "sha256": "369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67"
+ },
+ {
+ "package": "torch",
+ "version": "2.12.1+cu130",
+ "filename": "torch-2.12.1+cu130-cp312-cp312-manylinux_2_28_x86_64.whl",
+ "url": "https://download-r2.pytorch.org/whl/cu130/torch-2.12.1%2Bcu130-cp312-cp312-manylinux_2_28_x86_64.whl",
+ "size": 532716184,
+ "sha256": "4bafc356fbb622e2756179406825c3a56c17b401196435a1487c5b40c657706c"
+ },
+ {
+ "package": "tqdm",
+ "version": "4.70.0",
+ "filename": "tqdm-4.70.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/f9/1c/01bfd571a64e7f270e6bab5e33777debe0edc56759233ce84f27dec92d14/tqdm-4.70.0-py3-none-any.whl",
+ "size": 80184,
+ "sha256": "7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953"
+ },
+ {
+ "package": "transformers",
+ "version": "5.8.0",
+ "filename": "transformers-5.8.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/97/7b/5621d08b34ac35deb9fa14b58d27d124d21ef125ee1c64bc724ca47dfb63/transformers-5.8.0-py3-none-any.whl",
+ "size": 10630279,
+ "sha256": "e9d2cae6d195a7e1e05164c5ebf26142a7044e4dc4267274f4809204f92827e4"
+ },
+ {
+ "package": "triton",
+ "version": "3.7.1",
+ "filename": "triton-3.7.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
+ "url": "https://files.pythonhosted.org/packages/c4/6f/fb96d15db6f36d6eae4cafb998c2e0353bf59d7c4ea1662d7497f269134a/triton-3.7.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl",
+ "size": 197719725,
+ "sha256": "7e40869937a68206ec70d7f25bb7ec6433cb083f9135e1f36dbd318dc449a728"
+ },
+ {
+ "package": "typer",
+ "version": "0.27.1",
+ "filename": "typer-0.27.1-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/43/89/9518bc0c3929bee36b3a4a8e3daddd6e03f92f9961c66d4983b837160543/typer-0.27.1-py3-none-any.whl",
+ "size": 122874,
+ "sha256": "53150287edd11baeb4e4722c8e394fcdf8181c0ae89485cba8d25c778d5edd56"
+ },
+ {
+ "package": "typing-extensions",
+ "version": "4.16.0",
+ "filename": "typing_extensions-4.16.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl",
+ "size": 45571,
+ "sha256": "481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8"
+ }
+ ],
+ "x86_64-pc-windows-msvc": [
+ {
+ "package": "annotated-doc",
+ "version": "0.0.5",
+ "filename": "annotated_doc-0.0.5-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl",
+ "size": 5302,
+ "sha256": "117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101"
+ },
+ {
+ "package": "anyio",
+ "version": "4.14.2",
+ "filename": "anyio-4.14.2-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl",
+ "size": 125813,
+ "sha256": "9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494"
+ },
+ {
+ "package": "certifi",
+ "version": "2026.7.22",
+ "filename": "certifi-2026.7.22-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl",
+ "size": 136983,
+ "sha256": "62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775"
+ },
+ {
+ "package": "colorama",
+ "version": "0.4.6",
+ "filename": "colorama-0.4.6-py2.py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl",
+ "size": 25335,
+ "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"
+ },
+ {
+ "package": "filelock",
+ "version": "3.32.2",
+ "filename": "filelock-3.32.2-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/c1/e8/72f8cef9fdfeffe06213fe8508039396ee48daa0e3259457ed766173bfd6/filelock-3.32.2-py3-none-any.whl",
+ "size": 98830,
+ "sha256": "87dd94cf281e586d135fa51132b8e3d9a598b316e90377a288663c9321036c82"
+ },
+ {
+ "package": "fsspec",
+ "version": "2026.7.0",
+ "filename": "fsspec-2026.7.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/fd/3c/6a2bf344106328fd04963664a60b9bb6496fc25df8e962fcdc1367285fb9/fsspec-2026.7.0-py3-none-any.whl",
+ "size": 206583,
+ "sha256": "b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279"
+ },
+ {
+ "package": "h11",
+ "version": "0.16.0",
+ "filename": "h11-0.16.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl",
+ "size": 37515,
+ "sha256": "63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"
+ },
+ {
+ "package": "hf-xet",
+ "version": "1.6.0",
+ "filename": "hf_xet-1.6.0-cp38-abi3-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/98/b7/8c59a66d15205024662f1d66968136f13893f96df1ddc5087e2e281fc95f/hf_xet-1.6.0-cp38-abi3-win_amd64.whl",
+ "size": 4033128,
+ "sha256": "fb4fadde1b2b70bf4c0c14a6dccbe7194b1c28947fefd5bbe3fed9d940676c3b"
+ },
+ {
+ "package": "httpcore",
+ "version": "1.0.9",
+ "filename": "httpcore-1.0.9-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl",
+ "size": 78784,
+ "sha256": "2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"
+ },
+ {
+ "package": "httpx",
+ "version": "0.28.1",
+ "filename": "httpx-0.28.1-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl",
+ "size": 73517,
+ "sha256": "d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"
+ },
+ {
+ "package": "huggingface-hub",
+ "version": "1.5.0",
+ "filename": "huggingface_hub-1.5.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/ec/74/2bc951622e2dbba1af9a460d93c51d15e458becd486e62c29cc0ccb08178/huggingface_hub-1.5.0-py3-none-any.whl",
+ "size": 596261,
+ "sha256": "c9c0b3ab95a777fc91666111f3b3ede71c0cdced3614c553a64e98920585c4ee"
+ },
+ {
+ "package": "idna",
+ "version": "3.18",
+ "filename": "idna-3.18-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl",
+ "size": 65455,
+ "sha256": "7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2"
+ },
+ {
+ "package": "jinja2",
+ "version": "3.1.6",
+ "filename": "jinja2-3.1.6-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl",
+ "size": 134899,
+ "sha256": "85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"
+ },
+ {
+ "package": "llvmlite",
+ "version": "0.48.0",
+ "filename": "llvmlite-0.48.0-cp312-cp312-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/16/78/d824ffff7521cd140dc2006e44ce2bc82e64b48d1b32e90e956308c85a74/llvmlite-0.48.0-cp312-cp312-win_amd64.whl",
+ "size": 41865022,
+ "sha256": "d45c7541a80934ec6d8ab0defe67439494ecd2193cbf852a44ba827808976ac1"
+ },
+ {
+ "package": "markdown-it-py",
+ "version": "4.2.0",
+ "filename": "markdown_it_py-4.2.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl",
+ "size": 91687,
+ "sha256": "9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a"
+ },
+ {
+ "package": "markupsafe",
+ "version": "3.0.3",
+ "filename": "markupsafe-3.0.3-cp312-cp312-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl",
+ "size": 15105,
+ "sha256": "26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"
+ },
+ {
+ "package": "mdurl",
+ "version": "0.1.2",
+ "filename": "mdurl-0.1.2-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl",
+ "size": 9979,
+ "sha256": "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"
+ },
+ {
+ "package": "mpmath",
+ "version": "1.3.0",
+ "filename": "mpmath-1.3.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl",
+ "size": 536198,
+ "sha256": "a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"
+ },
+ {
+ "package": "networkx",
+ "version": "3.6.1",
+ "filename": "networkx-3.6.1-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl",
+ "size": 2068504,
+ "sha256": "d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762"
+ },
+ {
+ "package": "numba",
+ "version": "0.66.0",
+ "filename": "numba-0.66.0-cp312-cp312-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/fc/eb/9e6171e378822ab191c7abcfd3d8cfc8644516f6c7834c22e210e4acc070/numba-0.66.0-cp312-cp312-win_amd64.whl",
+ "size": 2797403,
+ "sha256": "b075a4e7ebc43dc6294f223e2821659656209fd5e0ce53245877c23d66d6e1a9"
+ },
+ {
+ "package": "numpy",
+ "version": "2.3.5",
+ "filename": "numpy-2.3.5-cp312-cp312-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl",
+ "size": 12782922,
+ "sha256": "86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa"
+ },
+ {
+ "package": "packaging",
+ "version": "26.3",
+ "filename": "packaging-26.3-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl",
+ "size": 129956,
+ "sha256": "d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c"
+ },
+ {
+ "package": "pygments",
+ "version": "2.20.0",
+ "filename": "pygments-2.20.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl",
+ "size": 1231151,
+ "sha256": "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"
+ },
+ {
+ "package": "pyyaml",
+ "version": "6.0.3",
+ "filename": "pyyaml-6.0.3-cp312-cp312-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl",
+ "size": 154003,
+ "sha256": "5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"
+ },
+ {
+ "package": "regex",
+ "version": "2026.7.19",
+ "filename": "regex-2026.7.19-cp312-cp312-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/08/8e/c780c131f79b42ed22d1bd7da4096c2c35f813e835acd02ef0f018bd892c/regex-2026.7.19-cp312-cp312-win_amd64.whl",
+ "size": 277777,
+ "sha256": "e30d40268a28d54ce0437031750497004c22602b8e3ab891f759b795a003b312"
+ },
+ {
+ "package": "resampy",
+ "version": "0.4.3",
+ "filename": "resampy-0.4.3-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/4d/b9/3b00ac340a1aab3389ebcc52c779914a44aadf7b0cb7a3bf053195735607/resampy-0.4.3-py3-none-any.whl",
+ "size": 3076529,
+ "sha256": "ad2ed64516b140a122d96704e32bc0f92b23f45419e8b8f478e5a05f83edcebd"
+ },
+ {
+ "package": "rich",
+ "version": "15.0.0",
+ "filename": "rich-15.0.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl",
+ "size": 310654,
+ "sha256": "33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb"
+ },
+ {
+ "package": "safetensors",
+ "version": "0.7.0",
+ "filename": "safetensors-0.7.0-cp38-abi3-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/5d/e6/ec8471c8072382cb91233ba7267fd931219753bb43814cbc71757bfd4dab/safetensors-0.7.0-cp38-abi3-win_amd64.whl",
+ "size": 341380,
+ "sha256": "d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755"
+ },
+ {
+ "package": "sentencepiece",
+ "version": "0.2.1",
+ "filename": "sentencepiece-0.2.1-cp312-cp312-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/2d/81/92df5673c067148c2545b1bfe49adfd775bcc3a169a047f5a0e6575ddaca/sentencepiece-0.2.1-cp312-cp312-win_amd64.whl",
+ "size": 1054671,
+ "sha256": "4cdc7c36234fda305e85c32949c5211faaf8dd886096c7cea289ddc12a2d02de"
+ },
+ {
+ "package": "setuptools",
+ "version": "81.0.0",
+ "filename": "setuptools-81.0.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl",
+ "size": 1062021,
+ "sha256": "fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6"
+ },
+ {
+ "package": "shellingham",
+ "version": "1.5.4",
+ "filename": "shellingham-1.5.4-py2.py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl",
+ "size": 9755,
+ "sha256": "7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"
+ },
+ {
+ "package": "sympy",
+ "version": "1.14.0",
+ "filename": "sympy-1.14.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl",
+ "size": 6299353,
+ "sha256": "e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5"
+ },
+ {
+ "package": "tokenizers",
+ "version": "0.22.2",
+ "filename": "tokenizers-0.22.2-cp39-abi3-win_amd64.whl",
+ "url": "https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl",
+ "size": 2747786,
+ "sha256": "c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48"
+ },
+ {
+ "package": "torch",
+ "version": "2.12.1+cu130",
+ "filename": "torch-2.12.1+cu130-cp312-cp312-win_amd64.whl",
+ "url": "https://download-r2.pytorch.org/whl/cu130/torch-2.12.1%2Bcu130-cp312-cp312-win_amd64.whl",
+ "size": 1926431198,
+ "sha256": "52c5da6a0898d5d3473c02bd304b7a3bc0b72e351c6f3bfa0783e45ef9f4cd61"
+ },
+ {
+ "package": "tqdm",
+ "version": "4.70.0",
+ "filename": "tqdm-4.70.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/f9/1c/01bfd571a64e7f270e6bab5e33777debe0edc56759233ce84f27dec92d14/tqdm-4.70.0-py3-none-any.whl",
+ "size": 80184,
+ "sha256": "7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953"
+ },
+ {
+ "package": "transformers",
+ "version": "5.8.0",
+ "filename": "transformers-5.8.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/97/7b/5621d08b34ac35deb9fa14b58d27d124d21ef125ee1c64bc724ca47dfb63/transformers-5.8.0-py3-none-any.whl",
+ "size": 10630279,
+ "sha256": "e9d2cae6d195a7e1e05164c5ebf26142a7044e4dc4267274f4809204f92827e4"
+ },
+ {
+ "package": "typer",
+ "version": "0.27.1",
+ "filename": "typer-0.27.1-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/43/89/9518bc0c3929bee36b3a4a8e3daddd6e03f92f9961c66d4983b837160543/typer-0.27.1-py3-none-any.whl",
+ "size": 122874,
+ "sha256": "53150287edd11baeb4e4722c8e394fcdf8181c0ae89485cba8d25c778d5edd56"
+ },
+ {
+ "package": "typing-extensions",
+ "version": "4.16.0",
+ "filename": "typing_extensions-4.16.0-py3-none-any.whl",
+ "url": "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl",
+ "size": 45571,
+ "sha256": "481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8"
+ }
+ ]
+ }
+}
diff --git a/sa3-pin.json b/sa3-pin.json
index 5bde79f..a93d15f 100644
--- a/sa3-pin.json
+++ b/sa3-pin.json
@@ -1,5 +1,133 @@
{
"note": "Back on upstream: our MLX LoRA merge-at-load (ADR-0028) landed as PR #57 (2026-07-14), and #65 extended it with per-adapter strength= and step gating. Bump via ADR-0012's upgrade path.",
"repo": "https://github.com/Stability-AI/stable-audio-3",
- "commit": "0385302ea26522f00c80392c4b708df5ebf1adf5"
+ "commit": "a0b57f5483c4588f827f3552b7d5c6ca2a9687be",
+ "source": {
+ "url": "https://github.com/Stability-AI/stable-audio-3/archive/a0b57f5483c4588f827f3552b7d5c6ca2a9687be.tar.gz",
+ "sha256": "98e206e061a3b64a4e65f50b2802bdb6965910ac1fab65da919808dfb4497e9f",
+ "size": 50494239,
+ "archiveRoot": "stable-audio-3-a0b57f5483c4588f827f3552b7d5c6ca2a9687be",
+ "maxFiles": 2000,
+ "maxExpandedBytes": 134217728
+ },
+ "runtime": {
+ "requirements": "sa3-requirements.lock",
+ "python": [
+ {
+ "target": "aarch64-apple-darwin",
+ "version": "3.11.13",
+ "url": "https://releases.astral.sh/github/python-build-standalone/releases/download/20251007/cpython-3.11.13%2B20251007-aarch64-apple-darwin-install_only_stripped.tar.gz",
+ "sha256": "78bc6defdc1dac5bf6765c8f938e6849383dbed831ea1e2d11576a4683fb1e8c",
+ "size": 18949778,
+ "archiveRoot": "python",
+ "executable": "bin/python3.11",
+ "maxFiles": 5000,
+ "maxExpandedBytes": 134217728
+ },
+ {
+ "target": "x86_64-unknown-linux-gnu",
+ "version": "3.11.13",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251007/cpython-3.11.13%2B20251007-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz",
+ "sha256": "43bfc42529843ecd1d9c08c4a239ede348f96ff0acaef2ec24b28dc059f4f0c3",
+ "size": 30157215,
+ "archiveRoot": "python",
+ "executable": "bin/python3.11",
+ "maxFiles": 5000,
+ "maxExpandedBytes": 536870912
+ },
+ {
+ "target": "x86_64-pc-windows-msvc",
+ "version": "3.11.13",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251007/cpython-3.11.13%2B20251007-x86_64-pc-windows-msvc-install_only_stripped.tar.gz",
+ "sha256": "cde5153f59a67d9e108f2ed964526e9aed100eba180f54bee0496b4fd73a8b29",
+ "size": 25990147,
+ "archiveRoot": "python",
+ "executable": "python.exe",
+ "maxFiles": 5000,
+ "maxExpandedBytes": 536870912
+ }
+ ],
+ "uv": [
+ {
+ "target": "aarch64-apple-darwin",
+ "version": "0.11.7",
+ "url": "https://github.com/astral-sh/uv/releases/download/0.11.7/uv-aarch64-apple-darwin.tar.gz",
+ "sha256": "66e37d91f839e12481d7b932a1eccbfe732560f42c1cfb89faddfa2454534ba8",
+ "size": 20839135,
+ "archiveRoot": "uv-aarch64-apple-darwin",
+ "executable": "uv",
+ "maxFiles": 8,
+ "maxExpandedBytes": 67108864
+ },
+ {
+ "target": "x86_64-unknown-linux-gnu",
+ "version": "0.11.7",
+ "url": "https://github.com/astral-sh/uv/releases/download/0.11.7/uv-x86_64-unknown-linux-gnu.tar.gz",
+ "sha256": "6681d691eb7f9c00ac6a3af54252f7ab29ae72f0c8f95bdc7f9d1401c23ea868",
+ "size": 24249861,
+ "archiveRoot": "uv-x86_64-unknown-linux-gnu",
+ "executable": "uv",
+ "maxFiles": 8,
+ "maxExpandedBytes": 67108864
+ },
+ {
+ "target": "x86_64-pc-windows-msvc",
+ "version": "0.11.7",
+ "url": "https://github.com/astral-sh/uv/releases/download/0.11.7/uv-x86_64-pc-windows-msvc.zip",
+ "sha256": "fe0c7815acf4fc45f8a5eff58ed3cf7ae2e15c3cf1dceadbd10c816ec1690cc1",
+ "size": 23572531,
+ "archiveRoot": "uv-x86_64-pc-windows-msvc",
+ "archiveFormat": "zip",
+ "executable": "uv.exe",
+ "maxFiles": 8,
+ "maxExpandedBytes": 67108864
+ }
+ ]
+ },
+ "models": {
+ "repo": "stabilityai/stable-audio-3-optimized",
+ "revision": "6736003cb57d06b7b1fdc36fad31b2a3709e4774",
+ "artifacts": [
+ {
+ "path": "MLX/dit_medium_f16.npz",
+ "sha256": "f9e5647ea3225818657d47d47ae4b34afa29c0568206ca89566c1a758944a38e",
+ "size": 2907300946
+ },
+ {
+ "path": "MLX/dit_sm-music_f16.npz",
+ "sha256": "8ed3f38e2597f361ee675051f1265d9aa2ae2fffce1c61acd2e9fe31e1db1cbc",
+ "size": 919193814
+ },
+ {
+ "path": "MLX/dit_sm-sfx_f16.npz",
+ "sha256": "7e702d2640699a57fe436ca975fda16832040ba568c1e092c2ae826987558118",
+ "size": 919193814
+ },
+ {
+ "path": "MLX/same_l_decoder_f32.npz",
+ "sha256": "84924be2122d3a20fce443f40b782d9cd88e8e73707476326003ac47659a2287",
+ "size": 1704311976
+ },
+ {
+ "path": "MLX/same_l_encoder_f32.npz",
+ "sha256": "c5caafc6bd29fc3d4cb7a08b0d3725041fa2100711f86a4f05d2638c532871d2",
+ "size": 1704313504
+ },
+ {
+ "path": "MLX/same_s_decoder_f32.npz",
+ "sha256": "909928a8e6937c1ebe6ac4b729f0462bd3773704a11ea18278e42671dc69bfe4",
+ "size": 218090820
+ },
+ {
+ "path": "MLX/same_s_encoder_f32.npz",
+ "sha256": "a48f80d81c30d74c45e2a3047082c4891f715e24c44645adb9c1f4f07afdaf0c",
+ "size": 214946620
+ },
+ {
+ "path": "MLX/t5gemma_f16.npz",
+ "sha256": "8deb20489f36d9aec539f26c9c67321f99bc5fe300d470435ed6e76be4f16bbd",
+ "size": 567443068
+ }
+ ]
+ }
}
diff --git a/sa3-pytorch-cuda-pin.json b/sa3-pytorch-cuda-pin.json
new file mode 100644
index 0000000..1c63ead
--- /dev/null
+++ b/sa3-pytorch-cuda-pin.json
@@ -0,0 +1,93 @@
+{
+ "schemaVersion": 1,
+ "releaseReady": false,
+ "backend": "pytorch_cuda",
+ "platform": "windows-x86_64",
+ "source": {
+ "repository": "https://github.com/Stability-AI/stable-audio-3",
+ "revision": "a0b57f5483c4588f827f3552b7d5c6ca2a9687be",
+ "archiveUrl": "https://github.com/Stability-AI/stable-audio-3/archive/a0b57f5483c4588f827f3552b7d5c6ca2a9687be.tar.gz",
+ "size": 50494239,
+ "sha256": "98e206e061a3b64a4e65f50b2802bdb6965910ac1fab65da919808dfb4497e9f",
+ "license": "MIT"
+ },
+ "sharedRuntime": {
+ "python": "3.12",
+ "cuda": "12.6",
+ "requirementsInput": "backend/runtime-locks/windows-gpu-pytorch.in",
+ "requirementsLock": "backend/runtime-locks/windows-gpu-pytorch.txt",
+ "requirementsLockSize": 56238,
+ "requirementsLockSha256": "3c9bf7d79c3848ebe1da40fd14b26708b55d8157f008cb3a1944ddfb1cd597c4",
+ "packages": {
+ "torch": "2.7.1+cu126",
+ "torchaudio": "2.7.1+cu126",
+ "transformers": "5.8.0",
+ "huggingface-hub": "1.7.1",
+ "numpy": "2.3.5",
+ "safetensors": "0.7.0",
+ "sentencepiece": "0.2.1",
+ "resampy": "0.4.3"
+ },
+ "mrt2RequalificationRequired": true
+ },
+ "models": {
+ "small-music": {
+ "repository": "stabilityai/stable-audio-3-small-music",
+ "revision": "0fef1392cd842149a2b6d445e181c97608faac06",
+ "required": true,
+ "weight": {
+ "path": "model.safetensors",
+ "size": 2270384940,
+ "sha256": "da85866b11b01d0694d990785f6abbd79c8064df1b0e6f8aea52935e0ef84b64"
+ },
+ "config": {
+ "path": "model_config.json",
+ "size": 10341,
+ "gitBlobSha1": "29ba617d6556c9e3c94bea19f07ea66d0c895e9e",
+ "sha256": null
+ }
+ },
+ "small-sfx": {
+ "repository": "stabilityai/stable-audio-3-small-sfx",
+ "revision": "ae12755283df9d62ca39a9b050a39a0b607b8c20",
+ "required": true,
+ "weight": {
+ "path": "model.safetensors",
+ "size": 2270384940,
+ "sha256": "ed9cf1b6172f1a8c2921a9560c21109ff3239524563ced9dce6dcdef41e2f515"
+ },
+ "config": {
+ "path": "model_config.json",
+ "size": 10454,
+ "gitBlobSha1": null,
+ "sha256": null
+ }
+ },
+ "medium": {
+ "repository": "stabilityai/stable-audio-3-medium",
+ "revision": "27b5a21b791b1b033d193a9e1e3ce78493f102f9",
+ "required": false,
+ "enabled": false,
+ "blockedBy": "No official Windows FlashAttention 2 build has been qualified",
+ "weight": {
+ "path": "model.safetensors",
+ "size": 9222116660,
+ "sha256": "48d9c65e290e7bcd5194e0633bfc2424a59ee9683f5c2d58762d997b7d8ce0b5"
+ },
+ "config": {
+ "path": "model_config.json",
+ "size": 10360,
+ "gitBlobSha1": null,
+ "sha256": null
+ }
+ }
+ },
+ "gatedArtifactsComplete": false,
+ "releaseBlockers": [
+ "Authenticated SHA-256 audit of all model configs and nested T5Gemma artifacts after the terms flow in issue #108",
+ "Small Music and Small SFX measured VRAM reservations with conservative headroom",
+ "MRT2 functional and real-time parity on the shared torch 2.7.1/CUDA 12.6 runtime",
+ "Windows NVIDIA OOM, cancellation, crash, exit, and VRAM-release evidence",
+ "Ten-minute dual-deck 25-frame and 5-frame runs with zero engine-reported underruns"
+ ]
+}
diff --git a/sa3-tflite-pin.json b/sa3-tflite-pin.json
new file mode 100644
index 0000000..7a0db6d
--- /dev/null
+++ b/sa3-tflite-pin.json
@@ -0,0 +1,86 @@
+{
+ "schemaVersion": 1,
+ "runtime": {
+ "repo": "https://github.com/Stability-AI/stable-audio-3",
+ "revision": "a0b57f5483c4588f827f3552b7d5c6ca2a9687be",
+ "subdirectory": "optimized/tflite",
+ "entrypoint": "scripts/sa3_tflite.py",
+ "requirementsInput": "scripts/sa3-tflite-requirements.in",
+ "requirementsLock": "scripts/sa3-tflite-requirements.lock"
+ },
+ "models": {
+ "repo": "stabilityai/stable-audio-3-optimized",
+ "revision": "6736003cb57d06b7b1fdc36fad31b2a3709e4774",
+ "precision": "fp32",
+ "shared": [
+ {
+ "path": "tflite/t5gemma/encoder_fp16.tflite",
+ "installPath": "models/tflite/t5gemma/encoder_fp16.tflite",
+ "size": 563818608,
+ "sha256": "8530d0b3e6b9b9dcf1239145c2a853fb749708eaddbb472ff8f0802b50059372"
+ }
+ ],
+ "bundles": {
+ "sm-music": [
+ {
+ "path": "tflite/sa3-sm-music/dit_fp32.tflite",
+ "installPath": "models/tflite/sa3-sm-music/dit_fp32.tflite",
+ "size": 1838758544,
+ "sha256": "d388700a2ca439c11e9a53506e964e93231386a2beb8173c6eec6d95f676ce09"
+ },
+ {
+ "path": "tflite/same-s/enc_fp32.tflite",
+ "installPath": "models/tflite/same-s/enc_fp32.tflite",
+ "size": 215195204,
+ "sha256": "35ce38ea9f56e116036c683e37bf96c954d4fe0a435606ded0f62595b91f52a3"
+ },
+ {
+ "path": "tflite/same-s/dec_fp32.tflite",
+ "installPath": "models/tflite/same-s/dec_fp32.tflite",
+ "size": 218377156,
+ "sha256": "cd87fa6686b24a56dc3497e05fbb26a34cf9604afe49c6631e829c9e70fccf21"
+ }
+ ],
+ "sm-sfx": [
+ {
+ "path": "tflite/sa3-sm-sfx/dit_fp32.tflite",
+ "installPath": "models/tflite/sa3-sm-sfx/dit_fp32.tflite",
+ "size": 1838758544,
+ "sha256": "6060ecfeca34c4ab35bc1912a37e680e8cd7aab6c4bd9de1bc2655414891b8d8"
+ },
+ {
+ "path": "tflite/same-s/enc_fp32.tflite",
+ "installPath": "models/tflite/same-s/enc_fp32.tflite",
+ "size": 215195204,
+ "sha256": "35ce38ea9f56e116036c683e37bf96c954d4fe0a435606ded0f62595b91f52a3"
+ },
+ {
+ "path": "tflite/same-s/dec_fp32.tflite",
+ "installPath": "models/tflite/same-s/dec_fp32.tflite",
+ "size": 218377156,
+ "sha256": "cd87fa6686b24a56dc3497e05fbb26a34cf9604afe49c6631e829c9e70fccf21"
+ }
+ ],
+ "medium": [
+ {
+ "path": "tflite/sa3-m/dit_fp32.tflite",
+ "installPath": "models/tflite/sa3-m/dit_fp32.tflite",
+ "size": 5816313104,
+ "sha256": "b811dc7d0135ca48afbc7a7bb7d19bdaaad13cbcb592418b8aa169e0c149daba"
+ },
+ {
+ "path": "tflite/same-l/enc_fp32.tflite",
+ "installPath": "models/tflite/same-l/enc_fp32.tflite",
+ "size": 1823872896,
+ "sha256": "f8b5e95a7073e3b59e4a1c2b07836d86d514cc7eaaff05b3c7cbdd1620f141d5"
+ },
+ {
+ "path": "tflite/same-l/dec_fp32.tflite",
+ "installPath": "models/tflite/same-l/dec_fp32.tflite",
+ "size": 1823900848,
+ "sha256": "3af34d35939ce6fc74d9f7b9d9bd6b99bc9568b614bcfe57da4a781bf40c8c6c"
+ }
+ ]
+ }
+ }
+}
diff --git a/sa3-tflite-wheels.json b/sa3-tflite-wheels.json
new file mode 100644
index 0000000..3ea65b2
--- /dev/null
+++ b/sa3-tflite-wheels.json
@@ -0,0 +1,55 @@
+{
+ "schemaVersion": 1,
+ "python": "3.11",
+ "common": [
+ {"package":"annotated-doc","version":"0.0.5","filename":"annotated_doc-0.0.5-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl","size":5302,"sha256":"117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101"},
+ {"package":"annotated-types","version":"0.8.0","filename":"annotated_types-0.8.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl","size":13427,"sha256":"f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0"},
+ {"package":"anyio","version":"4.14.2","filename":"anyio-4.14.2-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl","size":125813,"sha256":"9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494"},
+ {"package":"backports-strenum","version":"1.3.1","filename":"backports_strenum-1.3.1-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/d6/50/56cf20e2ee5127b603b81d5a69580a1a325083e2b921aa8f067da83927c0/backports_strenum-1.3.1-py3-none-any.whl","size":8304,"sha256":"cdcfe36dc897e2615dc793b7d3097f54d359918fc448754a517e6f23044ccf83"},
+ {"package":"certifi","version":"2026.7.22","filename":"certifi-2026.7.22-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl","size":136983,"sha256":"62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775"},
+ {"package":"click","version":"8.4.2","filename":"click-8.4.2-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl","size":119243,"sha256":"e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76"},
+ {"package":"filelock","version":"3.32.2","filename":"filelock-3.32.2-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/c1/e8/72f8cef9fdfeffe06213fe8508039396ee48daa0e3259457ed766173bfd6/filelock-3.32.2-py3-none-any.whl","size":98830,"sha256":"87dd94cf281e586d135fa51132b8e3d9a598b316e90377a288663c9321036c82"},
+ {"package":"fastapi","version":"0.136.3","filename":"fastapi-0.136.3-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl","size":117481,"sha256":"3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620"},
+ {"package":"flatbuffers","version":"25.12.19","filename":"flatbuffers-25.12.19-py2.py3-none-any.whl","url":"https://files.pythonhosted.org/packages/e8/2d/d2a548598be01649e2d46231d151a6c56d10b964d94043a335ae56ea2d92/flatbuffers-25.12.19-py2.py3-none-any.whl","size":26661,"sha256":"7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4"},
+ {"package":"fsspec","version":"2026.7.0","filename":"fsspec-2026.7.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/fd/3c/6a2bf344106328fd04963664a60b9bb6496fc25df8e962fcdc1367285fb9/fsspec-2026.7.0-py3-none-any.whl","size":206583,"sha256":"b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279"},
+ {"package":"h11","version":"0.16.0","filename":"h11-0.16.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl","size":37515,"sha256":"63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"},
+ {"package":"httpcore","version":"1.0.9","filename":"httpcore-1.0.9-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl","size":78784,"sha256":"2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"},
+ {"package":"httpx","version":"0.28.1","filename":"httpx-0.28.1-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl","size":73517,"sha256":"d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"},
+ {"package":"huggingface-hub","version":"1.27.0","filename":"huggingface_hub-1.27.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/de/d8/95b735e183957c1f26d94c52977f09d466d55119cbbc1558ea4975e4c216/huggingface_hub-1.27.0-py3-none-any.whl","size":784926,"sha256":"7df6827c2f956c60fbaa64646e979e566db76f619dd0a9729dfb8c5a3eb4f68d"},
+ {"package":"idna","version":"3.18","filename":"idna-3.18-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl","size":65455,"sha256":"7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2"},
+ {"package":"packaging","version":"26.3","filename":"packaging-26.3-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl","size":129956,"sha256":"d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c"},
+ {"package":"pydantic","version":"2.13.4","filename":"pydantic-2.13.4-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl","size":472262,"sha256":"45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba"},
+ {"package":"pycparser","version":"3.0","filename":"pycparser-3.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl","size":48172,"sha256":"b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992"},
+ {"package":"python-multipart","version":"0.0.32","filename":"python_multipart-0.0.32-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl","size":30042,"sha256":"ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23"},
+ {"package":"starlette","version":"1.6.0","filename":"starlette-1.6.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/c8/cb/6a6a47d5b464bd08695d254f3da6e7986cc70c9fa5d778eda57538edfe56/starlette-1.6.0-py3-none-any.whl","size":75969,"sha256":"a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c"},
+ {"package":"tqdm","version":"4.70.0","filename":"tqdm-4.70.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/f9/1c/01bfd571a64e7f270e6bab5e33777debe0edc56759233ce84f27dec92d14/tqdm-4.70.0-py3-none-any.whl","size":80184,"sha256":"7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953"},
+ {"package":"typing-inspection","version":"0.4.2","filename":"typing_inspection-0.4.2-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl","size":14611,"sha256":"4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"},
+ {"package":"typing-extensions","version":"4.16.0","filename":"typing_extensions-4.16.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl","size":45571,"sha256":"481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8"},
+ {"package":"uvicorn","version":"0.49.0","filename":"uvicorn-0.49.0-py3-none-any.whl","url":"https://files.pythonhosted.org/packages/88/fa/e1388bbcf24ef3274f45c0c1c7b501fd14971037c1b6ee23610553307497/uvicorn-0.49.0-py3-none-any.whl","size":71376,"sha256":"ba3d14c3ee7e41c6c654c46c9eb489d33213cdd30aa1696eab1374337c13f68f"}
+ ],
+ "targets": {
+ "x86_64-unknown-linux-gnu": [
+ {"package":"ai-edge-litert","version":"2.1.6","filename":"ai_edge_litert-2.1.6-cp311-cp311-manylinux_2_27_x86_64.whl","url":"https://files.pythonhosted.org/packages/b2/b9/c7153b2f6f37bc521876b8fa86125eb618bba9d84b20ba0bc5c05795eda7/ai_edge_litert-2.1.6-cp311-cp311-manylinux_2_27_x86_64.whl","size":17328951,"sha256":"af4f2ba681fa2c688746cbd7ddd71a2bbbdd9e6a51aa609d382bfad77d1c695e"},
+ {"package":"cffi","version":"2.1.1","filename":"cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl","url":"https://files.pythonhosted.org/packages/f7/a4/4399daaf8f7dfee9d7c3327fdb0426ee041cc63edc358b93911ceb2bfc7a/cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl","size":217807,"sha256":"34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632"},
+ {"package":"hf-xet","version":"1.6.0","filename":"hf_xet-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl","url":"https://files.pythonhosted.org/packages/67/4e/a28359bf1c1ecf11eba22123168c138698f7cb576ac678f5a2e16cd5da08/hf_xet-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl","size":4464663,"sha256":"d62671bb130879cef0ee4c9ebe47a14af6c66ec53e6d84dc15936e5ffdfac82f"},
+ {"package":"numpy","version":"2.4.6","filename":"numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl","url":"https://files.pythonhosted.org/packages/02/03/74fe2a4cb3817d94d86402f2506554130a2f01414e299b5a843e5a8a957f/numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl","size":16918164,"sha256":"89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93"},
+ {"package":"protobuf","version":"7.35.1","filename":"protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl","url":"https://files.pythonhosted.org/packages/e4/be/5b3cfe508bfab6761414ff944e3366eb13be4fd71efcd69450f89ba39f43/protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl","size":327130,"sha256":"74758715c53d7158fb76caf4f0cfdacc5329a4b1bb994f865d6cf302d413a1c4"},
+ {"package":"pydantic-core","version":"2.46.4","filename":"pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl","url":"https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl","size":2089685,"sha256":"f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4"},
+ {"package":"pyyaml","version":"6.0.3","filename":"pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl","url":"https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl","size":806638,"sha256":"b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"},
+ {"package":"sentencepiece","version":"0.2.2","filename":"sentencepiece-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl","url":"https://files.pythonhosted.org/packages/06/5f/9117bf854aef817ad0d0ee9310eed0308a7e529e7eaf2e80ad9cd281ef82/sentencepiece-0.2.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl","size":1394242,"sha256":"1416b92f2f010333786fe6306ed2631121d5ea492219b0841e967b6765e64107"},
+ {"package":"soundfile","version":"0.14.0","filename":"soundfile-0.14.0-py2.py3-none-manylinux_2_28_x86_64.whl","url":"https://files.pythonhosted.org/packages/7b/a2/70fd4432b924684c372df8b0a45708c36c057ef3596c9eb53e0a806b980b/soundfile-0.14.0-py2.py3-none-manylinux_2_28_x86_64.whl","size":1315963,"sha256":"1e38bac1853412871318e82a1ba69a8be677619b56025bbfcccdb41b6cafe82d"}
+ ],
+ "x86_64-pc-windows-msvc": [
+ {"package":"ai-edge-litert","version":"2.1.6","filename":"ai_edge_litert-2.1.6-cp311-cp311-win_amd64.whl","url":"https://files.pythonhosted.org/packages/87/0f/031a56bc95a7109f4a71ec5510a34214d5f9d99ff01a926fb2129ec2288b/ai_edge_litert-2.1.6-cp311-cp311-win_amd64.whl","size":16587870,"sha256":"b20f4c8cdbbf6f64e3baa77853e55a1b29515a45d6dfbe6b2ced9b3a1efb5807"},
+ {"package":"cffi","version":"2.1.1","filename":"cffi-2.1.1-cp311-cp311-win_amd64.whl","url":"https://files.pythonhosted.org/packages/73/c0/77ba02423c2f7d7091143c45cd49e0e6575c4c1967394bb542bd923a9b74/cffi-2.1.1-cp311-cp311-win_amd64.whl","size":185096,"sha256":"42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0"},
+ {"package":"colorama","version":"0.4.6","filename":"colorama-0.4.6-py2.py3-none-any.whl","url":"https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl","size":25335,"sha256":"4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+ {"package":"hf-xet","version":"1.6.0","filename":"hf_xet-1.6.0-cp38-abi3-win_amd64.whl","url":"https://files.pythonhosted.org/packages/98/b7/8c59a66d15205024662f1d66968136f13893f96df1ddc5087e2e281fc95f/hf_xet-1.6.0-cp38-abi3-win_amd64.whl","size":4033128,"sha256":"fb4fadde1b2b70bf4c0c14a6dccbe7194b1c28947fefd5bbe3fed9d940676c3b"},
+ {"package":"numpy","version":"2.4.6","filename":"numpy-2.4.6-cp311-cp311-win_amd64.whl","url":"https://files.pythonhosted.org/packages/c5/31/7fc6239c12bce7e931463251cca4426c465e1876ba3cc785402ef4dd8f4e/numpy-2.4.6-cp311-cp311-win_amd64.whl","size":12608406,"sha256":"1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147"},
+ {"package":"protobuf","version":"7.35.1","filename":"protobuf-7.35.1-cp310-abi3-win_amd64.whl","url":"https://files.pythonhosted.org/packages/0a/19/8d0cb6f20a1ef7b18f1c8986ad5783f22f84cce39c6ce9a6e645ea55192e/protobuf-7.35.1-cp310-abi3-win_amd64.whl","size":439996,"sha256":"230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87"},
+ {"package":"pydantic-core","version":"2.46.4","filename":"pydantic_core-2.46.4-cp311-cp311-win_amd64.whl","url":"https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl","size":2071114,"sha256":"6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33"},
+ {"package":"pyyaml","version":"6.0.3","filename":"pyyaml-6.0.3-cp311-cp311-win_amd64.whl","url":"https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl","size":158763,"sha256":"9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"},
+ {"package":"sentencepiece","version":"0.2.2","filename":"sentencepiece-0.2.2-cp311-cp311-win_amd64.whl","url":"https://files.pythonhosted.org/packages/ab/62/9e2569867e3dcff7ad6d89642a9615b9801b5cd698abe7df3b490361f66e/sentencepiece-0.2.2-cp311-cp311-win_amd64.whl","size":1246268,"sha256":"70d4ca6f4d06df7f0ccab6fe4f49c8a712c8c8b6847b4f0af9a0e1dbb0e0337e"},
+ {"package":"soundfile","version":"0.14.0","filename":"soundfile-0.14.0-py2.py3-none-win_amd64.whl","url":"https://files.pythonhosted.org/packages/ed/97/b39c18ac1df45e755ca22b8b00e872929da5d107998a207a5e4ac831bfda/soundfile-0.14.0-py2.py3-none-win_amd64.whl","size":1021480,"sha256":"299491d3499460fb1b74bb4bd78b57ffc2d243a5fafa7b6ec1b264875c78453e"}
+ ]
+ }
+}
diff --git a/scripts/assert-windows-release-rejects-unsigned.ps1 b/scripts/assert-windows-release-rejects-unsigned.ps1
new file mode 100644
index 0000000..ce7b1a7
--- /dev/null
+++ b/scripts/assert-windows-release-rejects-unsigned.ps1
@@ -0,0 +1,31 @@
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [string] $Path
+)
+
+$ErrorActionPreference = 'Stop'
+Set-StrictMode -Version Latest
+
+# Hosted pull-request CI deliberately creates unsigned development installers.
+# Prove the release verifier refuses one with an otherwise syntactically valid
+# expected identity. The exact NotSigned failure is required so a missing SDK
+# tool or unrelated script error cannot masquerade as successful rejection.
+$powerShell = (Get-Process -Id $PID).Path
+$PSNativeCommandUseErrorActionPreference = $false
+$output = & $powerShell -NoLogo -NoProfile -NonInteractive -File `
+ "$PSScriptRoot/verify-windows-signatures.ps1" `
+ -Path $Path `
+ -ExpectedCertificateSha1 ('0' * 40) `
+ -ExpectedSubject 'CN=Unsigned CI Sentinel' 2>&1
+$exitCode = $LASTEXITCODE
+$rendered = $output | Out-String
+if ($exitCode -eq 0) {
+ throw 'Release signature verification accepted an unsigned development installer.'
+}
+if ($rendered -notmatch 'Authenticode signature status is NotSigned') {
+ throw "Release verification failed for an unexpected reason instead of rejecting an unsigned artifact:`n$rendered"
+}
+Write-Host 'Release signature verification correctly rejected the unsigned development installer.'
+exit 0
diff --git a/scripts/audit-sa3-cuda-pin.py b/scripts/audit-sa3-cuda-pin.py
new file mode 100644
index 0000000..c21bf60
--- /dev/null
+++ b/scripts/audit-sa3-cuda-pin.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+"""Audit the fail-closed Windows SA3/CUDA candidate manifest.
+
+This audit deliberately fails for a release while any gated artifact lacks an
+application-controlled SHA-256. ``--allow-incomplete`` is only for reviewing
+the public, immutable metadata before issue #108 supplies an authenticated
+terms/download flow; it does not make the runtime installable.
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import re
+import sys
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parent.parent
+PIN_PATH = ROOT / "sa3-pytorch-cuda-pin.json"
+REQUIREMENT = re.compile(r"(?m)^([A-Za-z0-9_.-]+)==([^ \\\n]+) \\")
+
+
+def sha256(path: Path) -> str:
+ digest = hashlib.sha256()
+ with path.open("rb") as handle:
+ while chunk := handle.read(1024 * 1024):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def audit_lock(pin: dict) -> None:
+ runtime = pin["sharedRuntime"]
+ lock_path = ROOT / runtime["requirementsLock"]
+ if (lock_path.stat().st_size, sha256(lock_path)) != (
+ runtime["requirementsLockSize"],
+ runtime["requirementsLockSha256"],
+ ):
+ raise RuntimeError("shared runtime lock size or SHA-256 does not match the pin")
+ text = lock_path.read_text(encoding="utf-8")
+ requirements = dict(REQUIREMENT.findall(text))
+ if runtime["packages"].items() > requirements.items():
+ raise RuntimeError("shared runtime direct package pins do not match the lock")
+ if any(value in text for value in ("git+", "http://", " @ ", "--editable")):
+ raise RuntimeError("shared runtime lock contains a mutable dependency")
+ blocks = re.split(r"(?m)(?=^[A-Za-z0-9_.-]+==)", text)
+ if any("==" in block and "--hash=sha256:" not in block for block in blocks):
+ raise RuntimeError("shared runtime lock contains an unhashed dependency")
+
+
+def missing_artifact_hashes(pin: dict) -> list[str]:
+ missing = []
+ for model_name, model in pin["models"].items():
+ if not (model.get("required") or model.get("enabled")):
+ continue
+ for artifact_name in ("weight", "config"):
+ artifact = model[artifact_name]
+ if artifact.get("sha256") is None:
+ missing.append(f"{model_name}/{artifact['path']}")
+ return missing
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--allow-incomplete",
+ action="store_true",
+ help="review the non-release candidate even though gated hashes are missing",
+ )
+ args = parser.parse_args()
+ pin = json.loads(PIN_PATH.read_text(encoding="utf-8"))
+ if pin.get("schemaVersion") != 1 or pin.get("backend") != "pytorch_cuda":
+ raise RuntimeError("unsupported Windows SA3/CUDA pin schema")
+ if pin.get("platform") != "windows-x86_64":
+ raise RuntimeError("the CUDA candidate must be Windows x64 only")
+ if pin["source"]["revision"] not in pin["source"]["archiveUrl"]:
+ raise RuntimeError("source archive URL is not tied to the immutable revision")
+ audit_lock(pin)
+ missing = missing_artifact_hashes(pin)
+ complete = not missing
+ if pin.get("gatedArtifactsComplete") is not complete:
+ raise RuntimeError("gatedArtifactsComplete disagrees with artifact hashes")
+ if pin.get("releaseReady") and (not complete or pin["releaseBlockers"]):
+ raise RuntimeError("releaseReady cannot be true while gates remain")
+ if missing and not args.allow_incomplete:
+ raise RuntimeError(
+ "gated artifact SHA-256 values are missing: " + ", ".join(missing)
+ )
+ print(
+ "SA3/CUDA pin audit complete"
+ + (" (candidate remains release-blocked)" if missing else "")
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ try:
+ raise SystemExit(main())
+ except (OSError, RuntimeError, ValueError, json.JSONDecodeError) as error:
+ print(f"SA3/CUDA pin audit failed: {error}", file=sys.stderr)
+ raise SystemExit(1)
diff --git a/scripts/audit-sa3-pins.py b/scripts/audit-sa3-pins.py
new file mode 100644
index 0000000..362ca0f
--- /dev/null
+++ b/scripts/audit-sa3-pins.py
@@ -0,0 +1,219 @@
+#!/usr/bin/env python3
+"""Reproduce the external provenance checks for both SA3 manifests.
+
+The default audit downloads and hashes the small source/runtime archives, uses
+the immutable Hugging Face revision's LFS metadata for the eight multi-GB model
+objects, and checks that both dependency locks remain fully hash-pinned. Pass
+--include-model-bytes for the stronger (roughly 23 GB) end-to-end model audit.
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import re
+import sys
+import urllib.parse
+import urllib.request
+from pathlib import Path
+from typing import Any
+
+
+ROOT = Path(__file__).resolve().parent.parent
+PIN_PATH = ROOT / "sa3-pin.json"
+TFLITE_PIN_PATH = ROOT / "sa3-tflite-pin.json"
+LOCK_PATHS = (
+ ROOT / "scripts" / "sa3-requirements.lock",
+ ROOT / "scripts" / "sa3-tflite-requirements.lock",
+)
+USER_AGENT = "LSDJ-SA3-pin-audit/1"
+
+
+def fetch(url: str):
+ parsed = urllib.parse.urlparse(url)
+ if parsed.scheme != "https" or parsed.username or parsed.password:
+ raise RuntimeError(f"refusing non-HTTPS or credential-bearing URL: {url}")
+ request = urllib.request.Request(url, headers={"User-Agent": USER_AGENT})
+ response = urllib.request.urlopen(request, timeout=60)
+ final = urllib.parse.urlparse(response.geturl())
+ if final.scheme != "https":
+ response.close()
+ raise RuntimeError(f"redirect left HTTPS: {response.geturl()}")
+ return response
+
+
+def read_json(url: str) -> dict[str, Any]:
+ with fetch(url) as response:
+ return json.load(response)
+
+
+def read_text(url: str) -> str:
+ with fetch(url) as response:
+ return response.read().decode("utf-8")
+
+
+def audit_publisher_checksum(
+ label: str, artifact: dict[str, Any], checksum_url: str
+) -> None:
+ filename = Path(urllib.parse.unquote(urllib.parse.urlparse(artifact["url"]).path)).name
+ checksums = {}
+ for line in read_text(checksum_url).splitlines():
+ fields = line.split(maxsplit=1)
+ if len(fields) == 2:
+ checksums[fields[1].lstrip("* ")] = fields[0].lower()
+ actual = checksums.get(filename)
+ if actual != artifact["sha256"].lower():
+ raise RuntimeError(f"{label}: pin does not match publisher checksum metadata")
+ print(f"verified publisher checksum: {label} (sha256:{actual})")
+
+
+def hash_url(label: str, artifact: dict[str, Any]) -> None:
+ digest = hashlib.sha256()
+ size = 0
+ with fetch(artifact["url"]) as response:
+ while chunk := response.read(1024 * 1024):
+ digest.update(chunk)
+ size += len(chunk)
+ actual_hash = digest.hexdigest()
+ expected_hash = artifact["sha256"].lower()
+ expected_size = artifact["size"]
+ if (size, actual_hash) != (expected_size, expected_hash):
+ raise RuntimeError(
+ f"{label}: expected {expected_size} bytes/{expected_hash}, "
+ f"received {size} bytes/{actual_hash}"
+ )
+ print(f"verified bytes: {label} ({size} bytes, sha256:{actual_hash})")
+
+
+def unique_artifacts(artifacts: list[dict[str, Any]]) -> list[dict[str, Any]]:
+ unique: dict[str, dict[str, Any]] = {}
+ for artifact in artifacts:
+ path = artifact["path"]
+ prior = unique.get(path)
+ if prior is not None and (
+ prior["size"], prior["sha256"]
+ ) != (artifact["size"], artifact["sha256"]):
+ raise RuntimeError(f"manifest disagrees about duplicate artifact {path}")
+ unique[path] = artifact
+ return list(unique.values())
+
+
+def audit_model_metadata(
+ label: str, models: dict[str, Any], artifacts: list[dict[str, Any]]
+) -> None:
+ endpoint = (
+ f"https://huggingface.co/api/models/{models['repo']}/revision/"
+ f"{models['revision']}?blobs=true"
+ )
+ document = read_json(endpoint)
+ siblings = {item["rfilename"]: item for item in document.get("siblings", [])}
+ for artifact in unique_artifacts(artifacts):
+ path = artifact["path"]
+ sibling = siblings.get(path)
+ if sibling is None:
+ raise RuntimeError(f"model revision does not contain {path}")
+ lfs = sibling.get("lfs") or {}
+ actual_hash = lfs.get("sha256") or lfs.get("oid", "").removeprefix("sha256:")
+ actual_size = lfs.get("size", sibling.get("size"))
+ if (actual_size, actual_hash) != (artifact["size"], artifact["sha256"].lower()):
+ raise RuntimeError(
+ f"{path}: manifest does not match immutable revision LFS metadata"
+ )
+ print(
+ f"verified LFS object ({label}): {path} "
+ f"({actual_size} bytes, sha256:{actual_hash})"
+ )
+
+
+def audit_model_bytes(
+ label: str, models: dict[str, Any], artifacts: list[dict[str, Any]]
+) -> None:
+ for artifact in unique_artifacts(artifacts):
+ direct = {
+ **artifact,
+ "url": (
+ f"https://huggingface.co/{models['repo']}/resolve/"
+ f"{models['revision']}/{artifact['path']}?download=true"
+ ),
+ }
+ hash_url(f"{label}: {artifact['path']}", direct)
+
+
+def audit_lock(path: Path) -> None:
+ lock = path.read_text(encoding="utf-8")
+ packages = re.findall(r"(?m)^[A-Za-z0-9_.-]+==[^ \\\n]+", lock)
+ hashes = re.findall(r"--hash=sha256:[0-9a-f]{64}", lock)
+ if not packages or not hashes:
+ raise RuntimeError("dependency lock is missing packages or SHA-256 hashes")
+ blocks = re.split(r"(?m)(?=^[A-Za-z0-9_.-]+==)", lock)
+ unpinned = [
+ block.split("==", 1)[0]
+ for block in blocks
+ if "==" in block and "--hash=" not in block
+ ]
+ if unpinned:
+ raise RuntimeError(f"dependency lock entries lack hashes: {', '.join(unpinned)}")
+ print(
+ f"verified lock structure: {path.name}: "
+ f"{len(packages)} packages, {len(hashes)} SHA-256 hashes"
+ )
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--include-model-bytes",
+ action="store_true",
+ help="download and hash both backends' model objects (roughly 23 GB)",
+ )
+ args = parser.parse_args()
+ pin = json.loads(PIN_PATH.read_text(encoding="utf-8"))
+ tflite_pin = json.loads(TFLITE_PIN_PATH.read_text(encoding="utf-8"))
+
+ hash_url("Stable Audio 3 source", pin["source"])
+ for runtime in pin["runtime"]["uv"]:
+ audit_publisher_checksum(
+ f"uv {runtime['version']} ({runtime['target']})",
+ runtime,
+ f"{runtime['url']}.sha256",
+ )
+ hash_url(f"uv {runtime['version']} ({runtime['target']})", runtime)
+ for runtime in pin["runtime"]["python"]:
+ release_match = re.search(r"/releases/download/([^/]+)/", runtime["url"])
+ if release_match is None:
+ raise RuntimeError("Python runtime URL does not identify an immutable release")
+ release = release_match.group(1)
+ audit_publisher_checksum(
+ f"Python {runtime['version']} ({runtime['target']})",
+ runtime,
+ "https://github.com/astral-sh/python-build-standalone/"
+ f"releases/download/{release}/SHA256SUMS",
+ )
+ hash_url(f"Python {runtime['version']} ({runtime['target']})", runtime)
+ mlx_artifacts = pin["models"]["artifacts"]
+ tflite_artifacts = [
+ *tflite_pin["models"]["shared"],
+ *[
+ artifact
+ for bundle in tflite_pin["models"]["bundles"].values()
+ for artifact in bundle
+ ],
+ ]
+ audit_model_metadata("MLX", pin["models"], mlx_artifacts)
+ audit_model_metadata("TFLite", tflite_pin["models"], tflite_artifacts)
+ if args.include_model_bytes:
+ audit_model_bytes("MLX", pin["models"], mlx_artifacts)
+ audit_model_bytes("TFLite", tflite_pin["models"], tflite_artifacts)
+ for lock_path in LOCK_PATHS:
+ audit_lock(lock_path)
+ print("SA3 pin audit complete")
+ return 0
+
+
+if __name__ == "__main__":
+ try:
+ raise SystemExit(main())
+ except (OSError, RuntimeError, ValueError, json.JSONDecodeError) as error:
+ print(f"SA3 pin audit failed: {error}", file=sys.stderr)
+ raise SystemExit(1)
diff --git a/scripts/build-linux-appimage.sh b/scripts/build-linux-appimage.sh
new file mode 100755
index 0000000..d99c9fb
--- /dev/null
+++ b/scripts/build-linux-appimage.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+# Build and verify LSDJ's Ubuntu 22.04-compatible x86_64 AppImage. Model
+# runtimes/weights are external, verified, and app-managed; this shell exists
+# only on the release builder and is not part of the installed runtime.
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+LINUX_CONFIG="$REPO_ROOT/src-tauri/tauri.linux.conf.json"
+RELEASE_VERSION="${LSDJ_RELEASE_VERSION:-}"
+AUDIT_PATH="${LSDJ_LINUX_AUDIT_PATH:-$REPO_ROOT/src-tauri/target/release/bundle/appimage/linux-package-audit.json}"
+
+fail() {
+ echo "Linux release: $*" >&2
+ exit 1
+}
+
+[ "$(uname -s)" = "Linux" ] || fail "must be built on Linux"
+[ "$(uname -m)" = "x86_64" ] || fail "must be built for x86_64"
+
+GLIBC_DESCRIPTION="$(getconf GNU_LIBC_VERSION 2>/dev/null || true)"
+[[ "$GLIBC_DESCRIPTION" =~ ^glibc\ ([0-9]+)\.([0-9]+)$ ]] || fail \
+ "an auditable glibc build host is required"
+GLIBC_MAJOR="${BASH_REMATCH[1]}"
+GLIBC_MINOR="${BASH_REMATCH[2]}"
+if (( GLIBC_MAJOR > 2 || (GLIBC_MAJOR == 2 && GLIBC_MINOR > 35) )); then
+ fail "build host glibc $GLIBC_MAJOR.$GLIBC_MINOR is newer than Ubuntu 22.04's 2.35 floor"
+fi
+
+VERSION_ARGS=()
+if [ -n "$RELEASE_VERSION" ]; then
+ [[ "$RELEASE_VERSION" =~ ^v?([0-9]{4})\.(0[1-9]|1[0-2])\.([1-9][0-9]*)$ ]] || fail \
+ "LSDJ_RELEASE_VERSION must look like vYYYY.MM.N with a positive release number"
+ RELEASE_YEAR=$((10#${BASH_REMATCH[1]}))
+ RELEASE_MONTH=$((10#${BASH_REMATCH[2]}))
+ RELEASE_NUMBER=$((10#${BASH_REMATCH[3]}))
+ RELEASE_VERSION="${RELEASE_YEAR}.${RELEASE_MONTH}.${RELEASE_NUMBER}"
+ VERSION_ARGS=(--config "{\"version\":\"$RELEASE_VERSION\"}")
+fi
+
+echo "Linux release: building frontend"
+npm run build --prefix "$REPO_ROOT/frontend"
+
+echo "Linux release: building AppImage on glibc $GLIBC_MAJOR.$GLIBC_MINOR"
+(
+ cd "$REPO_ROOT/src-tauri"
+ cargo tauri build --ci \
+ --features managed-runtime \
+ --config "$LINUX_CONFIG" \
+ "${VERSION_ARGS[@]}"
+)
+
+shopt -s nullglob
+APPIMAGES=("$REPO_ROOT"/src-tauri/target/release/bundle/appimage/*.AppImage)
+[[ "${#APPIMAGES[@]}" -eq 1 ]] || fail \
+ "expected exactly one AppImage, found ${#APPIMAGES[@]}"
+
+python3 "$REPO_ROOT/scripts/verify_linux_appimage.py" \
+ "${APPIMAGES[0]}" \
+ --output "$AUDIT_PATH"
+
+echo "Linux release: verified ${APPIMAGES[0]}"
+echo "Linux release: native dependency audit $AUDIT_PATH"
diff --git a/scripts/build-macos-release.sh b/scripts/build-macos-release.sh
index 668889b..d528195 100755
--- a/scripts/build-macos-release.sh
+++ b/scripts/build-macos-release.sh
@@ -11,6 +11,7 @@ DMG_DIR="$REPO_ROOT/src-tauri/target/release/bundle/dmg"
BACKEND_DIR="$REPO_ROOT/src-tauri/sidecar-dist/lsdj_backend"
BACKEND_BIN="$BACKEND_DIR/lsdj_backend"
RELEASE_CONFIG="$REPO_ROOT/src-tauri/tauri.release.conf.json"
+MACOS_CONFIG="$REPO_ROOT/src-tauri/tauri.macos.conf.json"
ENTITLEMENTS="$REPO_ROOT/src-tauri/entitlements.plist"
RELEASE_VERSION="${LSDJ_RELEASE_VERSION:-}"
EXPECTED_BUNDLE_ID="works.protocol.lsdj"
@@ -136,11 +137,13 @@ echo "macOS release: building, signing, notarizing, and stapling"
if [ -n "$RELEASE_VERSION" ]; then
cargo tauri build --ci \
--features bundled-backend \
+ --config "$MACOS_CONFIG" \
--config "$RELEASE_CONFIG" \
--config "{\"version\":\"$RELEASE_VERSION\"}"
else
cargo tauri build --ci \
--features bundled-backend \
+ --config "$MACOS_CONFIG" \
--config "$RELEASE_CONFIG"
fi
)
diff --git a/scripts/build-windows-installer.ps1 b/scripts/build-windows-installer.ps1
new file mode 100644
index 0000000..91afd60
--- /dev/null
+++ b/scripts/build-windows-installer.ps1
@@ -0,0 +1,111 @@
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $true)]
+ [ValidatePattern('^v[0-9]{4}\.(0[1-9]|1[0-2])\.[1-9][0-9]*$')]
+ [string] $ReleaseTag,
+
+ [switch] $Release,
+
+ [switch] $UnsignedDevelopment
+)
+
+$ErrorActionPreference = 'Stop'
+Set-StrictMode -Version Latest
+
+if (-not $IsWindows -or -not [Environment]::Is64BitOperatingSystem -or -not [Environment]::Is64BitProcess) {
+ throw 'LSDJ Windows installers must be built by a 64-bit process on Windows x64.'
+}
+if ($Release -eq $UnsignedDevelopment) {
+ throw 'Choose exactly one of -Release or -UnsignedDevelopment.'
+}
+
+$match = [regex]::Match($ReleaseTag, '^v(?