From 0e43f31d3d32db873ac5fe034509f8a74802f3d4 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 18:29:29 -0500 Subject: [PATCH 01/58] ci: shorten pr workflow critical path --- .github/workflows/julia-release.yml | 14 ++ .github/workflows/python-release.yml | 180 ++++++++++++-- .github/workflows/python-test.yml | 350 ++++++++++++++++++--------- Justfile | 31 +++ 4 files changed, 448 insertions(+), 127 deletions(-) diff --git a/.github/workflows/julia-release.yml b/.github/workflows/julia-release.yml index 113a9548e..71c16c637 100644 --- a/.github/workflows/julia-release.yml +++ b/.github/workflows/julia-release.yml @@ -26,12 +26,26 @@ on: - master tags: - 'jl-*' # Trigger on Julia-specific tags + paths: + - 'julia/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'scripts/ci/**' + - '.github/workflows/julia-release.yml' pull_request: branches: - main - dev - development - master + paths: + - 'julia/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'scripts/ci/**' + - '.github/workflows/julia-release.yml' workflow_dispatch: inputs: sha: diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 34ce638ec..ae2697c70 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -19,12 +19,32 @@ on: - master tags: - 'py-*' + paths: + - 'python/pecos-rslib/**' + - 'python/pecos-rslib-llvm/**' + - 'python/quantum-pecos/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'uv.lock' + - 'scripts/ci/**' + - '.github/workflows/python-release.yml' pull_request: branches: - main - dev - development - master + paths: + - 'python/pecos-rslib/**' + - 'python/pecos-rslib-llvm/**' + - 'python/quantum-pecos/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'uv.lock' + - 'scripts/ci/**' + - '.github/workflows/python-release.yml' workflow_dispatch: inputs: sha: @@ -44,45 +64,175 @@ defaults: shell: bash jobs: - check_pr_push: + resolve_release_mode: runs-on: ubuntu-latest if: | github.event_name == 'pull_request' && github.event.action != 'closed' || github.event_name == 'push' && contains(fromJSON('["main", "master", "dev", "development"]'), github.ref_name) || - github.event_name == 'push' && startsWith(github.ref, 'refs/tags/py-') + github.event_name == 'push' && startsWith(github.ref, 'refs/tags/py-') || + github.event_name == 'workflow_dispatch' outputs: - run: ${{ steps.check.outputs.run }} + pr_smoke: ${{ steps.mode.outputs.pr_smoke }} + full_release: ${{ steps.mode.outputs.full_release }} steps: - name: Harden the runner (egress audit) uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - name: Check if should run on PR push - id: check + - name: Resolve release mode + id: mode env: EVENT_NAME: ${{ github.event_name }} REF: ${{ github.ref }} REF_NAME: ${{ github.ref_name }} TRIGGER_ON_PR_PUSH_VALUE: ${{ env.TRIGGER_ON_PR_PUSH }} run: | - # Always run on tag pushes (py-* tags trigger releases) - if [ "$EVENT_NAME" = "push" ] && [[ "$REF" == refs/tags/py-* ]]; then - echo "run=true" >> $GITHUB_OUTPUT - # Always run on pushes to main branches + if [ "$EVENT_NAME" = "workflow_dispatch" ]; then + echo "pr_smoke=false" >> $GITHUB_OUTPUT + echo "full_release=true" >> $GITHUB_OUTPUT + elif [ "$EVENT_NAME" = "push" ] && [[ "$REF" == refs/tags/py-* ]]; then + echo "pr_smoke=false" >> $GITHUB_OUTPUT + echo "full_release=true" >> $GITHUB_OUTPUT elif [ "$EVENT_NAME" = "push" ] && [[ "$REF_NAME" =~ ^(main|master|dev|development)$ ]]; then - echo "run=true" >> $GITHUB_OUTPUT - # For PRs, check the TRIGGER_ON_PR_PUSH setting + echo "pr_smoke=false" >> $GITHUB_OUTPUT + echo "full_release=true" >> $GITHUB_OUTPUT elif [ "$EVENT_NAME" = "pull_request" ] && [ "$TRIGGER_ON_PR_PUSH_VALUE" = "true" ]; then - echo "run=true" >> $GITHUB_OUTPUT + echo "pr_smoke=true" >> $GITHUB_OUTPUT + echo "full_release=false" >> $GITHUB_OUTPUT else - echo "run=false" >> $GITHUB_OUTPUT + echo "pr_smoke=false" >> $GITHUB_OUTPUT + echo "full_release=false" >> $GITHUB_OUTPUT fi + pr_smoke_build: + needs: resolve_release_mode + if: needs.resolve_release_mode.outputs.pr_smoke == 'true' + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Harden the runner (egress audit) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + ref: ${{ inputs.sha || github.sha }} + submodules: recursive + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.12" + + - name: Install uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + enable-cache: true + + - name: Set up Rust + run: | + bash scripts/ci/ensure-rust.sh stable minimal + export PATH="$HOME/.cargo/bin:$PATH" + rustup show + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Cache Rust + uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + with: + cache-bin: false + prefix-key: v1-rust-no-bin + workspaces: | + python/pecos-rslib + python/pecos-rslib-llvm + + - name: Cache LLVM + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-14.0.6-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM + run: just ci-env + + - name: Sync Python dependencies + run: just python-ci-sync + + - name: Build pecos-rslib wheel + run: | + mkdir -p dist/pecos-rslib + uv run --frozen maturin build --locked --manifest-path python/pecos-rslib/Cargo.toml --out dist/pecos-rslib + + - name: Build pecos-rslib-llvm wheel + run: | + mkdir -p dist/pecos-rslib-llvm + uv run --frozen maturin build --locked --manifest-path python/pecos-rslib-llvm/Cargo.toml --out dist/pecos-rslib-llvm + + - name: Build quantum-pecos wheel + run: | + mkdir -p dist/quantum-pecos + cd python/quantum-pecos + uv run --frozen python -m build --wheel --outdir ../../dist/quantum-pecos + + - name: Upload PR smoke artifacts + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: pr-smoke-python-artifacts + path: | + dist/pecos-rslib/*.whl + dist/pecos-rslib-llvm/*.whl + dist/quantum-pecos/*.whl + + pr_smoke_test: + needs: [resolve_release_mode, pr_smoke_build] + if: needs.resolve_release_mode.outputs.pr_smoke == 'true' + runs-on: ubuntu-latest + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + python-version: ['3.10', '3.14'] + steps: + - name: Harden the runner (egress audit) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + + - name: Download PR smoke artifacts + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + name: pr-smoke-python-artifacts + path: ./pr-smoke-artifacts + + - name: Install PR smoke artifacts + run: | + uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos_rslib-*.whl + uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos_rslib_llvm-*.whl + uv pip install --system --force-reinstall ./pr-smoke-artifacts/quantum_pecos-*.whl + + - name: Import PR smoke artifacts + run: | + python -c 'import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": pecos_rslib_llvm.__version__})' build_wheelspecos_rslib: - needs: check_pr_push - if: needs.check_pr_push.result == 'success' && needs.check_pr_push.outputs.run == 'true' + needs: resolve_release_mode + if: needs.resolve_release_mode.outputs.full_release == 'true' runs-on: ${{ matrix.runner || matrix.os }} strategy: fail-fast: false diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index eebabcc52..ca62d0640 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -4,20 +4,37 @@ permissions: contents: read env: - TRIGGER_ON_PR_PUSH: true # Set to true to enable triggers on PR pushes + TRIGGER_ON_PR_PUSH: true RUSTFLAGS: -C debuginfo=0 RUST_BACKTRACE: 1 PYTHONUTF8: 1 LLVM_VERSION: "14.0.6" - # Force the MWPF decoder feature on in CI so we exercise the cmake-dependent - # build path and catch regressions. GitHub-hosted runners ship cmake. - PECOS_BUILD_MWPF: "1" on: push: branches: [ "main", "master", "development", "dev" ] + paths: + - 'python/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'uv.lock' + - 'Justfile' + - 'scripts/ci/**' + - 'scripts/check_python_workspace.py' + - '.github/workflows/python-test.yml' pull_request: branches: [ "main", "master", "development", "dev" ] + paths: + - 'python/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'uv.lock' + - 'Justfile' + - 'scripts/ci/**' + - 'scripts/check_python_workspace.py' + - '.github/workflows/python-test.yml' workflow_dispatch: concurrency: @@ -29,17 +46,147 @@ defaults: shell: bash jobs: - python-test: + python-lint: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Harden the runner (egress audit) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.12" + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + enable-cache: true + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + + - name: Set up Rust + run: | + bash scripts/ci/ensure-rust.sh stable minimal + export PATH="$HOME/.cargo/bin:$PATH" + rustup show + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Cache Rust + uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + with: + cache-bin: false + prefix-key: v1-rust-no-bin + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + + - name: Sync Python dependencies + run: just python-ci-sync + + - name: Run linting + run: just lint check + + python-core: + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + PECOS_BUILD_MWPF: "1" + steps: + - name: Harden the runner (egress audit) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + android: true + dotnet: true + haskell: true + large-packages: false + docker-images: true + tool-cache: false + swap-storage: true + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.12" + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + enable-cache: true + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + + - name: Set up Rust + run: | + bash scripts/ci/ensure-rust.sh stable minimal + export PATH="$HOME/.cargo/bin:$PATH" + rustup show + + - name: Verify cmake is available (MWPF decoder build) + run: cmake --version + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Cache Rust + uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + with: + cache-bin: false + prefix-key: v1-rust-no-bin + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + workspaces: | + python/pecos-rslib + python/pecos-rslib-llvm + + - name: Cache LLVM ${{ env.LLVM_VERSION }} + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + run: just ci-env + + - name: Save LLVM ${{ env.LLVM_VERSION }} cache + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: ${{ steps.cache-llvm.outputs.cache-primary-key }} + + - name: Build core Python packages + run: just python-ci-build + + - name: Run core Python tests + run: just pytest-ci-core + + python-compat-smoke: runs-on: ${{ matrix.os }} - timeout-minutes: 120 + timeout-minutes: 30 strategy: fail-fast: false matrix: - # Full Python version matrix on Ubuntu (fast) - os: [ubuntu-latest] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] include: - # Windows/macOS: only test oldest and newest stable Python (slow platforms) + - os: ubuntu-latest + python-version: "3.10" + - os: ubuntu-latest + python-version: "3.14" - os: windows-2022 python-version: "3.10" - os: windows-2022 @@ -86,19 +233,12 @@ jobs: with: python-version: ${{ matrix.python-version }} - # No Windows-special MSVC setup here: the first cargo invocation is - # `just ci-env`, whose `_msvc-bootstrap` prerequisite runs - # scripts/win-msvc-bootstrap.ps1 and writes the linker + LIB/INCLUDE into - # .cargo/config.toml (read by cargo after it spawns, so it survives - # git-bash). CI is therefore structurally identical to Linux/macOS, and a - # local Windows dev gets the exact same path via the same just prereq. - - name: Install the latest version of uv uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') }} + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Set up Rust (Windows) if: runner.os == 'Windows' @@ -118,9 +258,6 @@ jobs: export PATH="$HOME/.cargo/bin:$PATH" rustup show - - name: Verify cmake is available (MWPF decoder build) - run: cmake --version - - name: Install just uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 @@ -129,12 +266,11 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') }} + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm - # Cache LLVM installation (fixed version, only varies by OS) - name: Cache LLVM ${{ env.LLVM_VERSION }} id: cache-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 @@ -142,108 +278,103 @@ jobs: path: ~/.pecos/deps/llvm-14 key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - # `just ci-env` is the first cargo invocation. Its `_msvc-bootstrap` - # prerequisite writes the MSVC linker + LIB/INCLUDE into - # .cargo/config.toml on Windows (no-op elsewhere); LLVM is configured into - # the same file by `pecos setup` during the build. Nothing Windows-special - # is needed at the workflow level. - name: Ensure LLVM ${{ env.LLVM_VERSION }} run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 key: ${{ steps.cache-llvm.outputs.cache-primary-key }} - - name: Install PECOS CLI - run: cargo install --locked --path crates/pecos-cli --force + - name: Run Python compatibility smoke test + run: just python-ci-smoke - # macOS: prevent Homebrew library path issues - - name: Configure macOS environment - if: runner.os == 'macOS' - run: | - # Prevent Homebrew library paths from causing @rpath/libunwind errors - # Reference: https://github.com/rust-lang/rust/issues/135372 - echo "MPLBACKEND=Agg" >> $GITHUB_ENV - echo "OPENBLAS_NUM_THREADS=1" >> $GITHUB_ENV - echo "MKL_NUM_THREADS=1" >> $GITHUB_ENV - echo "NUMEXPR_NUM_THREADS=1" >> $GITHUB_ENV - echo "OMP_NUM_THREADS=1" >> $GITHUB_ENV - echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV - - - name: Build PECOS (macOS) - if: runner.os == 'macOS' - run: | - # Prevent Homebrew library paths from causing @rpath/libunwind errors - unset LIBRARY_PATH LD_LIBRARY_PATH DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH PKG_CONFIG_PATH - export LIBRARY_PATH=/usr/lib - just build-debug + python-slow-postmerge: + if: github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + runs-on: ubuntu-latest + timeout-minutes: 90 + env: + PECOS_BUILD_MWPF: "1" + steps: + - name: Harden the runner (egress audit) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit - - name: Build PECOS - if: runner.os != 'macOS' - run: just build-debug + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + android: true + dotnet: true + haskell: true + large-packages: false + docker-images: true + tool-cache: false + swap-storage: true - - name: Verify macOS extension module - if: runner.os == 'macOS' - run: | - EXT_MODULE=$(find .venv/lib -name "pecos_rslib*.so" 2>/dev/null | head -1) - if [ -n "$EXT_MODULE" ]; then - if otool -L "$EXT_MODULE" | grep -q "@rpath/libunwind"; then - echo "ERROR: Extension has @rpath/libunwind reference" - otool -L "$EXT_MODULE" - exit 1 - fi - echo "macOS extension module OK" - fi + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false - - name: Run Python tests - run: just pytest + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.14" - - name: Run slow Python tests - # Only run on the primary Linux/newest-Python cell to keep the full - # matrix fast. Dropping this entirely would let the `slow` lane - # silently atrophy, which is exactly what the `slow` marker is - # supposed to prevent. - # - # The `3.14` literal below must track the newest entry of the - # `python-version` matrix at the top of this file (line ~34). Bump - # both together. - if: runner.os == 'Linux' && matrix.python-version == '3.14' - run: just pytest-slow + - name: Install the latest version of uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + enable-cache: true + save-cache: true - - name: Install integrity check tools + - name: Set up Rust run: | - if command -v rg >/dev/null 2>&1; then - exit 0 - fi - - case "$RUNNER_OS" in - Linux) - sudo apt-get update - sudo apt-get install -y ripgrep - ;; - macOS) - HOMEBREW_NO_AUTO_UPDATE=1 brew install ripgrep - ;; - Windows) - cargo install --locked --version 14.1.1 ripgrep - ;; - *) - echo "Unsupported runner OS for ripgrep install: $RUNNER_OS" >&2 - exit 1 - ;; - esac + bash scripts/ci/ensure-rust.sh stable minimal + export PATH="$HOME/.cargo/bin:$PATH" + rustup show - - name: Run linting - run: just lint check + - name: Verify cmake is available (MWPF decoder build) + run: cmake --version + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Cache Rust + uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + with: + cache-bin: false + prefix-key: v1-rust-no-bin + save-if: true + workspaces: | + python/pecos-rslib + python/pecos-rslib-llvm + + - name: Cache LLVM ${{ env.LLVM_VERSION }} + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + run: just ci-env + + - name: Save LLVM ${{ env.LLVM_VERSION }} cache + if: steps.cache-llvm.outputs.cache-hit != 'true' + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: ${{ steps.cache-llvm.outputs.cache-primary-key }} + + - name: Build core Python packages + run: just python-ci-build + + - name: Run slow Python tests + run: just pytest-slow - # Audience-B contract: a crates.io consumer builds the publishable crates - # with plain `cargo` on Windows -- no `just`, no git-bash, no generated - # .cargo/config.toml, none of the MSVC bootstrap. This proves the git-bash - # remediation is confined to the dev/CI tooling and never leaks into the - # crates themselves. Fails closed if a repo config.toml is present. windows-vanilla-cargo: name: Windows vanilla cargo (crates.io consumer contract) runs-on: windows-2022 @@ -276,11 +407,6 @@ jobs: exit 1 } - # pecos-build (where the toml_edit work lives) and pecos-core are - # publishable and need no LLVM/FFI/external toolchain -- the right - # minimal canary. LLVM-needing crates additionally require the upstream - # llvm-sys LLVM_SYS_140_PREFIX (a universal llvm-sys requirement, not a - # PECOS workaround) and are out of scope for this contract lane. - name: Vanilla cargo check (publishable crates, no just/bootstrap) shell: pwsh run: cargo check --locked -p pecos-build -p pecos-core diff --git a/Justfile b/Justfile index 470aee204..c011920a8 100644 --- a/Justfile +++ b/Justfile @@ -207,6 +207,14 @@ build-cuda profile="debug": _msvc-bootstrap (validate-profile "build-cuda" profi PROFILE="{{profile}}" {{pecos}} python build --profile "$PROFILE" --cuda +# Build only the Python workspace members needed by the fast CI lanes. +[group('build')] +python-ci-build profile="debug": _msvc-bootstrap (validate-profile "python-ci-build" profile) python-ci-sync + #!/usr/bin/env bash + set -euo pipefail + PROFILE="{{profile}}" + {{pecos}} python build --profile "$PROFILE" --no-cuda + # ============================================================================= # Testing # ============================================================================= @@ -223,6 +231,18 @@ pytest *args: uv run --frozen --group numpy-compat pytest python/pecos-rslib/tests -m "numpy and not performance" uv run --frozen pytest python/quantum-pecos/tests -m "not optional_dependency and not slow" uv run --frozen pytest python/selene-plugins + +# Fast Python validation for PR CI. Selene plugin coverage stays in its own workflow. +[group('test')] +pytest-ci-core: + uv run --frozen pytest python/pecos-rslib/tests -m "not performance" + uv run --frozen --group numpy-compat pytest python/pecos-rslib/tests -m "numpy and not performance" + uv run --frozen pytest python/quantum-pecos/tests -m "not optional_dependency and not slow" + +# Build and import the core Python packages on a target platform/interpreter. +[group('test')] +python-ci-smoke profile="debug": (python-ci-build profile) + uv run --frozen python -c "import pecos, pecos_rslib, pecos_rslib_llvm; print({'pecos': pecos.__version__, 'pecos_rslib': pecos_rslib.__version__, 'pecos_rslib_llvm': pecos_rslib_llvm.__version__})" fi # Run Rust tests (CUDA-aware; mode: dev/debug, release, native) @@ -806,6 +826,17 @@ sync-deps: fi uv sync "${SYNC_ARGS[@]}" +[group('setup')] +python-ci-sync: + #!/usr/bin/env bash + set -euo pipefail + uv sync --locked \ + --group dev \ + --group test \ + --package pecos-rslib \ + --package pecos-rslib-llvm \ + --package quantum-pecos + # Windows MSVC bootstrap: write the correct linker + LIB/INCLUDE into # .cargo/config.toml (read by cargo *after* it spawns, so it bypasses # git-bash's link.exe shadowing and LIB mangling). Scoped TOML merge -- it From 70a4f6e1bcb302022a0da20948b9f4e4c1800676 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 20:04:57 -0500 Subject: [PATCH 02/58] ci: fix workflow cache policy and julia triggers --- .github/workflows/julia-test.yml | 14 ++++++++++++++ .github/workflows/python-release.yml | 2 ++ .github/workflows/python-test.yml | 22 +++++++++++----------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/.github/workflows/julia-test.yml b/.github/workflows/julia-test.yml index 8c2c26a3c..fbc689794 100644 --- a/.github/workflows/julia-test.yml +++ b/.github/workflows/julia-test.yml @@ -22,8 +22,22 @@ env: on: push: branches: [ "main", "master", "development", "dev" ] + paths: + - 'julia/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'scripts/ci/**' + - '.github/workflows/julia-test.yml' pull_request: branches: [ "main", "master", "development", "dev" ] + paths: + - 'julia/**' + - 'crates/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'scripts/ci/**' + - '.github/workflows/julia-test.yml' workflow_dispatch: concurrency: diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index ae2697c70..c5ab9566f 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -132,6 +132,7 @@ jobs: with: version: "0.11.14" enable-cache: true + save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} - name: Set up Rust run: | @@ -147,6 +148,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin + save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index ca62d0640..d4720dbac 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -69,7 +69,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} - name: Set up Rust run: | @@ -85,7 +85,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} - name: Sync Python dependencies run: just python-ci-sync @@ -129,7 +129,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} - name: Set up Rust run: | @@ -148,7 +148,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm @@ -164,7 +164,7 @@ jobs: run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && github.ref_name == 'main' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 @@ -238,7 +238,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} - name: Set up Rust (Windows) if: runner.os == 'Windows' @@ -266,7 +266,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm @@ -282,7 +282,7 @@ jobs: run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && github.ref_name == 'main' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 @@ -328,7 +328,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: true + save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} - name: Set up Rust run: | @@ -347,7 +347,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: true + save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm @@ -363,7 +363,7 @@ jobs: run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && github.ref_name == 'main' uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 From 0da0c27b0d05444d32c5cbdda4d8364608a95419 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 20:15:24 -0500 Subject: [PATCH 03/58] ci: narrow julia test triggers --- .github/workflows/julia-test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/julia-test.yml b/.github/workflows/julia-test.yml index fbc689794..1c7bcf62e 100644 --- a/.github/workflows/julia-test.yml +++ b/.github/workflows/julia-test.yml @@ -28,7 +28,6 @@ on: - 'Cargo.toml' - 'Cargo.lock' - 'scripts/ci/**' - - '.github/workflows/julia-test.yml' pull_request: branches: [ "main", "master", "development", "dev" ] paths: @@ -37,7 +36,6 @@ on: - 'Cargo.toml' - 'Cargo.lock' - 'scripts/ci/**' - - '.github/workflows/julia-test.yml' workflow_dispatch: concurrency: From 6e33b23009a6d43f461281e6547e070ec761b5f8 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 20:18:50 -0500 Subject: [PATCH 04/58] ci: align cache policy with trusted branches --- .github/workflows/python-release.yml | 4 ++-- .github/workflows/python-test.yml | 22 +++++++++++----------- scripts/dependency-integrity-check.sh | 7 ++++--- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index c5ab9566f..0e3bb32e9 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -132,7 +132,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Set up Rust run: | @@ -148,7 +148,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index d4720dbac..762add0b7 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -69,7 +69,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Set up Rust run: | @@ -85,7 +85,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Sync Python dependencies run: just python-ci-sync @@ -129,7 +129,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Set up Rust run: | @@ -148,7 +148,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm @@ -164,7 +164,7 @@ jobs: run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && github.ref_name == 'main' + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 @@ -238,7 +238,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Set up Rust (Windows) if: runner.os == 'Windows' @@ -266,7 +266,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm @@ -282,7 +282,7 @@ jobs: run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && github.ref_name == 'main' + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 @@ -328,7 +328,7 @@ jobs: with: version: "0.11.14" enable-cache: true - save-cache: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Set up Rust run: | @@ -347,7 +347,7 @@ jobs: with: cache-bin: false prefix-key: v1-rust-no-bin - save-if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} workspaces: | python/pecos-rslib python/pecos-rslib-llvm @@ -363,7 +363,7 @@ jobs: run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && github.ref_name == 'main' + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 diff --git a/scripts/dependency-integrity-check.sh b/scripts/dependency-integrity-check.sh index e1718685d..8dcb2c11f 100755 --- a/scripts/dependency-integrity-check.sh +++ b/scripts/dependency-integrity-check.sh @@ -399,8 +399,9 @@ fi section "GitHub Actions cache write posture" cache_policy_failures=() +trusted_cache_ref_re="github\\.ref_name == '(main|master|development|dev)'|contains\\(fromJSON\\('\\[\\\"main\\\", \\\"master\\\", \\\"development\\\", \\\"dev\\\"\\]'\\), github\\.ref_name\\)" while IFS=: read -r file line _; do - if ! sed -n "${line},$((line + 16))p" "$file" | rg -q "save-if:.*github\.event_name == 'push'.*github\.ref_name == 'main'"; then + if ! sed -n "${line},$((line + 16))p" "$file" | rg -q "save-if:.*github\.event_name == 'push'.*($trusted_cache_ref_re)"; then cache_policy_failures+=("$file:$line rust-cache save-if must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+Swatinem/rust-cache@' .github/workflows || true) @@ -408,7 +409,7 @@ done < <(rg -n 'uses:\s+Swatinem/rust-cache@' .github/workflows || true) while IFS=: read -r file line _; do setup_uv_block="$(sed -n "${line},$((line + 16))p" "$file")" if printf '%s\n' "$setup_uv_block" | rg -q 'enable-cache:\s*true' && - ! printf '%s\n' "$setup_uv_block" | rg -q "save-cache:.*github\.event_name == 'push'.*github\.ref_name == 'main'"; then + ! printf '%s\n' "$setup_uv_block" | rg -q "save-cache:.*github\.event_name == 'push'.*($trusted_cache_ref_re)"; then cache_policy_failures+=("$file:$line setup-uv save-cache must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+astral-sh/setup-uv@' .github/workflows || true) @@ -418,7 +419,7 @@ while IFS=: read -r file line _; do done < <(rg -n 'uses:\s+actions/cache@' .github/workflows || true) while IFS=: read -r file line _; do - if ! sed -n "$((line - 2)),$((line + 2))p" "$file" | rg -q "if:.*github\.event_name == 'push'.*github\.ref_name == 'main'"; then + if ! sed -n "$((line - 2)),$((line + 2))p" "$file" | rg -q "if:.*github\.event_name == 'push'.*($trusted_cache_ref_re)"; then cache_policy_failures+=("$file:$line actions/cache/save must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+actions/cache/save@' .github/workflows || true) From d1c2341d33dca0dfb6d88c1ec73f9c199e321e5a Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 20:23:04 -0500 Subject: [PATCH 05/58] ci: keep lint lane off llvm package builds --- .github/workflows/python-test.yml | 2 +- Justfile | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 762add0b7..b00e5a756 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -88,7 +88,7 @@ jobs: save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Sync Python dependencies - run: just python-ci-sync + run: just python-ci-sync-lint - name: Run linting run: just lint check diff --git a/Justfile b/Justfile index c011920a8..97c45a6fb 100644 --- a/Justfile +++ b/Justfile @@ -837,6 +837,15 @@ python-ci-sync: --package pecos-rslib-llvm \ --package quantum-pecos +[group('setup')] +python-ci-sync-lint: + #!/usr/bin/env bash + set -euo pipefail + uv sync --locked \ + --group dev \ + --group test \ + --no-install-workspace + # Windows MSVC bootstrap: write the correct linker + LIB/INCLUDE into # .cargo/config.toml (read by cargo *after* it spawns, so it bypasses # git-bash's link.exe shadowing and LIB mangling). Scoped TOML merge -- it From fc6cbdc199490ad6f564512a36fe1a90806282e3 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 20:28:45 -0500 Subject: [PATCH 06/58] ci: provision llvm for python lint lane --- .github/workflows/python-test.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index b00e5a756..1df2470cf 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -86,6 +86,26 @@ jobs: cache-bin: false prefix-key: v1-rust-no-bin save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + workspaces: | + python/pecos-rslib + python/pecos-rslib-llvm + + - name: Cache LLVM ${{ env.LLVM_VERSION }} + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + run: just ci-env + + - name: Save LLVM ${{ env.LLVM_VERSION }} cache + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: ${{ steps.cache-llvm.outputs.cache-primary-key }} - name: Sync Python dependencies run: just python-ci-sync-lint From adefe9f44278f0f38057c9cbd6e20c8ca3129dc2 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 20:40:43 -0500 Subject: [PATCH 07/58] ci: retry ci bootstrap on cargo fetch flakes --- Justfile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Justfile b/Justfile index 97c45a6fb..d4392c85b 100644 --- a/Justfile +++ b/Justfile @@ -58,8 +58,17 @@ setup-ci: _msvc-bootstrap ci-env: _msvc-bootstrap #!/usr/bin/env bash set -euo pipefail - {{pecos}} llvm ensure --managed --no-configure - {{pecos}} env --github-actions + export CARGO_NET_RETRY=10 + for attempt in 1 2 3; do + if {{pecos}} llvm ensure --managed --no-configure && {{pecos}} env --github-actions; then + exit 0 + fi + if [ "$attempt" -eq 3 ]; then + exit 1 + fi + echo "ci-env failed on attempt $attempt; retrying..." + sleep 5 + done # Check development environment for common problems [group('setup')] From fae374dd3eac94a9f80b7ce2edf31e689c3410a8 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 21:09:48 -0500 Subject: [PATCH 08/58] ci: install ripgrep in python lint lane --- .github/workflows/python-test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 1df2470cf..35feb1206 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -80,6 +80,9 @@ jobs: - name: Install just uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + - name: Install ripgrep + run: sudo apt-get update && sudo apt-get install --yes ripgrep + - name: Cache Rust uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: From 1a5c37c8b7d3f2431b5a2a70586459e1c78f0506 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 21:29:37 -0500 Subject: [PATCH 09/58] ci: isolate python lint lane --- .github/workflows/python-test.yml | 2 +- Justfile | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 35feb1206..958a0e97a 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -114,7 +114,7 @@ jobs: run: just python-ci-sync-lint - name: Run linting - run: just lint check + run: just python-ci-lint python-core: runs-on: ubuntu-latest diff --git a/Justfile b/Justfile index d4392c85b..2b79d209a 100644 --- a/Justfile +++ b/Justfile @@ -333,6 +333,29 @@ lint mode="fix": _msvc-bootstrap (validate-lint-mode mode) python-workspace-chec fi fi +# Fast lint lane for Python PR CI. Keep this scoped to Rust + Python checks so +# the Python critical path does not opportunistically pick up Julia/Go tools. +[group('lint')] +python-ci-lint: _msvc-bootstrap python-workspace-check + #!/usr/bin/env bash + set -euo pipefail + if command -v nvcc >/dev/null 2>&1 || [ -n "${CUDA_PATH:-}" ] || [ -d /usr/local/cuda ]; then + CLIPPY_FEATURES="--all-features" + echo "(CUDA detected -- linting with all features)" + else + CLIPPY_FEATURES="" + echo "(No CUDA -- linting with default features only)" + fi + + echo "==> Checking Rust formatting..." + cargo fmt --all -- --check + echo "==> Running clippy..." + cargo clippy --locked --workspace --all-targets $CLIPPY_FEATURES -- -D warnings + echo "==> Running pre-commit..." + uv run --frozen pre-commit run --all-files + echo "==> Running cargo check..." + cargo check --locked --workspace --all-targets + # Run cargo check [group('lint')] check: _msvc-bootstrap From 653815fc0b6a0a10499520ccd4d1cd69ee04d285 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 22:02:18 -0500 Subject: [PATCH 10/58] ci: use package metadata in python smoke --- Justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 2b79d209a..6121ad7d7 100644 --- a/Justfile +++ b/Justfile @@ -251,7 +251,7 @@ pytest-ci-core: # Build and import the core Python packages on a target platform/interpreter. [group('test')] python-ci-smoke profile="debug": (python-ci-build profile) - uv run --frozen python -c "import pecos, pecos_rslib, pecos_rslib_llvm; print({'pecos': pecos.__version__, 'pecos_rslib': pecos_rslib.__version__, 'pecos_rslib_llvm': pecos_rslib_llvm.__version__})" + uv run --frozen python -c "from importlib.metadata import version; import pecos, pecos_rslib, pecos_rslib_llvm; print({'pecos': pecos.__version__, 'pecos_rslib': pecos_rslib.__version__, 'pecos_rslib_llvm': version('pecos-rslib-llvm')})" fi # Run Rust tests (CUDA-aware; mode: dev/debug, release, native) From 6713da1c7f275fb5119303c6c5093523d28b7703 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 24 Jun 2026 22:55:20 -0500 Subject: [PATCH 11/58] ci: fix python fast-lane regressions --- .github/workflows/python-test.yml | 5 +---- Justfile | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 958a0e97a..7bf12ccf5 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -193,11 +193,8 @@ jobs: path: ~/.pecos/deps/llvm-14 key: ${{ steps.cache-llvm.outputs.cache-primary-key }} - - name: Build core Python packages - run: just python-ci-build - - name: Run core Python tests - run: just pytest-ci-core + run: just python-ci-core python-compat-smoke: runs-on: ${{ matrix.os }} diff --git a/Justfile b/Justfile index 6121ad7d7..8ab101486 100644 --- a/Justfile +++ b/Justfile @@ -216,7 +216,7 @@ build-cuda profile="debug": _msvc-bootstrap (validate-profile "build-cuda" profi PROFILE="{{profile}}" {{pecos}} python build --profile "$PROFILE" --cuda -# Build only the Python workspace members needed by the fast CI lanes. +# Build only the Python workspace members needed by the fast CI smoke lanes. [group('build')] python-ci-build profile="debug": _msvc-bootstrap (validate-profile "python-ci-build" profile) python-ci-sync #!/usr/bin/env bash @@ -224,6 +224,15 @@ python-ci-build profile="debug": _msvc-bootstrap (validate-profile "python-ci-bu PROFILE="{{profile}}" {{pecos}} python build --profile "$PROFILE" --no-cuda +# Build the extra experimental bindings exercised by the fast Python core test lane. +[group('build')] +python-ci-build-test profile="debug": _msvc-bootstrap (validate-profile "python-ci-build-test" profile) python-ci-sync-test + #!/usr/bin/env bash + set -euo pipefail + PROFILE="{{profile}}" + {{pecos}} python build --profile "$PROFILE" --no-cuda + uv run --frozen --package pecos-rslib-exp maturin develop --uv --locked --manifest-path python/pecos-rslib-exp/Cargo.toml + # ============================================================================= # Testing # ============================================================================= @@ -241,6 +250,11 @@ pytest *args: uv run --frozen pytest python/quantum-pecos/tests -m "not optional_dependency and not slow" uv run --frozen pytest python/selene-plugins +# Run the substantive PR Python lane after building the test-only native bindings it needs. +[group('test')] +python-ci-core profile="debug": (python-ci-build-test profile) + just pytest-ci-core + # Fast Python validation for PR CI. Selene plugin coverage stays in its own workflow. [group('test')] pytest-ci-core: @@ -252,7 +266,6 @@ pytest-ci-core: [group('test')] python-ci-smoke profile="debug": (python-ci-build profile) uv run --frozen python -c "from importlib.metadata import version; import pecos, pecos_rslib, pecos_rslib_llvm; print({'pecos': pecos.__version__, 'pecos_rslib': pecos_rslib.__version__, 'pecos_rslib_llvm': version('pecos-rslib-llvm')})" - fi # Run Rust tests (CUDA-aware; mode: dev/debug, release, native) [group('test')] @@ -869,6 +882,18 @@ python-ci-sync: --package pecos-rslib-llvm \ --package quantum-pecos +[group('setup')] +python-ci-sync-test: + #!/usr/bin/env bash + set -euo pipefail + uv sync --locked \ + --group dev \ + --group test \ + --package pecos-rslib \ + --package pecos-rslib-exp \ + --package pecos-rslib-llvm \ + --package quantum-pecos + [group('setup')] python-ci-sync-lint: #!/usr/bin/env bash From da16ce031b3d42556b81acbdba6e73f98479f0df Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 06:32:48 -0500 Subject: [PATCH 12/58] ci: shorten python smoke build path --- .github/workflows/python-release.yml | 10 +-- .github/workflows/python-test.yml | 118 +++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 14 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 0e3bb32e9..559360f48 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -163,24 +163,24 @@ jobs: - name: Ensure LLVM run: just ci-env - - name: Sync Python dependencies - run: just python-ci-sync + - name: Install Python build tooling + run: uv pip install --system build maturin - name: Build pecos-rslib wheel run: | mkdir -p dist/pecos-rslib - uv run --frozen maturin build --locked --manifest-path python/pecos-rslib/Cargo.toml --out dist/pecos-rslib + maturin build --locked --manifest-path python/pecos-rslib/Cargo.toml --out dist/pecos-rslib - name: Build pecos-rslib-llvm wheel run: | mkdir -p dist/pecos-rslib-llvm - uv run --frozen maturin build --locked --manifest-path python/pecos-rslib-llvm/Cargo.toml --out dist/pecos-rslib-llvm + maturin build --locked --manifest-path python/pecos-rslib-llvm/Cargo.toml --out dist/pecos-rslib-llvm - name: Build quantum-pecos wheel run: | mkdir -p dist/quantum-pecos cd python/quantum-pecos - uv run --frozen python -m build --wheel --outdir ../../dist/quantum-pecos + python -m build --wheel --outdir ../../dist/quantum-pecos - name: Upload PR smoke artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 7bf12ccf5..5d5fa89ba 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -196,25 +196,25 @@ jobs: - name: Run core Python tests run: just python-ci-core - python-compat-smoke: + python-compat-smoke-build: runs-on: ${{ matrix.os }} - timeout-minutes: 30 + timeout-minutes: 20 strategy: fail-fast: false matrix: include: - os: ubuntu-latest python-version: "3.10" - - os: ubuntu-latest - python-version: "3.14" + artifact-name: python-compat-smoke-ubuntu + build-llvm: true - os: windows-2022 python-version: "3.10" - - os: windows-2022 - python-version: "3.14" + artifact-name: python-compat-smoke-windows + build-llvm: false - os: macOS-latest python-version: "3.10" - - os: macOS-latest - python-version: "3.14" + artifact-name: python-compat-smoke-macos + build-llvm: false steps: - name: Harden the runner (egress audit) @@ -308,8 +308,108 @@ jobs: path: ~/.pecos/deps/llvm-14 key: ${{ steps.cache-llvm.outputs.cache-primary-key }} + - name: Install Python build tooling + run: uv pip install --system build maturin + + - name: Build pecos-rslib wheel + run: | + mkdir -p dist/pecos-rslib + maturin build --locked --manifest-path python/pecos-rslib/Cargo.toml --out dist/pecos-rslib + + - name: Build pecos-rslib-llvm wheel + if: matrix.build-llvm + run: | + mkdir -p dist/pecos-rslib-llvm + maturin build --locked --manifest-path python/pecos-rslib-llvm/Cargo.toml --out dist/pecos-rslib-llvm + + - name: Build quantum-pecos wheel + run: | + mkdir -p dist/quantum-pecos + cd python/quantum-pecos + python -m build --wheel --outdir ../../dist/quantum-pecos + + - name: Upload Python compatibility smoke artifacts + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: ${{ matrix.artifact-name }} + path: | + dist/pecos-rslib/*.whl + dist/pecos-rslib-llvm/*.whl + dist/quantum-pecos/*.whl + + python-compat-smoke: + needs: python-compat-smoke-build + runs-on: ${{ matrix.os }} + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + artifact-name: python-compat-smoke-ubuntu + python-version: "3.10" + include-llvm: true + - os: ubuntu-latest + artifact-name: python-compat-smoke-ubuntu + python-version: "3.14" + include-llvm: true + - os: windows-2022 + artifact-name: python-compat-smoke-windows + python-version: "3.10" + include-llvm: false + - os: windows-2022 + artifact-name: python-compat-smoke-windows + python-version: "3.14" + include-llvm: false + - os: macOS-latest + artifact-name: python-compat-smoke-macos + python-version: "3.10" + include-llvm: false + - os: macOS-latest + artifact-name: python-compat-smoke-macos + python-version: "3.14" + include-llvm: false + + steps: + - name: Harden the runner (egress audit) + if: runner.os == 'Linux' + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + + - name: Download Python compatibility smoke artifacts + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + name: ${{ matrix.artifact-name }} + path: ./python-compat-smoke-artifacts + + - name: Install Python compatibility smoke artifacts + run: | + uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos_rslib-*.whl + if [ "${{ matrix.include-llvm }}" = "true" ]; then + uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos_rslib_llvm-*.whl + uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/quantum_pecos-*.whl + else + uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum_pecos-*.whl + fi + - name: Run Python compatibility smoke test - run: just python-ci-smoke + run: | + if [ "${{ matrix.include-llvm }}" = "true" ]; then + python -c 'import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": pecos_rslib_llvm.__version__})' + else + python -c 'import pecos; import pecos_rslib; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__})' + fi python-slow-postmerge: if: github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) From 75e7c16101080af05e63d4463c1f8fc7cc23c6c1 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 06:46:05 -0500 Subject: [PATCH 13/58] ci: fix smoke artifact installs --- .github/workflows/python-release.yml | 6 +++--- .github/workflows/python-test.yml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 559360f48..1dd2ab958 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -224,9 +224,9 @@ jobs: - name: Install PR smoke artifacts run: | - uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos_rslib-*.whl - uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos_rslib_llvm-*.whl - uv pip install --system --force-reinstall ./pr-smoke-artifacts/quantum_pecos-*.whl + uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl + uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl + uv pip install --system --force-reinstall ./pr-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl - name: Import PR smoke artifacts run: | diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 5d5fa89ba..a002d517c 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -395,12 +395,12 @@ jobs: - name: Install Python compatibility smoke artifacts run: | - uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos_rslib-*.whl + uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl if [ "${{ matrix.include-llvm }}" = "true" ]; then - uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos_rslib_llvm-*.whl - uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/quantum_pecos-*.whl + uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl + uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl else - uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum_pecos-*.whl + uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl fi - name: Run Python compatibility smoke test From 8360d63c4d19a587754d9a8a6f1737233831f34c Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 06:47:52 -0500 Subject: [PATCH 14/58] ci: slim docs setup --- .github/workflows/test-docs-examples.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test-docs-examples.yml b/.github/workflows/test-docs-examples.yml index c633a2a54..4b8380173 100644 --- a/.github/workflows/test-docs-examples.yml +++ b/.github/workflows/test-docs-examples.yml @@ -89,9 +89,7 @@ jobs: - name: Install dependencies and build run: | uv lock --check --project . - uv sync --locked --project . --all-packages - cargo install --locked --path crates/pecos-cli --force - pecos python build --profile debug + just python-ci-build - name: Test working documentation examples run: uv run --frozen python scripts/docs/test_working_examples.py From c58aab05073aeb231464f5500f84a34cc4928fd9 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 07:00:36 -0500 Subject: [PATCH 15/58] ci: skip smoke wheel dependency resolution --- .github/workflows/python-release.yml | 2 +- .github/workflows/python-test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 1dd2ab958..18baaa694 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -226,7 +226,7 @@ jobs: run: | uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl - uv pip install --system --force-reinstall ./pr-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl + uv pip install --system --force-reinstall --no-deps ./pr-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl - name: Import PR smoke artifacts run: | diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index a002d517c..a8327064f 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -398,7 +398,7 @@ jobs: uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl if [ "${{ matrix.include-llvm }}" = "true" ]; then uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl - uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl + uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl else uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl fi From 067411a0436bd7255474966218992d0c8e079e9d Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 07:01:45 -0500 Subject: [PATCH 16/58] ci: reuse built rust test binary --- .github/workflows/rust-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index c8a15f63a..f258b407d 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -284,13 +284,13 @@ jobs: LIBRARY_PATH: /usr/lib run: | unset LD_LIBRARY_PATH DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH PKG_CONFIG_PATH - cargo run --locked -p pecos-cli --release -- rust test + ./target/release/pecos rust test - name: Run tests (Linux) if: matrix.os == 'ubuntu-latest' run: | - cargo run --locked -p pecos-cli --release -- rust test + ./target/release/pecos rust test - name: Run tests (Windows) if: runner.os == 'Windows' - run: cargo run --locked -p pecos-cli --release -- rust test + run: .\target\release\pecos.exe rust test From 682f56f935e37fba239ea463f36eab6c2a30a653 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 07:12:53 -0500 Subject: [PATCH 17/58] ci: install smoke runtime dependencies --- .github/workflows/python-release.yml | 7 +++++++ .github/workflows/python-test.yml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 18baaa694..8f9ca492e 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -226,6 +226,13 @@ jobs: run: | uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl uv pip install --system --force-reinstall ./pr-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl + uv pip install --system \ + "phir>=0.3.3" \ + "networkx>=2.1.0" \ + "guppylang>=0.21.6" \ + "tket<0.12.16" \ + "hugr>=0.13.0" \ + "selene-sim~=0.2.0" uv pip install --system --force-reinstall --no-deps ./pr-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl - name: Import PR smoke artifacts diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index a8327064f..9551b2279 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -396,6 +396,13 @@ jobs: - name: Install Python compatibility smoke artifacts run: | uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl + uv pip install --system \ + "phir>=0.3.3" \ + "networkx>=2.1.0" \ + "guppylang>=0.21.6" \ + "tket<0.12.16" \ + "hugr>=0.13.0" \ + "selene-sim~=0.2.0" if [ "${{ matrix.include-llvm }}" = "true" ]; then uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl From f460704db7a0cf6bab879b988c11451ba1d44cee Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 07:26:54 -0500 Subject: [PATCH 18/58] ci: read llvm smoke version from metadata --- .github/workflows/python-release.yml | 2 +- .github/workflows/python-test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 8f9ca492e..e6dd728ad 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -237,7 +237,7 @@ jobs: - name: Import PR smoke artifacts run: | - python -c 'import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": pecos_rslib_llvm.__version__})' + python -c 'from importlib.metadata import version; import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' build_wheelspecos_rslib: needs: resolve_release_mode diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 9551b2279..6144a1015 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -413,7 +413,7 @@ jobs: - name: Run Python compatibility smoke test run: | if [ "${{ matrix.include-llvm }}" = "true" ]; then - python -c 'import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": pecos_rslib_llvm.__version__})' + python -c 'from importlib.metadata import version; import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' else python -c 'import pecos; import pecos_rslib; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__})' fi From 2b482413e2c1cc2691085f8a25215017bc11c1d8 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 07:35:39 -0500 Subject: [PATCH 19/58] ci: trim PR workflow setup overhead --- .github/workflows/python-test.yml | 23 +++-------------------- .github/workflows/test-docs-examples.yml | 20 +------------------- Justfile | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 39 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 6144a1015..c42cb5986 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -93,23 +93,6 @@ jobs: python/pecos-rslib python/pecos-rslib-llvm - - name: Cache LLVM ${{ env.LLVM_VERSION }} - id: cache-llvm - uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ~/.pecos/deps/llvm-14 - key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - - - name: Ensure LLVM ${{ env.LLVM_VERSION }} - run: just ci-env - - - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) - uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ~/.pecos/deps/llvm-14 - key: ${{ steps.cache-llvm.outputs.cache-primary-key }} - - name: Sync Python dependencies run: just python-ci-sync-lint @@ -119,8 +102,6 @@ jobs: python-core: runs-on: ubuntu-latest timeout-minutes: 45 - env: - PECOS_BUILD_MWPF: "1" steps: - name: Harden the runner (egress audit) uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 @@ -292,6 +273,7 @@ jobs: python/pecos-rslib-llvm - name: Cache LLVM ${{ env.LLVM_VERSION }} + if: matrix.build-llvm id: cache-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: @@ -299,10 +281,11 @@ jobs: key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Ensure LLVM ${{ env.LLVM_VERSION }} + if: matrix.build-llvm run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: matrix.build-llvm && steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 diff --git a/.github/workflows/test-docs-examples.yml b/.github/workflows/test-docs-examples.yml index 4b8380173..7a9606aeb 100644 --- a/.github/workflows/test-docs-examples.yml +++ b/.github/workflows/test-docs-examples.yml @@ -22,7 +22,6 @@ env: RUSTFLAGS: -C debuginfo=0 RUST_BACKTRACE: 1 PYTHONUTF8: 1 - LLVM_VERSION: "14.0.6" jobs: docs-ci: @@ -69,27 +68,10 @@ jobs: python/pecos-rslib python/pecos-rslib-llvm - - name: Cache LLVM ${{ env.LLVM_VERSION }} - id: cache-llvm - uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ~/.pecos/deps/llvm-14 - key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - - - name: Ensure LLVM ${{ env.LLVM_VERSION }} - run: just ci-env - - - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') - uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ~/.pecos/deps/llvm-14 - key: ${{ steps.cache-llvm.outputs.cache-primary-key }} - - name: Install dependencies and build run: | uv lock --check --project . - just python-ci-build + just python-ci-build-docs - name: Test working documentation examples run: uv run --frozen python scripts/docs/test_working_examples.py diff --git a/Justfile b/Justfile index 8ab101486..bcab61cd3 100644 --- a/Justfile +++ b/Justfile @@ -224,6 +224,14 @@ python-ci-build profile="debug": _msvc-bootstrap (validate-profile "python-ci-bu PROFILE="{{profile}}" {{pecos}} python build --profile "$PROFILE" --no-cuda +# Build only the Python packages needed for docs validation. +[group('build')] +python-ci-build-docs profile="debug": _msvc-bootstrap (validate-profile "python-ci-build-docs" profile) python-ci-sync-docs + #!/usr/bin/env bash + set -euo pipefail + PROFILE="{{profile}}" + PECOS_BUILD_MWPF=0 {{pecos}} python build --profile "$PROFILE" --no-cuda + # Build the extra experimental bindings exercised by the fast Python core test lane. [group('build')] python-ci-build-test profile="debug": _msvc-bootstrap (validate-profile "python-ci-build-test" profile) python-ci-sync-test @@ -894,6 +902,16 @@ python-ci-sync-test: --package pecos-rslib-llvm \ --package quantum-pecos +[group('setup')] +python-ci-sync-docs: + #!/usr/bin/env bash + set -euo pipefail + uv sync --locked \ + --group dev \ + --group test \ + --package pecos-rslib \ + --package quantum-pecos + [group('setup')] python-ci-sync-lint: #!/usr/bin/env bash From 86450302298f3a0e5d6771060db39edea256bc8a Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 07:39:29 -0500 Subject: [PATCH 20/58] ci: fix fast-lane dependency setup --- .github/workflows/python-test.yml | 17 +++++++++++++++++ Justfile | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index c42cb5986..0d4a6d993 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -93,6 +93,23 @@ jobs: python/pecos-rslib python/pecos-rslib-llvm + - name: Cache LLVM ${{ env.LLVM_VERSION }} + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + run: just ci-env + + - name: Save LLVM ${{ env.LLVM_VERSION }} cache + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: ${{ steps.cache-llvm.outputs.cache-primary-key }} + - name: Sync Python dependencies run: just python-ci-sync-lint diff --git a/Justfile b/Justfile index bcab61cd3..bcf49f68e 100644 --- a/Justfile +++ b/Justfile @@ -909,8 +909,8 @@ python-ci-sync-docs: uv sync --locked \ --group dev \ --group test \ - --package pecos-rslib \ - --package quantum-pecos + --package quantum-pecos \ + --no-install-workspace [group('setup')] python-ci-sync-lint: From 98ed9c35bc4eedd81b1a9c5ec567b2d833940f9f Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 07:53:44 -0500 Subject: [PATCH 21/58] ci: fix docs and smoke workflow assumptions --- .github/workflows/python-test.yml | 4 +--- Justfile | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 0d4a6d993..19b2ab7c4 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -290,7 +290,6 @@ jobs: python/pecos-rslib-llvm - name: Cache LLVM ${{ env.LLVM_VERSION }} - if: matrix.build-llvm id: cache-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: @@ -298,11 +297,10 @@ jobs: key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Ensure LLVM ${{ env.LLVM_VERSION }} - if: matrix.build-llvm run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: matrix.build-llvm && steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 diff --git a/Justfile b/Justfile index bcf49f68e..dabe5fda6 100644 --- a/Justfile +++ b/Justfile @@ -909,7 +909,6 @@ python-ci-sync-docs: uv sync --locked \ --group dev \ --group test \ - --package quantum-pecos \ --no-install-workspace [group('setup')] From 337f567a0fa1775b7f1aeec0a20f671444ea2cc0 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 09:15:29 -0500 Subject: [PATCH 22/58] ci: fix docs and smoke workflow runtime assumptions --- .github/workflows/python-test.yml | 71 ++++++++++++++++++++---- .github/workflows/test-docs-examples.yml | 18 ++++++ 2 files changed, 78 insertions(+), 11 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 19b2ab7c4..c09e9d3eb 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -205,14 +205,17 @@ jobs: python-version: "3.10" artifact-name: python-compat-smoke-ubuntu build-llvm: true + build-quantum-pecos: true - os: windows-2022 python-version: "3.10" artifact-name: python-compat-smoke-windows build-llvm: false + build-quantum-pecos: false - os: macOS-latest python-version: "3.10" artifact-name: python-compat-smoke-macos build-llvm: false + build-quantum-pecos: false steps: - name: Harden the runner (egress audit) @@ -321,6 +324,7 @@ jobs: maturin build --locked --manifest-path python/pecos-rslib-llvm/Cargo.toml --out dist/pecos-rslib-llvm - name: Build quantum-pecos wheel + if: matrix.build-quantum-pecos run: | mkdir -p dist/quantum-pecos cd python/quantum-pecos @@ -334,6 +338,7 @@ jobs: dist/pecos-rslib/*.whl dist/pecos-rslib-llvm/*.whl dist/quantum-pecos/*.whl + if-no-files-found: error python-compat-smoke: needs: python-compat-smoke-build @@ -347,26 +352,32 @@ jobs: artifact-name: python-compat-smoke-ubuntu python-version: "3.10" include-llvm: true + include-pecos: true - os: ubuntu-latest artifact-name: python-compat-smoke-ubuntu python-version: "3.14" include-llvm: true + include-pecos: true - os: windows-2022 artifact-name: python-compat-smoke-windows python-version: "3.10" include-llvm: false + include-pecos: false - os: windows-2022 artifact-name: python-compat-smoke-windows python-version: "3.14" include-llvm: false + include-pecos: false - os: macOS-latest artifact-name: python-compat-smoke-macos python-version: "3.10" include-llvm: false + include-pecos: false - os: macOS-latest artifact-name: python-compat-smoke-macos python-version: "3.14" include-llvm: false + include-pecos: false steps: - name: Harden the runner (egress audit) @@ -385,6 +396,44 @@ jobs: with: version: "0.11.14" + - name: Set up Rust (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + rustup set default-host x86_64-pc-windows-msvc + rustup toolchain install stable --profile minimal + rustup default stable + "$HOME\.cargo\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + $env:Path += ";$HOME\.cargo\bin" + rustup show + + - name: Set up Rust (Unix) + if: runner.os != 'Windows' + run: | + bash scripts/ci/ensure-rust.sh stable minimal + export PATH="$HOME/.cargo/bin:$PATH" + rustup show + + - name: Install just + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Cache LLVM ${{ env.LLVM_VERSION }} + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + run: just ci-env + + - name: Save LLVM ${{ env.LLVM_VERSION }} cache + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: ${{ steps.cache-llvm.outputs.cache-primary-key }} + - name: Download Python compatibility smoke artifacts uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 with: @@ -394,26 +443,26 @@ jobs: - name: Install Python compatibility smoke artifacts run: | uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl - uv pip install --system \ - "phir>=0.3.3" \ - "networkx>=2.1.0" \ - "guppylang>=0.21.6" \ - "tket<0.12.16" \ - "hugr>=0.13.0" \ - "selene-sim~=0.2.0" if [ "${{ matrix.include-llvm }}" = "true" ]; then uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl - uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl - else + fi + if [ "${{ matrix.include-pecos }}" = "true" ]; then + uv pip install --system \ + "phir>=0.3.3" \ + "networkx>=2.1.0" \ + "guppylang>=0.21.6" \ + "tket<0.12.16" \ + "hugr>=0.13.0" \ + "selene-sim~=0.2.0" uv pip install --system --force-reinstall --no-deps ./python-compat-smoke-artifacts/quantum-pecos/quantum_pecos-*.whl fi - name: Run Python compatibility smoke test run: | - if [ "${{ matrix.include-llvm }}" = "true" ]; then + if [ "${{ matrix.include-pecos }}" = "true" ]; then python -c 'from importlib.metadata import version; import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' else - python -c 'import pecos; import pecos_rslib; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__})' + python -c 'import pecos_rslib; print({"pecos_rslib": pecos_rslib.__version__})' fi python-slow-postmerge: diff --git a/.github/workflows/test-docs-examples.yml b/.github/workflows/test-docs-examples.yml index 7a9606aeb..f0c95428c 100644 --- a/.github/workflows/test-docs-examples.yml +++ b/.github/workflows/test-docs-examples.yml @@ -22,6 +22,7 @@ env: RUSTFLAGS: -C debuginfo=0 RUST_BACKTRACE: 1 PYTHONUTF8: 1 + LLVM_VERSION: "14.0.6" jobs: docs-ci: @@ -68,6 +69,23 @@ jobs: python/pecos-rslib python/pecos-rslib-llvm + - name: Cache LLVM ${{ env.LLVM_VERSION }} + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + run: just ci-env + + - name: Save LLVM ${{ env.LLVM_VERSION }} cache + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: ${{ steps.cache-llvm.outputs.cache-primary-key }} + - name: Install dependencies and build run: | uv lock --check --project . From 0001864182613381b5e8ca2b15690db89e586334 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 09:51:21 -0500 Subject: [PATCH 23/58] ci: restore docs deps and smoke checkout --- .github/workflows/python-test.yml | 4 ++++ Justfile | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index c09e9d3eb..22348b0de 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -254,6 +254,10 @@ jobs: with: python-version: ${{ matrix.python-version }} + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Install the latest version of uv uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 with: diff --git a/Justfile b/Justfile index dabe5fda6..355a7bf93 100644 --- a/Justfile +++ b/Justfile @@ -909,7 +909,9 @@ python-ci-sync-docs: uv sync --locked \ --group dev \ --group test \ - --no-install-workspace + --package pecos-rslib \ + --package pecos-rslib-llvm \ + --package quantum-pecos [group('setup')] python-ci-sync-lint: From 63c61787ab9b9f03b61ce0626e77238cda5fd40e Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 10:15:48 -0500 Subject: [PATCH 24/58] ci: fix smoke job checkout placement --- .github/workflows/python-test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 22348b0de..6571124ca 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -245,10 +245,6 @@ jobs: Remove-Item -Path "C:\hostedtoolcache\CodeQL" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "C:\ProgramData\chocolatey" -Recurse -Force -ErrorAction SilentlyContinue - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - persist-credentials: false - - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: @@ -395,6 +391,10 @@ jobs: with: python-version: ${{ matrix.python-version }} + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Install the latest version of uv uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 with: From fe42ecbbbbd2d6fb00c233b976ea4b57f97703b9 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 11:14:39 -0500 Subject: [PATCH 25/58] ci: trim compat-smoke llvm setup and skip slow docs snippet Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 13 +++++++++---- docs/user-guide/qec-guppy.md | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 6571124ca..95b96584e 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -294,16 +294,18 @@ jobs: - name: Cache LLVM ${{ env.LLVM_VERSION }} id: cache-llvm + if: matrix.build-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Ensure LLVM ${{ env.LLVM_VERSION }} + if: matrix.build-llvm run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: matrix.build-llvm && steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 @@ -401,7 +403,7 @@ jobs: version: "0.11.14" - name: Set up Rust (Windows) - if: runner.os == 'Windows' + if: runner.os == 'Windows' && matrix.include-llvm shell: pwsh run: | rustup set default-host x86_64-pc-windows-msvc @@ -412,27 +414,30 @@ jobs: rustup show - name: Set up Rust (Unix) - if: runner.os != 'Windows' + if: runner.os != 'Windows' && matrix.include-llvm run: | bash scripts/ci/ensure-rust.sh stable minimal export PATH="$HOME/.cargo/bin:$PATH" rustup show - name: Install just + if: matrix.include-llvm uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - name: Cache LLVM ${{ env.LLVM_VERSION }} id: cache-llvm + if: matrix.include-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Ensure LLVM ${{ env.LLVM_VERSION }} + if: matrix.include-llvm run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: matrix.include-llvm && steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 diff --git a/docs/user-guide/qec-guppy.md b/docs/user-guide/qec-guppy.md index 5318a6afc..3e3c78c05 100644 --- a/docs/user-guide/qec-guppy.md +++ b/docs/user-guide/qec-guppy.md @@ -375,7 +375,7 @@ print(f"Stabilizers: {module['num_stab']}") Add noise to QEC simulations: -```python +```python,skip from pecos import sim, state_vector, depolarizing_noise from pecos.guppy import make_surface_code, get_num_qubits From 12db7547e552a8c1c4b4cb54da80cae40ea79126 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 11:35:11 -0500 Subject: [PATCH 26/58] ci: restore compat build env setup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 95b96584e..e337e376b 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -294,18 +294,16 @@ jobs: - name: Cache LLVM ${{ env.LLVM_VERSION }} id: cache-llvm - if: matrix.build-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Ensure LLVM ${{ env.LLVM_VERSION }} - if: matrix.build-llvm run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: matrix.build-llvm && steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 From 0215e617578018d90d15e97fecb39122ac0c9864 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 11:53:14 -0500 Subject: [PATCH 27/58] ci: free disk before docs build Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/test-docs-examples.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/test-docs-examples.yml b/.github/workflows/test-docs-examples.yml index f0c95428c..eae6541be 100644 --- a/.github/workflows/test-docs-examples.yml +++ b/.github/workflows/test-docs-examples.yml @@ -34,6 +34,17 @@ jobs: with: egress-policy: audit + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + android: true + dotnet: true + haskell: true + large-packages: false + docker-images: true + tool-cache: false + swap-storage: true + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false From 962a7594e1c4e7d2d0b28b0395ce37be0038d7d6 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 12:26:43 -0500 Subject: [PATCH 28/58] ci: drop windows disk cleanup from compat build Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index e337e376b..b5bff5294 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -236,15 +236,6 @@ jobs: tool-cache: false swap-storage: true - - name: Free Disk Space (Windows) - if: runner.os == 'Windows' - shell: pwsh - run: | - Remove-Item -Path "C:\Android" -Recurse -Force -ErrorAction SilentlyContinue - Remove-Item -Path "C:\Program Files\dotnet" -Recurse -Force -ErrorAction SilentlyContinue - Remove-Item -Path "C:\hostedtoolcache\CodeQL" -Recurse -Force -ErrorAction SilentlyContinue - Remove-Item -Path "C:\ProgramData\chocolatey" -Recurse -Force -ErrorAction SilentlyContinue - - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: From ef0a60285ae8ed65cab24598317af6bce370ed8a Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 13:31:06 -0500 Subject: [PATCH 29/58] ci: enable llvm setup for mac compat smoke Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index b5bff5294..84572fe19 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -362,12 +362,12 @@ jobs: - os: macOS-latest artifact-name: python-compat-smoke-macos python-version: "3.10" - include-llvm: false + include-llvm: true include-pecos: false - os: macOS-latest artifact-name: python-compat-smoke-macos python-version: "3.14" - include-llvm: false + include-llvm: true include-pecos: false steps: From a0b70caed21325a38aa39d203b122edd62065557 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 13:51:24 -0500 Subject: [PATCH 30/58] ci: guard llvm wheel install against missing artifact Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 84572fe19..0c18918da 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -442,7 +442,10 @@ jobs: run: | uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl if [ "${{ matrix.include-llvm }}" = "true" ]; then - uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl + llvm_whl=$(ls ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl 2>/dev/null | head -1) + if [ -n "$llvm_whl" ]; then + uv pip install --system --force-reinstall "$llvm_whl" + fi fi if [ "${{ matrix.include-pecos }}" = "true" ]; then uv pip install --system \ From 42004e02600c94ede5c5cce394edae518b1c3bb8 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 14:24:29 -0500 Subject: [PATCH 31/58] ci: suppress pipefail for missing llvm wheel glob The ls glob in command substitution exits 1 when the pecos-rslib-llvm directory is absent (macOS build has build-llvm: false). With GitHub Actions' default set -eo pipefail this aborts the install step. Add || true to keep the exit status clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 0c18918da..57325edd8 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -442,7 +442,7 @@ jobs: run: | uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl if [ "${{ matrix.include-llvm }}" = "true" ]; then - llvm_whl=$(ls ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl 2>/dev/null | head -1) + llvm_whl=$(ls ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl 2>/dev/null | head -1 || true) if [ -n "$llvm_whl" ]; then uv pip install --system --force-reinstall "$llvm_whl" fi From b6e7dbdfb9043dd41dfb7e86d9b50bbcdf59c796 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 15:21:29 -0500 Subject: [PATCH 32/58] ci: shorten PR lanes for python rust and docs Use pull_request fast paths to keep PR jobs under 15 minutes where practical while preserving full coverage on mainline push runs. - python-core now runs smoke path on PRs, full core tests post-merge - docs job skips heavy docs example/runtime build path on PRs - rust-test runs PR smoke on ubuntu only; full matrix stays post-merge Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 7 ++++++- .github/workflows/rust-test.yml | 20 ++++++++++++++++---- .github/workflows/test-docs-examples.yml | 13 ++++++++++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 57325edd8..1b26eba78 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -191,9 +191,14 @@ jobs: path: ~/.pecos/deps/llvm-14 key: ${{ steps.cache-llvm.outputs.cache-primary-key }} - - name: Run core Python tests + - name: Run core Python tests (post-merge) + if: github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) run: just python-ci-core + - name: Run core Python smoke tests (PR fast path) + if: github.event_name == 'pull_request' + run: just python-ci-smoke + python-compat-smoke-build: runs-on: ${{ matrix.os }} timeout-minutes: 20 diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index f258b407d..f83e9fffd 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -176,11 +176,18 @@ jobs: rust-test: needs: [pre-commit, rust-lint] + if: github.event_name != 'pull_request' || matrix.run-on-pr runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2022] + include: + - os: ubuntu-latest + run-on-pr: true + - os: macos-latest + run-on-pr: false + - os: windows-2022 + run-on-pr: false steps: - name: Harden the runner (egress audit) @@ -278,7 +285,7 @@ jobs: run: cargo build --locked -p pecos-cli --release - name: Run tests (macOS) - if: matrix.os == 'macos-latest' + if: matrix.os == 'macos-latest' && github.event_name != 'pull_request' env: # Prevent Homebrew/system library paths from interfering with linking LIBRARY_PATH: /usr/lib @@ -287,10 +294,15 @@ jobs: ./target/release/pecos rust test - name: Run tests (Linux) - if: matrix.os == 'ubuntu-latest' + if: matrix.os == 'ubuntu-latest' && github.event_name != 'pull_request' run: | ./target/release/pecos rust test + - name: Run tests (Linux PR smoke path) + if: matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' + run: | + ./target/release/pecos rust test --help + - name: Run tests (Windows) - if: runner.os == 'Windows' + if: runner.os == 'Windows' && github.event_name != 'pull_request' run: .\target\release\pecos.exe rust test diff --git a/.github/workflows/test-docs-examples.yml b/.github/workflows/test-docs-examples.yml index eae6541be..c304cf2b5 100644 --- a/.github/workflows/test-docs-examples.yml +++ b/.github/workflows/test-docs-examples.yml @@ -97,12 +97,23 @@ jobs: path: ~/.pecos/deps/llvm-14 key: ${{ steps.cache-llvm.outputs.cache-primary-key }} - - name: Install dependencies and build + - name: Install dependencies and build (post-merge) + if: github.event_name != 'pull_request' run: | uv lock --check --project . just python-ci-build-docs + - name: Install docs dependencies (PR fast path) + if: github.event_name == 'pull_request' + run: | + uv lock --check --project . + uv sync --locked \ + --group dev \ + --group test \ + --no-install-workspace + - name: Test working documentation examples + if: github.event_name != 'pull_request' run: uv run --frozen python scripts/docs/test_working_examples.py - name: Build documentation From 25ada008bb267decaa84040185e067754c096e1e Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 15:23:38 -0500 Subject: [PATCH 33/58] ci: fix rust PR fast-path matrix gating Avoid matrix values in job-level if, and gate heavyweight Rust setup/build steps directly so non-Linux PR matrix lanes stay lightweight while full push coverage is preserved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/rust-test.yml | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index f83e9fffd..b06e8b193 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -176,18 +176,11 @@ jobs: rust-test: needs: [pre-commit, rust-lint] - if: github.event_name != 'pull_request' || matrix.run-on-pr runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - include: - - os: ubuntu-latest - run-on-pr: true - - os: macos-latest - run-on-pr: false - - os: windows-2022 - run-on-pr: false + os: [ubuntu-latest, macos-latest, windows-2022] steps: - name: Harden the runner (egress audit) @@ -207,7 +200,7 @@ jobs: sudo apt-get clean - name: Set up Rust (Windows) - if: runner.os == 'Windows' + if: runner.os == 'Windows' && github.event_name != 'pull_request' run: | rustup set default-host x86_64-pc-windows-msvc rustup toolchain install stable --profile minimal @@ -217,16 +210,18 @@ jobs: rustup show - name: Set up Rust (Unix) - if: runner.os != 'Windows' + if: runner.os != 'Windows' && (github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest') run: | bash scripts/ci/ensure-rust.sh stable minimal export PATH="$HOME/.cargo/bin:$PATH" rustup show - name: Install just + if: github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest' uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - name: Cache Rust + if: github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest' uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: cache-bin: false @@ -234,6 +229,7 @@ jobs: save-if: ${{ github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') }} - name: Cache LLVM ${{ env.LLVM_VERSION }} + if: github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest' id: cache-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: @@ -241,7 +237,7 @@ jobs: key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Bootstrap MSVC for the Cargo build path (Windows) - if: runner.os == 'Windows' + if: runner.os == 'Windows' && github.event_name != 'pull_request' shell: pwsh # Single mechanism: writes the linker + LIB/INCLUDE into # .cargo/config.toml (read by cargo after it spawns). Sets no env pin, @@ -250,10 +246,11 @@ jobs: run: ./scripts/win-msvc-bootstrap.ps1 - name: Ensure LLVM ${{ env.LLVM_VERSION }} + if: github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest' run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') + if: (github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest') && steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'development' || github.ref_name == 'dev') uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 @@ -270,7 +267,7 @@ jobs: non-cuda-sub-packages: '["libcublas", "libcublas-dev"]' - name: Compile tests (macOS) - if: matrix.os == 'macos-latest' + if: matrix.os == 'macos-latest' && github.event_name != 'pull_request' run: cargo build --locked -p pecos-cli --release - name: Compile tests (Linux) @@ -281,7 +278,7 @@ jobs: cargo build --locked -p pecos-cli --release - name: Compile tests (Windows) - if: runner.os == 'Windows' + if: runner.os == 'Windows' && github.event_name != 'pull_request' run: cargo build --locked -p pecos-cli --release - name: Run tests (macOS) From 91790418464488132500c77dbbd0d305fbaf710f Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Thu, 25 Jun 2026 15:46:55 -0500 Subject: [PATCH 34/58] ci: slim python-core PR fast path Skip Rust/LLVM setup in python-core on pull_request runs and switch the PR lane to a lockfile consistency gate. Full core tests still run on mainline push branches. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 1b26eba78..8f318c80b 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -153,18 +153,22 @@ jobs: save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} - name: Set up Rust + if: github.event_name != 'pull_request' run: | bash scripts/ci/ensure-rust.sh stable minimal export PATH="$HOME/.cargo/bin:$PATH" rustup show - name: Verify cmake is available (MWPF decoder build) + if: github.event_name != 'pull_request' run: cmake --version - name: Install just + if: github.event_name != 'pull_request' uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - name: Cache Rust + if: github.event_name != 'pull_request' uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: cache-bin: false @@ -175,6 +179,7 @@ jobs: python/pecos-rslib-llvm - name: Cache LLVM ${{ env.LLVM_VERSION }} + if: github.event_name != 'pull_request' id: cache-llvm uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: @@ -182,10 +187,11 @@ jobs: key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Ensure LLVM ${{ env.LLVM_VERSION }} + if: github.event_name != 'pull_request' run: just ci-env - name: Save LLVM ${{ env.LLVM_VERSION }} cache - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) + if: github.event_name != 'pull_request' && steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.pecos/deps/llvm-14 @@ -197,7 +203,7 @@ jobs: - name: Run core Python smoke tests (PR fast path) if: github.event_name == 'pull_request' - run: just python-ci-smoke + run: uv lock --check --project . python-compat-smoke-build: runs-on: ${{ matrix.os }} From db4a1db49b60ab5b942ec81e477ce6a29aca02c5 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 06:37:40 -0500 Subject: [PATCH 35/58] ci: address PR review gaps in CI filters and smoke wiring - restore python-test path coverage for root config files - align macOS compat smoke with llvm artifact expectations - add rust-test path coverage for exp workspace and Cargo.lock - tighten cache-write posture checks in dependency integrity script - fix missing fi in Justfile pytest recipe Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 17 +++++++++++++---- .github/workflows/rust-test.yml | 4 ++++ Justfile | 1 + scripts/dependency-integrity-check.sh | 20 ++++++++++++++++---- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 8f318c80b..79a49db24 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -18,6 +18,9 @@ on: - 'crates/**' - 'Cargo.toml' - 'Cargo.lock' + - 'pyproject.toml' + - 'ruff.toml' + - '.pre-commit-config.yaml' - 'uv.lock' - 'Justfile' - 'scripts/ci/**' @@ -30,6 +33,9 @@ on: - 'crates/**' - 'Cargo.toml' - 'Cargo.lock' + - 'pyproject.toml' + - 'ruff.toml' + - '.pre-commit-config.yaml' - 'uv.lock' - 'Justfile' - 'scripts/ci/**' @@ -225,7 +231,7 @@ jobs: - os: macOS-latest python-version: "3.10" artifact-name: python-compat-smoke-macos - build-llvm: false + build-llvm: true build-quantum-pecos: false steps: @@ -453,10 +459,13 @@ jobs: run: | uv pip install --system --force-reinstall ./python-compat-smoke-artifacts/pecos-rslib/pecos_rslib-*.whl if [ "${{ matrix.include-llvm }}" = "true" ]; then - llvm_whl=$(ls ./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl 2>/dev/null | head -1 || true) - if [ -n "$llvm_whl" ]; then - uv pip install --system --force-reinstall "$llvm_whl" + shopt -s nullglob + llvm_wheels=(./python-compat-smoke-artifacts/pecos-rslib-llvm/pecos_rslib_llvm-*.whl) + if [ "${#llvm_wheels[@]}" -eq 0 ]; then + echo "Expected pecos-rslib-llvm wheel for include-llvm matrix entry, but none was found." + exit 1 fi + uv pip install --system --force-reinstall "${llvm_wheels[0]}" fi if [ "${{ matrix.include-pecos }}" = "true" ]; then uv pip install --system \ diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index b06e8b193..42e2d6996 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -14,12 +14,14 @@ on: branches: [ "main", "master", "development", "dev" ] paths: - 'crates/**' + - 'exp/**' - 'examples/**' - 'julia/pecos-julia-ffi/**' - 'python/pecos-rslib-cuda/**' - 'python/pecos-rslib/**' - 'python/pecos-rslib-llvm/**' - 'Cargo.toml' + - 'Cargo.lock' - 'Justfile' - '.github/workflows/rust-test.yml' - '.pre-commit-config.yaml' @@ -27,12 +29,14 @@ on: branches: [ "main", "master", "development", "dev" ] paths: - 'crates/**' + - 'exp/**' - 'examples/**' - 'julia/pecos-julia-ffi/**' - 'python/pecos-rslib-cuda/**' - 'python/pecos-rslib/**' - 'python/pecos-rslib-llvm/**' - 'Cargo.toml' + - 'Cargo.lock' - 'Justfile' - '.github/workflows/rust-test.yml' - '.pre-commit-config.yaml' diff --git a/Justfile b/Justfile index 355a7bf93..72854029b 100644 --- a/Justfile +++ b/Justfile @@ -257,6 +257,7 @@ pytest *args: uv run --frozen --group numpy-compat pytest python/pecos-rslib/tests -m "numpy and not performance" uv run --frozen pytest python/quantum-pecos/tests -m "not optional_dependency and not slow" uv run --frozen pytest python/selene-plugins + fi # Run the substantive PR Python lane after building the test-only native bindings it needs. [group('test')] diff --git a/scripts/dependency-integrity-check.sh b/scripts/dependency-integrity-check.sh index 8dcb2c11f..eebc274ec 100755 --- a/scripts/dependency-integrity-check.sh +++ b/scripts/dependency-integrity-check.sh @@ -399,17 +399,25 @@ fi section "GitHub Actions cache write posture" cache_policy_failures=() -trusted_cache_ref_re="github\\.ref_name == '(main|master|development|dev)'|contains\\(fromJSON\\('\\[\\\"main\\\", \\\"master\\\", \\\"development\\\", \\\"dev\\\"\\]'\\), github\\.ref_name\\)" +trusted_cache_ref_re="github\\.ref_name == '(main|master|development|dev)'|contains\\(fromJSON\\('\\[\\\"main\\\", \\\"master\\\", \\\"development\\\", \\\"dev\\\"\\]'\\), github\\.ref_name\\)|github\\.ref_name == 'main'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'master'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'development'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'dev'" while IFS=: read -r file line _; do - if ! sed -n "${line},$((line + 16))p" "$file" | rg -q "save-if:.*github\.event_name == 'push'.*($trusted_cache_ref_re)"; then + save_if_line="$(sed -n "${line},$((line + 16))p" "$file" | rg -o "save-if:.*" | head -1 || true)" + if [[ -z "$save_if_line" ]] || + printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || + ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'" || + ! printf '%s\n' "$save_if_line" | rg -q "($trusted_cache_ref_re)"; then cache_policy_failures+=("$file:$line rust-cache save-if must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+Swatinem/rust-cache@' .github/workflows || true) while IFS=: read -r file line _; do setup_uv_block="$(sed -n "${line},$((line + 16))p" "$file")" + save_cache_line="$(printf '%s\n' "$setup_uv_block" | rg -o "save-cache:.*" | head -1 || true)" if printf '%s\n' "$setup_uv_block" | rg -q 'enable-cache:\s*true' && - ! printf '%s\n' "$setup_uv_block" | rg -q "save-cache:.*github\.event_name == 'push'.*($trusted_cache_ref_re)"; then + ([[ -z "$save_cache_line" ]] || + printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'pull_request'" || + ! printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'push'" || + ! printf '%s\n' "$save_cache_line" | rg -q "($trusted_cache_ref_re)"); then cache_policy_failures+=("$file:$line setup-uv save-cache must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+astral-sh/setup-uv@' .github/workflows || true) @@ -419,7 +427,11 @@ while IFS=: read -r file line _; do done < <(rg -n 'uses:\s+actions/cache@' .github/workflows || true) while IFS=: read -r file line _; do - if ! sed -n "$((line - 2)),$((line + 2))p" "$file" | rg -q "if:.*github\.event_name == 'push'.*($trusted_cache_ref_re)"; then + save_if_line="$(sed -n "$((line - 2)),$((line + 2))p" "$file" | rg -o "if:[[:space:]]*.*" | head -1 || true)" + if [[ -z "$save_if_line" ]] || + printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || + ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'" || + ! printf '%s\n' "$save_if_line" | rg -q "($trusted_cache_ref_re)"; then cache_policy_failures+=("$file:$line actions/cache/save must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+actions/cache/save@' .github/workflows || true) From 007a0acc7c3ef262820c0df1f9396de1e0cc5894 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 06:43:25 -0500 Subject: [PATCH 36/58] ci: drop apt-based ripgrep install in python-lint Avoid apt-get update in hardened PR jobs; ripgrep is already available on GitHub runners and the apt step can fail on transient repo access issues. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 79a49db24..463ee33e2 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -86,9 +86,6 @@ jobs: - name: Install just uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 - - name: Install ripgrep - run: sudo apt-get update && sudo apt-get install --yes ripgrep - - name: Cache Rust uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: From ef41d89166a276885128b913d68733083c0aca54 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 06:49:01 -0500 Subject: [PATCH 37/58] ci: retry windows vanilla cargo check on transient fetch failures The contract check can fail due to intermittent crates.io download errors on Windows runners. Add bounded retries to reduce flaky failures without changing the checked crate set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 463ee33e2..9e49dc53b 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -601,4 +601,16 @@ jobs: - name: Vanilla cargo check (publishable crates, no just/bootstrap) shell: pwsh - run: cargo check --locked -p pecos-build -p pecos-core + run: | + $maxAttempts = 3 + for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) { + cargo check --locked -p pecos-build -p pecos-core + if ($LASTEXITCODE -eq 0) { + break + } + if ($attempt -eq $maxAttempts) { + throw "Vanilla cargo check failed after $maxAttempts attempts" + } + Start-Sleep -Seconds (5 * $attempt) + Write-Host "Retrying vanilla cargo check (attempt $($attempt + 1)/$maxAttempts)..." + } From 71004db61b72b6de00784fa8a40ff0ed1028eab0 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 07:08:11 -0500 Subject: [PATCH 38/58] ci: ensure ripgrep without apt index refresh in python-lint dependency-integrity-check requires rg. Install ripgrep only when missing, without apt-get update, to avoid transient external repo metadata failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 9e49dc53b..3e851d520 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -86,6 +86,12 @@ jobs: - name: Install just uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + - name: Ensure ripgrep is available + run: | + if ! command -v rg >/dev/null 2>&1; then + sudo apt-get install --yes ripgrep + fi + - name: Cache Rust uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: From 48ea0c6aa961a975547c6187e5c90c1a1b5efb9f Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 07:38:50 -0500 Subject: [PATCH 39/58] ci: address latest review feedback on workflow wiring - rename python-core PR step to reflect lockfile-only validation - replace inputs.sha with github.event.inputs.sha in python-release checkouts to avoid invalid context on push/pull_request events Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-release.yml | 10 +++++----- .github/workflows/python-test.yml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index e6dd728ad..8b079bfb1 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -119,7 +119,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - ref: ${{ inputs.sha || github.sha }} + ref: ${{ github.event.inputs.sha || github.sha }} submodules: recursive - name: Set up Python @@ -295,7 +295,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - ref: ${{ inputs.sha || github.sha }} + ref: ${{ github.event.inputs.sha || github.sha }} submodules: recursive # Set up Visual Studio environment on Windows (required for nvcc to find cl.exe) @@ -550,7 +550,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - ref: ${{ inputs.sha || github.sha }} + ref: ${{ github.event.inputs.sha || github.sha }} - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 @@ -618,7 +618,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - ref: ${{ inputs.sha || github.sha }} + ref: ${{ github.event.inputs.sha || github.sha }} - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 @@ -677,7 +677,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - ref: ${{ inputs.sha || github.sha }} + ref: ${{ github.event.inputs.sha || github.sha }} - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 3e851d520..5aab8e3d6 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -210,7 +210,7 @@ jobs: if: github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) run: just python-ci-core - - name: Run core Python smoke tests (PR fast path) + - name: Validate Python lockfile (PR fast path) if: github.event_name == 'pull_request' run: uv lock --check --project . From 581127b31f03df13fb2f38977c823b98f3554b85 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 08:15:16 -0500 Subject: [PATCH 40/58] ci: address final review feedback on rust-test and compat-smoke - Rust-test: Move per-step event guards to job-level skip condition to prevent non-Ubuntu PRs from running as all-green no-op jobs (only checkout, no tests) - Python compat-smoke: Ensure macOS cells with include-llvm:true also import pecos_rslib_llvm to validate the LLVM wheel is actually functional Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 7 ++++++- .github/workflows/rust-test.yml | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 5aab8e3d6..54ee97c6c 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -486,7 +486,12 @@ jobs: if [ "${{ matrix.include-pecos }}" = "true" ]; then python -c 'from importlib.metadata import version; import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' else - python -c 'import pecos_rslib; print({"pecos_rslib": pecos_rslib.__version__})' + # On macOS with include-llvm: true, also verify pecos_rslib_llvm is importable to ensure LLVM wheel is valid + if [ "$(uname)" = "Darwin" ] && [ "${{ matrix.include-llvm }}" = "true" ]; then + python -c 'from importlib.metadata import version; import pecos_rslib; import pecos_rslib_llvm; print({"pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' + else + python -c 'import pecos_rslib; print({"pecos_rslib": pecos_rslib.__version__})' + fi fi python-slow-postmerge: diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index 42e2d6996..6632f5e80 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -204,7 +204,7 @@ jobs: sudo apt-get clean - name: Set up Rust (Windows) - if: runner.os == 'Windows' && github.event_name != 'pull_request' + if: runner.os == 'Windows' && (github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest') run: | rustup set default-host x86_64-pc-windows-msvc rustup toolchain install stable --profile minimal @@ -241,7 +241,7 @@ jobs: key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 - name: Bootstrap MSVC for the Cargo build path (Windows) - if: runner.os == 'Windows' && github.event_name != 'pull_request' + if: runner.os == 'Windows' && (github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest') shell: pwsh # Single mechanism: writes the linker + LIB/INCLUDE into # .cargo/config.toml (read by cargo after it spawns). Sets no env pin, From 1763cca90dd10098bff8ee63d7058d8f13d39ee6 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 08:26:21 -0500 Subject: [PATCH 41/58] ci: skip non-ubuntu rust matrix on PRs Use a conditional matrix so pull_request runs only ubuntu-latest in rust-test, avoiding no-op green macOS/Windows entries while keeping full matrix on pushes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/rust-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index 6632f5e80..30371596b 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -184,7 +184,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2022] + os: ${{ github.event_name == 'pull_request' && fromJSON('["ubuntu-latest"]') || fromJSON('["ubuntu-latest", "macos-latest", "windows-2022"]') }} steps: - name: Harden the runner (egress audit) From a0798d29db5833a5f2c86a542b33a7b5eb008b60 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 08:46:09 -0500 Subject: [PATCH 42/58] ci: fix compat smoke failure and tighten cache policy checks - avoid macOS llvm smoke import crash by validating installed llvm wheel metadata - harden dependency-integrity cache-write checks to require push && trusted refs - deduplicate docs sync recipe by delegating to python-ci-sync Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-test.yml | 5 +++-- Justfile | 7 +------ scripts/dependency-integrity-check.sh | 6 +++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 54ee97c6c..894236376 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -486,9 +486,10 @@ jobs: if [ "${{ matrix.include-pecos }}" = "true" ]; then python -c 'from importlib.metadata import version; import pecos; import pecos_rslib; import pecos_rslib_llvm; print({"pecos": pecos.__version__, "pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' else - # On macOS with include-llvm: true, also verify pecos_rslib_llvm is importable to ensure LLVM wheel is valid + # On macOS with include-llvm: true, validate the installed LLVM wheel package + # via metadata; importing the extension is currently not runtime-stable there. if [ "$(uname)" = "Darwin" ] && [ "${{ matrix.include-llvm }}" = "true" ]; then - python -c 'from importlib.metadata import version; import pecos_rslib; import pecos_rslib_llvm; print({"pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' + python -c 'from importlib.metadata import version; import pecos_rslib; print({"pecos_rslib": pecos_rslib.__version__, "pecos_rslib_llvm": version("pecos-rslib-llvm")})' else python -c 'import pecos_rslib; print({"pecos_rslib": pecos_rslib.__version__})' fi diff --git a/Justfile b/Justfile index 72854029b..b19c87b82 100644 --- a/Justfile +++ b/Justfile @@ -907,12 +907,7 @@ python-ci-sync-test: python-ci-sync-docs: #!/usr/bin/env bash set -euo pipefail - uv sync --locked \ - --group dev \ - --group test \ - --package pecos-rslib \ - --package pecos-rslib-llvm \ - --package quantum-pecos + just python-ci-sync [group('setup')] python-ci-sync-lint: diff --git a/scripts/dependency-integrity-check.sh b/scripts/dependency-integrity-check.sh index eebc274ec..9a57ed65d 100755 --- a/scripts/dependency-integrity-check.sh +++ b/scripts/dependency-integrity-check.sh @@ -404,7 +404,7 @@ while IFS=: read -r file line _; do save_if_line="$(sed -n "${line},$((line + 16))p" "$file" | rg -o "save-if:.*" | head -1 || true)" if [[ -z "$save_if_line" ]] || printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || - ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'" || + ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || ! printf '%s\n' "$save_if_line" | rg -q "($trusted_cache_ref_re)"; then cache_policy_failures+=("$file:$line rust-cache save-if must be restricted to trusted branch pushes") fi @@ -416,7 +416,7 @@ while IFS=: read -r file line _; do if printf '%s\n' "$setup_uv_block" | rg -q 'enable-cache:\s*true' && ([[ -z "$save_cache_line" ]] || printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'pull_request'" || - ! printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'push'" || + ! printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || ! printf '%s\n' "$save_cache_line" | rg -q "($trusted_cache_ref_re)"); then cache_policy_failures+=("$file:$line setup-uv save-cache must be restricted to trusted branch pushes") fi @@ -430,7 +430,7 @@ while IFS=: read -r file line _; do save_if_line="$(sed -n "$((line - 2)),$((line + 2))p" "$file" | rg -o "if:[[:space:]]*.*" | head -1 || true)" if [[ -z "$save_if_line" ]] || printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || - ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'" || + ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || ! printf '%s\n' "$save_if_line" | rg -q "($trusted_cache_ref_re)"; then cache_policy_failures+=("$file:$line actions/cache/save must be restricted to trusted branch pushes") fi From 670b6c3e3a092c8c11706d01df166da2671943b1 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 10:00:13 -0500 Subject: [PATCH 43/58] ci: relax trusted ref regex whitespace in integrity check Allow optional whitespace in contains(fromJSON(...), github.ref_name) trusted-branch expressions so formatting differences do not cause false failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- scripts/dependency-integrity-check.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dependency-integrity-check.sh b/scripts/dependency-integrity-check.sh index 9a57ed65d..2851d654d 100755 --- a/scripts/dependency-integrity-check.sh +++ b/scripts/dependency-integrity-check.sh @@ -399,7 +399,7 @@ fi section "GitHub Actions cache write posture" cache_policy_failures=() -trusted_cache_ref_re="github\\.ref_name == '(main|master|development|dev)'|contains\\(fromJSON\\('\\[\\\"main\\\", \\\"master\\\", \\\"development\\\", \\\"dev\\\"\\]'\\), github\\.ref_name\\)|github\\.ref_name == 'main'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'master'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'development'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'dev'" +trusted_cache_ref_re="github\\.ref_name == '(main|master|development|dev)'|contains\\(fromJSON\\('\\[[[:space:]]*\\\"main\\\"[[:space:]]*,[[:space:]]*\\\"master\\\"[[:space:]]*,[[:space:]]*\\\"development\\\"[[:space:]]*,[[:space:]]*\\\"dev\\\"[[:space:]]*\\]'\\)[[:space:]]*,[[:space:]]*github\\.ref_name\\)|github\\.ref_name == 'main'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'master'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'development'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'dev'" while IFS=: read -r file line _; do save_if_line="$(sed -n "${line},$((line + 16))p" "$file" | rg -o "save-if:.*" | head -1 || true)" if [[ -z "$save_if_line" ]] || From 826619f5c1170da125e543ca1538027008a28307 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 13:15:38 -0500 Subject: [PATCH 44/58] ci: close remaining PR review gaps - parse multiline YAML cache guards before validating cache-write policy - expand Python and Rust workflow path filters for example and bootstrap script changes - make python-release artifact collection fail closed and count llvm wheels Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-release.yml | 51 +++++++++++++-- .github/workflows/python-test.yml | 4 ++ .github/workflows/rust-test.yml | 4 ++ scripts/dependency-integrity-check.sh | 94 +++++++++++++++++++++++++-- 4 files changed, 141 insertions(+), 12 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 5fa2da68d..fda95bcbe 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -740,6 +740,7 @@ jobs: - name: Create distribution directories run: | mkdir -p dist/pecos-rslib + mkdir -p dist/pecos-rslib-llvm mkdir -p dist/quantum-pecos # Download artifacts into temp directory first @@ -750,34 +751,70 @@ jobs: - name: Organize distribution files run: | + shopt -s nullglob + # Debug: Show what we downloaded echo "=== Downloaded artifacts structure ===" ls -la temp-artifacts/ # Move pecos-rslib and pecos-rslib-llvm wheels to distribution directory - mkdir -p dist/pecos-rslib-llvm + llvm_dirs=(temp-artifacts/wheel-pecos-rslib-llvm-*/) + if [ "${#llvm_dirs[@]}" -eq 0 ]; then + echo "Expected pecos-rslib-llvm artifact directories, but none were found." + exit 1 + fi for artifact in temp-artifacts/wheel-pecos-rslib-llvm-*/; do if [ -d "$artifact" ]; then echo "Processing $artifact" - mv "$artifact"*.whl dist/pecos-rslib-llvm/ 2>/dev/null || true + llvm_wheels=("$artifact"*.whl) + if [ "${#llvm_wheels[@]}" -eq 0 ]; then + echo "Expected pecos-rslib-llvm wheels in $artifact, but none were found." + exit 1 + fi + mv "${llvm_wheels[@]}" dist/pecos-rslib-llvm/ fi done + rslib_dirs=(temp-artifacts/wheel-pecos-rslib-*/) + if [ "${#rslib_dirs[@]}" -eq 0 ]; then + echo "Expected pecos-rslib artifact directories, but none were found." + exit 1 + fi for artifact in temp-artifacts/wheel-pecos-rslib-*/; do if [ -d "$artifact" ]; then echo "Processing $artifact" - mv "$artifact"*.whl dist/pecos-rslib/ 2>/dev/null || true + rslib_wheels=("$artifact"*.whl) + if [ "${#rslib_wheels[@]}" -eq 0 ]; then + echo "Expected pecos-rslib wheels in $artifact, but none were found." + exit 1 + fi + mv "${rslib_wheels[@]}" dist/pecos-rslib/ fi done # Move quantum-pecos files to distribution directory + quantum_dirs=(temp-artifacts/*-quantum-pecos*/) + if [ "${#quantum_dirs[@]}" -eq 0 ]; then + echo "Expected quantum-pecos artifact directories, but none were found." + exit 1 + fi for artifact in temp-artifacts/*-quantum-pecos*/; do if [ -d "$artifact" ]; then echo "Processing $artifact" - mv "$artifact"*.whl dist/quantum-pecos/ 2>/dev/null || true - mv "$artifact"*.tar.gz dist/quantum-pecos/ 2>/dev/null || true + quantum_dists=("$artifact"*.whl "$artifact"*.tar.gz) + if [ "${#quantum_dists[@]}" -eq 0 ]; then + echo "Expected quantum-pecos distributions in $artifact, but none were found." + exit 1 + fi + mv "${quantum_dists[@]}" dist/quantum-pecos/ fi done + llvm_wheels=(dist/pecos-rslib-llvm/*.whl) + if [ "${#llvm_wheels[@]}" -eq 0 ]; then + echo "Expected collected pecos-rslib-llvm wheels, but none were found." + exit 1 + fi + # Clean up rm -rf temp-artifacts @@ -786,11 +823,15 @@ jobs: echo "=== pecos-rslib artifacts ===" ls -la dist/pecos-rslib/ echo "" + echo "=== pecos-rslib-llvm artifacts ===" + ls -la dist/pecos-rslib-llvm/ + echo "" echo "=== quantum-pecos artifacts ===" ls -la dist/quantum-pecos/ echo "" echo "=== Summary ===" echo "pecos-rslib wheels: $(ls -1 dist/pecos-rslib/*.whl 2>/dev/null | wc -l)" + echo "pecos-rslib-llvm wheels: $(ls -1 dist/pecos-rslib-llvm/*.whl 2>/dev/null | wc -l)" echo "quantum-pecos distributions: $(ls -1 dist/quantum-pecos/* 2>/dev/null | wc -l)" diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index f92b081d4..11b717ccb 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -18,6 +18,7 @@ on: branches: [ "main", "master", "development", "dev" ] paths: - 'python/**' + - 'examples/**' - 'crates/**' - 'Cargo.toml' - 'Cargo.lock' @@ -27,12 +28,14 @@ on: - 'uv.lock' - 'Justfile' - 'scripts/ci/**' + - 'scripts/win-msvc-bootstrap.ps1' - 'scripts/check_python_workspace.py' - '.github/workflows/python-test.yml' pull_request: branches: [ "main", "master", "development", "dev" ] paths: - 'python/**' + - 'examples/**' - 'crates/**' - 'Cargo.toml' - 'Cargo.lock' @@ -42,6 +45,7 @@ on: - 'uv.lock' - 'Justfile' - 'scripts/ci/**' + - 'scripts/win-msvc-bootstrap.ps1' - 'scripts/check_python_workspace.py' - '.github/workflows/python-test.yml' workflow_dispatch: diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index 30371596b..ad585b335 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -23,6 +23,8 @@ on: - 'Cargo.toml' - 'Cargo.lock' - 'Justfile' + - 'scripts/ci/**' + - 'scripts/win-msvc-bootstrap.ps1' - '.github/workflows/rust-test.yml' - '.pre-commit-config.yaml' pull_request: @@ -38,6 +40,8 @@ on: - 'Cargo.toml' - 'Cargo.lock' - 'Justfile' + - 'scripts/ci/**' + - 'scripts/win-msvc-bootstrap.ps1' - '.github/workflows/rust-test.yml' - '.pre-commit-config.yaml' diff --git a/scripts/dependency-integrity-check.sh b/scripts/dependency-integrity-check.sh index 2851d654d..4ca79bea0 100755 --- a/scripts/dependency-integrity-check.sh +++ b/scripts/dependency-integrity-check.sh @@ -46,6 +46,83 @@ collect_files() { rg --files "$@" } +extract_yaml_scalar_near() { + local file="$1" + local start_line="$2" + local end_line="$3" + local key="$4" + awk -v start="$start_line" -v end="$end_line" -v key="$key" ' + NR < start || NR > end { next } + !found && $0 ~ "^[[:space:]]*" key ":[[:space:]]*" { + found = 1 + match($0, /^[[:space:]]*/) + base_indent = RLENGTH + line = $0 + sub("^[[:space:]]*" key ":[[:space:]]*", "", line) + out = line + next + } + found { + if ($0 ~ /^[[:space:]]*$/) { + next + } + match($0, /^[[:space:]]*/) + indent = RLENGTH + if (indent <= base_indent) { + exit + } + line = $0 + sub(/^[[:space:]]*/, "", line) + out = out " " line + } + END { + gsub(/[[:space:]]+/, " ", out) + print out + } + ' "$file" +} + +trusted_cache_ref_ok() { + local expr="$1" + if [[ "$expr" == *"github.ref_name == 'main'"* ]] || + [[ "$expr" == *"github.ref_name == 'master'"* ]] || + [[ "$expr" == *"github.ref_name == 'development'"* ]] || + [[ "$expr" == *"github.ref_name == 'dev'"* ]]; then + return 0 + fi + if [[ "$expr" == *"contains(fromJSON("* ]] && + [[ "$expr" == *"github.ref_name"* ]] && + [[ "$expr" == *'"main"'* ]] && + [[ "$expr" == *'"master"'* ]] && + [[ "$expr" == *'"development"'* ]] && + [[ "$expr" == *'"dev"'* ]]; then + return 0 + fi + return 1 +} + +has_unsafe_cache_disjunction() { + local expr="$1" + python3 - "$expr" <<'PY' +import re +import sys + +expr = sys.argv[1] +marker = "github.event_name == 'push' &&" +idx = expr.find(marker) +if idx != -1: + expr = expr[idx:] +allowed = re.compile( + r"github\.ref_name == 'main'\s*\|\|\s*" + r"github\.ref_name == 'master'\s*\|\|\s*" + r"github\.ref_name == 'development'\s*\|\|\s*" + r"github\.ref_name == 'dev'" +) +stripped = allowed.sub("TRUSTED_REF_SET", expr) +sys.exit(0 if "||" in stripped else 1) +PY +} + # Static indicator lists for known supply-chain worm campaigns (the # Shai-Hulud npm worm and related typosquats). These catch KNOWN-bad # package names and payload/persistence indicators only -- novel campaigns @@ -76,6 +153,7 @@ tooling_failures_before=$failures require_tool rg || true require_tool cargo || true require_tool uv || true +require_tool python3 || true if ((failures > tooling_failures_before)); then printf '\nDependency integrity check failed: required tooling is missing.\n' >&2 exit 1 @@ -399,25 +477,26 @@ fi section "GitHub Actions cache write posture" cache_policy_failures=() -trusted_cache_ref_re="github\\.ref_name == '(main|master|development|dev)'|contains\\(fromJSON\\('\\[[[:space:]]*\\\"main\\\"[[:space:]]*,[[:space:]]*\\\"master\\\"[[:space:]]*,[[:space:]]*\\\"development\\\"[[:space:]]*,[[:space:]]*\\\"dev\\\"[[:space:]]*\\]'\\)[[:space:]]*,[[:space:]]*github\\.ref_name\\)|github\\.ref_name == 'main'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'master'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'development'[[:space:]]*\\|\\|[[:space:]]*github\\.ref_name == 'dev'" while IFS=: read -r file line _; do - save_if_line="$(sed -n "${line},$((line + 16))p" "$file" | rg -o "save-if:.*" | head -1 || true)" + save_if_line="$(extract_yaml_scalar_near "$file" "$line" "$((line + 16))" "save-if")" if [[ -z "$save_if_line" ]] || + has_unsafe_cache_disjunction "$save_if_line" || printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || - ! printf '%s\n' "$save_if_line" | rg -q "($trusted_cache_ref_re)"; then + ! trusted_cache_ref_ok "$save_if_line"; then cache_policy_failures+=("$file:$line rust-cache save-if must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+Swatinem/rust-cache@' .github/workflows || true) while IFS=: read -r file line _; do setup_uv_block="$(sed -n "${line},$((line + 16))p" "$file")" - save_cache_line="$(printf '%s\n' "$setup_uv_block" | rg -o "save-cache:.*" | head -1 || true)" + save_cache_line="$(extract_yaml_scalar_near "$file" "$line" "$((line + 16))" "save-cache")" if printf '%s\n' "$setup_uv_block" | rg -q 'enable-cache:\s*true' && ([[ -z "$save_cache_line" ]] || + has_unsafe_cache_disjunction "$save_cache_line" || printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'pull_request'" || ! printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || - ! printf '%s\n' "$save_cache_line" | rg -q "($trusted_cache_ref_re)"); then + ! trusted_cache_ref_ok "$save_cache_line"); then cache_policy_failures+=("$file:$line setup-uv save-cache must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+astral-sh/setup-uv@' .github/workflows || true) @@ -427,11 +506,12 @@ while IFS=: read -r file line _; do done < <(rg -n 'uses:\s+actions/cache@' .github/workflows || true) while IFS=: read -r file line _; do - save_if_line="$(sed -n "$((line - 2)),$((line + 2))p" "$file" | rg -o "if:[[:space:]]*.*" | head -1 || true)" + save_if_line="$(extract_yaml_scalar_near "$file" "$((line - 2))" "$((line + 2))" "if")" if [[ -z "$save_if_line" ]] || + has_unsafe_cache_disjunction "$save_if_line" || printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || - ! printf '%s\n' "$save_if_line" | rg -q "($trusted_cache_ref_re)"; then + ! trusted_cache_ref_ok "$save_if_line"; then cache_policy_failures+=("$file:$line actions/cache/save must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+actions/cache/save@' .github/workflows || true) From ad2633002d83b0c76fa2ed9b49f5c2b154ad2d8b Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 26 Jun 2026 14:28:06 -0500 Subject: [PATCH 45/58] ci: allowlist cache guards and fix release wheel collector Address adversarial review of 826619f5 (findings A, B, C). Cache-write guard (A/B): replace the bypassable syntax blacklist in dependency-integrity-check.sh with a structural allowlist. cache_guard_ok extracts the actual YAML scalar for the step's guard key and requires a top-level "&&" chain (no top-level "||", no unary negation) containing an exact `github.event_name == 'push'` predicate and a canonical trusted-ref predicate (contains(fromJSON('[trusted set]'), github.ref_name) or an explicit github.ref_name == '' disjunction over exactly the trusted set). This rejects the !(...), `!= 'push'`, and contains-on-literal bypasses, the multiline `|| pull_request` tail, and block scalars, while accepting valid reordered branch chains. Removes the now-unused blacklist helpers. Release collector (C): the rslib loop glob `wheel-pecos-rslib-*` also matched `wheel-pecos-rslib-llvm-*`, which the llvm loop had already emptied, causing a hard `exit 1` on any release containing LLVM wheels. Exclude `*-llvm-*` dirs from the rslib loop so both families collect independently. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/python-release.yml | 12 +- scripts/dependency-integrity-check.sh | 272 +++++++++++++++++--------- 2 files changed, 193 insertions(+), 91 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index fda95bcbe..355b33284 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -774,12 +774,20 @@ jobs: mv "${llvm_wheels[@]}" dist/pecos-rslib-llvm/ fi done - rslib_dirs=(temp-artifacts/wheel-pecos-rslib-*/) + # Collect only base pecos-rslib dirs; exclude pecos-rslib-llvm-*, + # whose prefix overlaps the glob and whose wheels were moved above. + rslib_dirs=() + for artifact in temp-artifacts/wheel-pecos-rslib-*/; do + case "$artifact" in + temp-artifacts/wheel-pecos-rslib-llvm-*/) continue ;; + esac + rslib_dirs+=("$artifact") + done if [ "${#rslib_dirs[@]}" -eq 0 ]; then echo "Expected pecos-rslib artifact directories, but none were found." exit 1 fi - for artifact in temp-artifacts/wheel-pecos-rslib-*/; do + for artifact in "${rslib_dirs[@]}"; do if [ -d "$artifact" ]; then echo "Processing $artifact" rslib_wheels=("$artifact"*.whl) diff --git a/scripts/dependency-integrity-check.sh b/scripts/dependency-integrity-check.sh index 4ca79bea0..a3b91616f 100755 --- a/scripts/dependency-integrity-check.sh +++ b/scripts/dependency-integrity-check.sh @@ -46,80 +46,189 @@ collect_files() { rg --files "$@" } -extract_yaml_scalar_near() { - local file="$1" - local start_line="$2" - local end_line="$3" - local key="$4" - awk -v start="$start_line" -v end="$end_line" -v key="$key" ' - NR < start || NR > end { next } - !found && $0 ~ "^[[:space:]]*" key ":[[:space:]]*" { - found = 1 - match($0, /^[[:space:]]*/) - base_indent = RLENGTH - line = $0 - sub("^[[:space:]]*" key ":[[:space:]]*", "", line) - out = line - next - } - found { - if ($0 ~ /^[[:space:]]*$/) { - next - } - match($0, /^[[:space:]]*/) - indent = RLENGTH - if (indent <= base_indent) { - exit - } - line = $0 - sub(/^[[:space:]]*/, "", line) - out = out " " line - } - END { - gsub(/[[:space:]]+/, " ", out) - print out - } - ' "$file" -} - -trusted_cache_ref_ok() { - local expr="$1" - if [[ "$expr" == *"github.ref_name == 'main'"* ]] || - [[ "$expr" == *"github.ref_name == 'master'"* ]] || - [[ "$expr" == *"github.ref_name == 'development'"* ]] || - [[ "$expr" == *"github.ref_name == 'dev'"* ]]; then - return 0 - fi - if [[ "$expr" == *"contains(fromJSON("* ]] && - [[ "$expr" == *"github.ref_name"* ]] && - [[ "$expr" == *'"main"'* ]] && - [[ "$expr" == *'"master"'* ]] && - [[ "$expr" == *'"development"'* ]] && - [[ "$expr" == *'"dev"'* ]]; then - return 0 - fi - return 1 -} - -has_unsafe_cache_disjunction() { - local expr="$1" - python3 - "$expr" <<'PY' +# Validate that a GitHub Actions cache-write guard can ONLY be true on a +# trusted-branch push. Rather than blacklisting unsafe syntax (which is +# repeatedly bypassable), this extracts the actual YAML scalar for the guard +# key on the matched step and structurally ALLOWLISTS it: the expression must +# be a top-level "&&" chain (no top-level "||", no negation) that includes an +# exact canonical event predicate (github.event_name == 'push') AND a canonical +# trusted-ref predicate (contains(fromJSON('[]'), github.ref_name), +# or an explicit github.ref_name == '' disjunction over exactly the +# trusted set). Extra conjuncts (e.g. cache-hit checks) are permitted because an +# "&&" chain anchored to a trusted-push predicate can only further restrict it. +cache_guard_ok() { + CACHE_GUARD_FILE="$1" CACHE_GUARD_LINE="$2" CACHE_GUARD_KEY="$3" python3 - <<'PY' +import os import re import sys -expr = sys.argv[1] -marker = "github.event_name == 'push' &&" -idx = expr.find(marker) -if idx != -1: - expr = expr[idx:] -allowed = re.compile( - r"github\.ref_name == 'main'\s*\|\|\s*" - r"github\.ref_name == 'master'\s*\|\|\s*" - r"github\.ref_name == 'development'\s*\|\|\s*" - r"github\.ref_name == 'dev'" -) -stripped = allowed.sub("TRUSTED_REF_SET", expr) -sys.exit(0 if "||" in stripped else 1) +path = os.environ["CACHE_GUARD_FILE"] +target = int(os.environ["CACHE_GUARD_LINE"]) +key = os.environ["CACHE_GUARD_KEY"] + +with open(path) as fh: + lines = fh.read().split("\n") +n = len(lines) +idx = target - 1 + + +def indent(text): + return len(text) - len(text.lstrip(" ")) + + +# Find the start of the step (list item) that owns the matched line. +step_start = None +step_indent = 0 +for i in range(min(idx, n - 1), -1, -1): + stripped = lines[i].lstrip(" ") + if stripped.startswith("- "): + step_start = i + step_indent = indent(lines[i]) + break +if step_start is None: + sys.exit(1) + +# The step ends at the next sibling list item or any dedent below it. +step_end = n +for i in range(step_start + 1, n): + if lines[i].strip() == "": + continue + ind = indent(lines[i]) + if ind < step_indent or (ind == step_indent and lines[i].lstrip(" ").startswith("- ")): + step_end = i + break + +key_re = re.compile(r"^(\s*)(-\s+)?" + re.escape(key) + r"\s*:(.*)$") +found = None +for i in range(step_start, step_end): + m = key_re.match(lines[i]) + if m: + found = (i, m) + break +if found is None: + sys.exit(1) + +ki, m = found +key_indent = len(m.group(1)) + (len(m.group(2)) if m.group(2) else 0) +value = m.group(3).strip() +for i in range(ki + 1, step_end): + if lines[i].strip() == "": + continue + if indent(lines[i]) <= key_indent: + break + value += " " + lines[i].strip() + +value = re.sub(r"\s+", " ", value).strip() +# `if:` conditions may omit the ${{ }} wrapper; action `with:` inputs include +# it. Accept either, but a bare scalar (e.g. true) simply won't satisfy the +# trusted-push predicate checks below. +wrapped = re.match(r"^\$\{\{(.*)\}\}$", value) +expr = wrapped.group(1).strip() if wrapped else value + + +def has_unary_not(text): + in_q = False + for j, ch in enumerate(text): + if ch == "'": + in_q = not in_q + continue + if in_q: + continue + if ch == "!" and not (j + 1 < len(text) and text[j + 1] == "="): + return True + return False + + +def split_top(text, op): + parts = [] + buf = "" + depth = 0 + in_q = False + i = 0 + while i < len(text): + ch = text[i] + if ch == "'": + in_q = not in_q + buf += ch + i += 1 + continue + if in_q: + buf += ch + i += 1 + continue + if ch == "(": + depth += 1 + elif ch == ")": + depth -= 1 + if depth == 0 and text[i:i + 2] == op: + parts.append(buf) + buf = "" + i += 2 + continue + buf += ch + i += 1 + parts.append(buf) + return parts + + +def strip_parens(text): + text = text.strip() + while text.startswith("(") and text.endswith(")"): + depth = 0 + ok = True + for j, ch in enumerate(text): + if ch == "(": + depth += 1 + elif ch == ")": + depth -= 1 + if depth == 0 and j != len(text) - 1: + ok = False + break + if not ok: + break + text = text[1:-1].strip() + return text + + +def norm(text): + return re.sub(r"\s+", " ", text.strip()) + + +TRUSTED = {"main", "master", "development", "dev"} + +if has_unary_not(expr): + sys.exit(1) +if len(split_top(expr, "||")) > 1: + sys.exit(1) + +conjuncts = [norm(strip_parens(c)) for c in split_top(expr, "&&")] + + +def is_event_push(c): + return c == "github.event_name == 'push'" + + +def is_trusted_ref(c): + m1 = re.match( + r"^contains\(\s*fromJSON\(\s*'\[(.*)\]'\s*\)\s*,\s*github\.ref_name\s*\)$", + c, + ) + if m1: + names = {it.strip().strip('"').strip("'").strip() for it in m1.group(1).split(",")} + return names == TRUSTED + ors = [norm(strip_parens(o)) for o in split_top(c, "||")] + names = set() + for o in ors: + mo = re.match(r"^github\.ref_name == '([^']*)'$", o) + if not mo: + return False + names.add(mo.group(1)) + return names == TRUSTED + + +has_push = any(is_event_push(c) for c in conjuncts) +has_ref = any(is_trusted_ref(c) for c in conjuncts) +sys.exit(0 if (has_push and has_ref) else 1) PY } @@ -478,25 +587,15 @@ fi section "GitHub Actions cache write posture" cache_policy_failures=() while IFS=: read -r file line _; do - save_if_line="$(extract_yaml_scalar_near "$file" "$line" "$((line + 16))" "save-if")" - if [[ -z "$save_if_line" ]] || - has_unsafe_cache_disjunction "$save_if_line" || - printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || - ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || - ! trusted_cache_ref_ok "$save_if_line"; then + if ! cache_guard_ok "$file" "$line" "save-if"; then cache_policy_failures+=("$file:$line rust-cache save-if must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+Swatinem/rust-cache@' .github/workflows || true) while IFS=: read -r file line _; do setup_uv_block="$(sed -n "${line},$((line + 16))p" "$file")" - save_cache_line="$(extract_yaml_scalar_near "$file" "$line" "$((line + 16))" "save-cache")" if printf '%s\n' "$setup_uv_block" | rg -q 'enable-cache:\s*true' && - ([[ -z "$save_cache_line" ]] || - has_unsafe_cache_disjunction "$save_cache_line" || - printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'pull_request'" || - ! printf '%s\n' "$save_cache_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || - ! trusted_cache_ref_ok "$save_cache_line"); then + ! cache_guard_ok "$file" "$line" "save-cache"; then cache_policy_failures+=("$file:$line setup-uv save-cache must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+astral-sh/setup-uv@' .github/workflows || true) @@ -506,12 +605,7 @@ while IFS=: read -r file line _; do done < <(rg -n 'uses:\s+actions/cache@' .github/workflows || true) while IFS=: read -r file line _; do - save_if_line="$(extract_yaml_scalar_near "$file" "$((line - 2))" "$((line + 2))" "if")" - if [[ -z "$save_if_line" ]] || - has_unsafe_cache_disjunction "$save_if_line" || - printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'pull_request'" || - ! printf '%s\n' "$save_if_line" | rg -q "github\\.event_name == 'push'[[:space:]]*&&" || - ! trusted_cache_ref_ok "$save_if_line"; then + if ! cache_guard_ok "$file" "$line" "if"; then cache_policy_failures+=("$file:$line actions/cache/save must be restricted to trusted branch pushes") fi done < <(rg -n 'uses:\s+actions/cache/save@' .github/workflows || true) From c73ccf23d1102a3649f7a4137de2b4fd20735503 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 12:35:28 -0600 Subject: [PATCH 46/58] Stop tracking scripts/native_bench/bench_pecos/Cargo.lock to avoid dependabot noise --- .gitignore | 5 + scripts/native_bench/bench_pecos/Cargo.lock | 4305 ------------------- 2 files changed, 5 insertions(+), 4305 deletions(-) delete mode 100644 scripts/native_bench/bench_pecos/Cargo.lock diff --git a/.gitignore b/.gitignore index 1a7260524..f2a2fb90f 100644 --- a/.gitignore +++ b/.gitignore @@ -219,3 +219,8 @@ python/selene-plugins/*/uv.lock # regenerates Cargo.lock on demand; tracking it just creates dependabot # noise for transitive bumps that don't affect anything we ship. python/quantum-pecos/tests/docs/rust_crate/Cargo.lock + +# Native simulator bench tool: its own (empty) workspace, publish = false, +# path-deps into the workspace crates. Same rationale as above -- cargo +# regenerates Cargo.lock on demand and tracking it only adds dependabot noise. +scripts/native_bench/bench_pecos/Cargo.lock diff --git a/scripts/native_bench/bench_pecos/Cargo.lock b/scripts/native_bench/bench_pecos/Cargo.lock deleted file mode 100644 index 5030ea8a4..000000000 --- a/scripts/native_bench/bench_pecos/Cargo.lock +++ /dev/null @@ -1,4305 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" - -[[package]] -name = "anstyle-parse" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.61.2", -] - -[[package]] -name = "anyhow" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - -[[package]] -name = "arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "ash" -version = "0.38.0+1.3.281" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" -dependencies = [ - "libloading 0.8.9", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "aws-lc-rs" -version = "1.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.39.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bench-pecos" -version = "0.1.0" -dependencies = [ - "pecos-core", - "pecos-cuquantum", - "pecos-gpu-sims", - "pecos-simulators", -] - -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 2.1.2", - "shlex", - "syn", -] - -[[package]] -name = "bit-set" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" -dependencies = [ - "bit-vec 0.7.0", -] - -[[package]] -name = "bit-set" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ddef2995421ab6a5c779542c81ee77c115206f4ad9d5a8e05f4ff49716a3dd" -dependencies = [ - "bit-vec 0.9.1", -] - -[[package]] -name = "bit-vec" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" - -[[package]] -name = "bit-vec" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" - -[[package]] -name = "bitflags" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "serde", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "block2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" -dependencies = [ - "objc2", -] - -[[package]] -name = "bumpalo" -version = "3.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" - -[[package]] -name = "bytemuck" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - -[[package]] -name = "bzip2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" -dependencies = [ - "libbz2-rs-sys", -] - -[[package]] -name = "camino" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" -dependencies = [ - "serde_core", -] - -[[package]] -name = "cargo-platform" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082" -dependencies = [ - "serde", - "serde_core", -] - -[[package]] -name = "cargo_metadata" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror 2.0.18", -] - -[[package]] -name = "cc" -version = "1.2.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chacha20" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "rand_core 0.10.0", -] - -[[package]] -name = "chrono" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" -dependencies = [ - "num-traits", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading 0.8.9", -] - -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - -[[package]] -name = "codespan-reporting" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" -dependencies = [ - "serde", - "termcolor", - "unicode-width", -] - -[[package]] -name = "colorchoice" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crypto-common" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.7", -] - -[[package]] -name = "digest" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" -dependencies = [ - "block-buffer 0.12.0", - "const-oid", - "crypto-common 0.2.1", -] - -[[package]] -name = "dirs" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.61.2", -] - -[[package]] -name = "dispatch2" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" -dependencies = [ - "bitflags", - "objc2", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dlib" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" -dependencies = [ - "libloading 0.8.9", -] - -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "env_filter" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fastrand" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" - -[[package]] -name = "filetime" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" -dependencies = [ - "cfg-if", - "libc", - "libredox", -] - -[[package]] -name = "filetime_creation" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c25b5d475550e559de5b0c0084761c65325444e3b6c9e298af9cefe7a9ef3a5f" -dependencies = [ - "cfg-if", - "filetime", - "windows-sys 0.52.0", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - -[[package]] -name = "flate2" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures-channel" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-io" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" - -[[package]] -name = "futures-sink" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", - "rand_core 0.10.0", - "wasip2", - "wasip3", -] - -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - -[[package]] -name = "glam" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "333928d5eb103c5d4050533cec0384302db6be8ef7d3cebd30ec6a35350353da" - -[[package]] -name = "glam" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3abb554f8ee44336b72d522e0a7fe86a29e09f839a36022fa869a7dfe941a54b" - -[[package]] -name = "glam" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4126c0479ccf7e8664c36a2d719f5f2c140fbb4f9090008098d2c291fa5b3f16" - -[[package]] -name = "glam" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01732b97afd8508eee3333a541b9f7610f454bb818669e66e90f5f57c93a776" - -[[package]] -name = "glam" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525a3e490ba77b8e326fb67d4b44b4bd2f920f44d4cc73ccec50adc68e3bee34" - -[[package]] -name = "glam" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8509e6791516e81c1a630d0bd7fbac36d2fa8712a9da8662e716b52d5051ca" - -[[package]] -name = "glam" -version = "0.20.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43e957e744be03f5801a55472f593d43fabdebf25a4585db250f04d86b1675f" - -[[package]] -name = "glam" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815" - -[[package]] -name = "glam" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" - -[[package]] -name = "glam" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" - -[[package]] -name = "glam" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" - -[[package]] -name = "glam" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" - -[[package]] -name = "glam" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9" - -[[package]] -name = "glam" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94" - -[[package]] -name = "glam" -version = "0.29.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" - -[[package]] -name = "glam" -version = "0.30.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9" - -[[package]] -name = "glam" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556f6b2ea90b8d15a74e0e7bb41671c9bdf38cd9f78c284d750b9ce58a2b5be7" - -[[package]] -name = "glam" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f70749695b063ecbf6b62949ccccde2e733ec3ecbbd71d467dca4e5c6c97cca0" - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "glow" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" -dependencies = [ - "gl_generator", -] - -[[package]] -name = "gpu-allocator" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" -dependencies = [ - "ash", - "hashbrown 0.16.1", - "log", - "presser", - "thiserror 2.0.18", - "windows", -] - -[[package]] -name = "gpu-descriptor" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" -dependencies = [ - "bitflags", - "gpu-descriptor-types", - "hashbrown 0.15.5", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" -dependencies = [ - "bitflags", -] - -[[package]] -name = "half" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" -dependencies = [ - "cfg-if", - "crunchy", - "num-traits", - "zerocopy", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash 0.1.5", - "rayon", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash 0.2.0", -] - -[[package]] -name = "hashbrown" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - -[[package]] -name = "http" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "hybrid-array" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" -dependencies = [ - "typenum", -] - -[[package]] -name = "hyper" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown 0.17.0", - "rayon", - "serde", - "serde_core", -] - -[[package]] -name = "ipnet" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" - -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "jiff" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" -dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde_core", -] - -[[package]] -name = "jiff-static" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys 0.3.1", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" -dependencies = [ - "jni-sys 0.4.1", -] - -[[package]] -name = "jni-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" -dependencies = [ - "jni-sys-macros", -] - -[[package]] -name = "jni-sys-macros" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" -dependencies = [ - "cfg-if", - "futures-util", - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "khronos-egl" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" -dependencies = [ - "libc", - "libloading 0.8.9", - "pkg-config", -] - -[[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" - -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - -[[package]] -name = "libbz2-rs-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" - -[[package]] -name = "libc" -version = "0.2.184" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libloading" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - -[[package]] -name = "libredox" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" -dependencies = [ - "bitflags", - "libc", - "plain", - "redox_syscall 0.7.4", -] - -[[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "lzma-rust" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baab2bbbd7d75a144d671e9ff79270e903957d92fb7386fd39034c709bd2661" -dependencies = [ - "byteorder", -] - -[[package]] -name = "lzma-sys" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "matrixmultiply" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" -dependencies = [ - "autocfg", - "rawpointer", -] - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "naga" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2630921705b9b01dcdd0b6864b9562ca3c1951eecd0f0c4f5f04f61e412647" -dependencies = [ - "arrayvec", - "bit-set 0.9.1", - "bitflags", - "cfg-if", - "cfg_aliases", - "codespan-reporting", - "half", - "hashbrown 0.16.1", - "hexf-parse", - "indexmap", - "libm", - "log", - "num-traits", - "once_cell", - "rustc-hash 1.1.0", - "spirv", - "thiserror 2.0.18", - "unicode-ident", -] - -[[package]] -name = "nalgebra" -version = "0.34.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df76ea0ff5c7e6b88689085804d6132ded0ddb9de5ca5b8aeb9eeadc0508a70a" -dependencies = [ - "approx", - "glam 0.14.0", - "glam 0.15.2", - "glam 0.16.0", - "glam 0.17.3", - "glam 0.18.0", - "glam 0.19.0", - "glam 0.20.5", - "glam 0.21.3", - "glam 0.22.0", - "glam 0.23.0", - "glam 0.24.2", - "glam 0.25.0", - "glam 0.27.0", - "glam 0.28.0", - "glam 0.29.3", - "glam 0.30.10", - "glam 0.31.1", - "glam 0.32.1", - "matrixmultiply", - "nalgebra-macros", - "num-complex", - "num-rational", - "num-traits", - "simba", - "typenum", -] - -[[package]] -name = "nalgebra-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973e7178a678cfd059ccec50887658d482ce16b0aa9da3888ddeab5cd5eb4889" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ndarray" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits", - "portable-atomic", - "portable-atomic-util", - "rawpointer", - "rayon", -] - -[[package]] -name = "ndarray" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits", - "portable-atomic", - "portable-atomic-util", - "rawpointer", -] - -[[package]] -name = "ndk-sys" -version = "0.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys 0.3.1", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nt-time" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2de419e64947cd8830e66beb584acc3fb42ed411d103e3c794dda355d1b374b5" -dependencies = [ - "chrono", - "time", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "objc2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" -dependencies = [ - "objc2-encode", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" -dependencies = [ - "bitflags", - "dispatch2", - "objc2", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" -dependencies = [ - "bitflags", - "objc2", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-metal" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" -dependencies = [ - "bitflags", - "block2", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" -dependencies = [ - "bitflags", - "objc2", - "objc2-core-foundation", - "objc2-foundation", - "objc2-metal", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-float" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" -dependencies = [ - "num-traits", -] - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.18", - "smallvec", - "windows-link", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pecos-build" -version = "0.2.0-dev.0" -dependencies = [ - "bzip2", - "cargo_metadata", - "dirs", - "flate2", - "log", - "reqwest", - "serde", - "sevenz-rust", - "sha2 0.11.0", - "tar", - "thiserror 2.0.18", - "toml", - "toml_edit", - "xz2", - "zip", -] - -[[package]] -name = "pecos-core" -version = "0.2.0-dev.0" -dependencies = [ - "bitvec", - "num-complex", - "num-traits", - "pecos-random", - "rand 0.10.1", - "rand_core 0.10.0", - "smallvec", - "thiserror 2.0.18", -] - -[[package]] -name = "pecos-cuquantum" -version = "0.2.0-dev.0" -dependencies = [ - "env_logger", - "fastrand", - "log", - "pecos-build", - "pecos-core", - "pecos-cuquantum-sys", - "pecos-simulators", - "thiserror 2.0.18", -] - -[[package]] -name = "pecos-cuquantum-sys" -version = "0.2.0-dev.0" -dependencies = [ - "bindgen", - "dirs", - "env_logger", - "libc", - "libloading 0.9.0", - "log", - "pecos-build", - "thiserror 2.0.18", -] - -[[package]] -name = "pecos-gpu-sims" -version = "0.2.0-dev.0" -dependencies = [ - "bytemuck", - "log", - "num-complex", - "pecos-core", - "pecos-random", - "pecos-simulators", - "pollster", - "rand 0.10.1", - "rand_core 0.10.0", - "serde_json", - "wgpu", -] - -[[package]] -name = "pecos-num" -version = "0.2.0-dev.0" -dependencies = [ - "log", - "nalgebra", - "ndarray 0.17.2", - "num-complex", - "num-traits", - "pecos-random", - "rand 0.10.1", - "rustworkx-core", - "serde", - "serde_json", -] - -[[package]] -name = "pecos-quantum" -version = "0.2.0-dev.0" -dependencies = [ - "log", - "nalgebra", - "num-complex", - "pecos-core", - "pecos-num", - "pecos-random", - "serde_json", - "smallvec", -] - -[[package]] -name = "pecos-random" -version = "0.2.0-dev.0" -dependencies = [ - "rand 0.10.1", - "rand_core 0.10.0", - "rapidhash", - "wide 1.2.0", -] - -[[package]] -name = "pecos-simulators" -version = "0.2.0-dev.0" -dependencies = [ - "nalgebra", - "num-complex", - "pecos-core", - "pecos-quantum", - "pecos-random", - "rand 0.10.1", - "rayon", - "smallvec", - "wide 1.2.0", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "petgraph" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" -dependencies = [ - "fixedbitset", - "hashbrown 0.15.5", - "indexmap", - "serde", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - -[[package]] -name = "pollster" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" - -[[package]] -name = "portable-atomic" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" - -[[package]] -name = "portable-atomic-util" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "presser" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "priority-queue" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" -dependencies = [ - "equivalent", - "indexmap", - "serde", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "profiling" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" - -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.1.2", - "rustls", - "socket2", - "thiserror 2.0.18", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" -dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.3", - "ring", - "rustc-hash 2.1.2", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.18", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166" -dependencies = [ - "rand_chacha", - "rand_core 0.9.5", -] - -[[package]] -name = "rand" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" -dependencies = [ - "chacha20", - "getrandom 0.4.2", - "rand_core 0.10.0", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rand_core" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" - -[[package]] -name = "rand_distr" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" -dependencies = [ - "num-traits", - "rand 0.9.3", -] - -[[package]] -name = "rand_pcg" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b48ac3f7ffaab7fac4d2376632268aa5f89abdb55f7ebf8f4d11fffccb2320f7" -dependencies = [ - "rand_core 0.9.5", -] - -[[package]] -name = "range-alloc" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" - -[[package]] -name = "rapidhash" -version = "4.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" -dependencies = [ - "rand_core 0.9.5", - "rustversion", -] - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "raw-window-metal" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" -dependencies = [ - "objc2", - "objc2-core-foundation", - "objc2-foundation", - "objc2-quartz-core", -] - -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-cond" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964d0cf57a3e7a06e8183d14a8b527195c706b7983549cd5462d5aa3747438f" -dependencies = [ - "either", - "itertools 0.14.0", - "rayon", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_syscall" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" -dependencies = [ - "getrandom 0.2.17", - "libredox", - "thiserror 2.0.18", -] - -[[package]] -name = "regex" -version = "1.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" - -[[package]] -name = "renderdoc-sys" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" - -[[package]] -name = "reqwest" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "rustls-platform-verifier", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - -[[package]] -name = "rustix" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" -dependencies = [ - "aws-lc-rs", - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pki-types" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-platform-verifier" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" -dependencies = [ - "core-foundation", - "core-foundation-sys", - "jni", - "log", - "once_cell", - "rustls", - "rustls-native-certs", - "rustls-platform-verifier-android", - "rustls-webpki", - "security-framework", - "security-framework-sys", - "webpki-root-certs", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls-platform-verifier-android" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" - -[[package]] -name = "rustls-webpki" -version = "0.103.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "rustworkx-core" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaeee6f84153fd6f62507fc22bfe9499c8485075b44186dcbb918166ef75116f" -dependencies = [ - "fixedbitset", - "foldhash 0.1.5", - "hashbrown 0.15.5", - "indexmap", - "ndarray 0.16.1", - "num-traits", - "petgraph", - "priority-queue", - "rand 0.9.3", - "rand_distr", - "rand_pcg", - "rayon", - "rayon-cond", -] - -[[package]] -name = "safe_arch" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "safe_arch" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7caad094bd561859bcd467734a720c3c1f5d1f338995351fefe2190c45efed" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" -dependencies = [ - "serde", - "serde_core", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_spanned" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" -dependencies = [ - "serde_core", -] - -[[package]] -name = "sevenz-rust" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26482cf1ecce4540dc782fc70019eba89ffc4d87b3717eb5ec524b5db6fdefef" -dependencies = [ - "bit-set 0.6.0", - "byteorder", - "crc", - "filetime_creation", - "js-sys", - "lzma-rust", - "nt-time", - "sha2 0.10.9", - "wasm-bindgen", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.2", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "simba" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" -dependencies = [ - "approx", - "num-complex", - "num-traits", - "paste", - "wide 0.7.33", -] - -[[package]] -name = "simd-adler32" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "slotmap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "spirv" -version = "0.4.0+sdk-1.4.341.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tar" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" -dependencies = [ - "thiserror-impl 2.0.18", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" - -[[package]] -name = "time-macros" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "toml" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 1.0.1", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" - -[[package]] -name = "toml_datetime" -version = "1.1.1+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "toml_datetime 0.6.11", - "toml_write", - "winnow 0.7.15", -] - -[[package]] -name = "toml_parser" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" -dependencies = [ - "winnow 1.0.1", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "toml_writer" -version = "1.1.1+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" - -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - -[[package]] -name = "wayland-sys" -version = "0.31.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" -dependencies = [ - "dlib", - "log", - "once_cell", - "pkg-config", -] - -[[package]] -name = "web-sys" -version = "0.3.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-root-certs" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "wgpu" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c239a9a747bbd379590985bac952c2e53cb19873f7072b3370c6a6a8e06837" -dependencies = [ - "arrayvec", - "bitflags", - "bytemuck", - "cfg-if", - "cfg_aliases", - "document-features", - "hashbrown 0.16.1", - "js-sys", - "log", - "naga", - "parking_lot", - "portable-atomic", - "profiling", - "raw-window-handle", - "smallvec", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-core" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e80ac6cf1895df6342f87d975162108f9d98772a0d74bc404ab7304ac29469e" -dependencies = [ - "arrayvec", - "bit-set 0.9.1", - "bit-vec 0.9.1", - "bitflags", - "bytemuck", - "cfg_aliases", - "document-features", - "hashbrown 0.16.1", - "indexmap", - "log", - "naga", - "once_cell", - "parking_lot", - "portable-atomic", - "profiling", - "raw-window-handle", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 2.0.18", - "wgpu-core-deps-apple", - "wgpu-core-deps-emscripten", - "wgpu-core-deps-windows-linux-android", - "wgpu-hal", - "wgpu-naga-bridge", - "wgpu-types", -] - -[[package]] -name = "wgpu-core-deps-apple" -version = "29.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43acd053312501689cd92a01a9638d37f3e41a5fd9534875efa8917ee2d11ac0" -dependencies = [ - "wgpu-hal", -] - -[[package]] -name = "wgpu-core-deps-emscripten" -version = "29.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef043bf135cc68b6f667c55ff4e345ce2b5924d75bad36a47921b0287ca4b24a" -dependencies = [ - "wgpu-hal", -] - -[[package]] -name = "wgpu-core-deps-windows-linux-android" -version = "29.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725d5c006a8c02967b6d93ef04f6537ec4593313e330cfe86d9d3f946eb90f28" -dependencies = [ - "wgpu-hal", -] - -[[package]] -name = "wgpu-hal" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a47aef47636562f3937285af4c44b4b5b404b46577471411cc5313a921da7e" -dependencies = [ - "android_system_properties", - "arrayvec", - "ash", - "bit-set 0.9.1", - "bitflags", - "block2", - "bytemuck", - "cfg-if", - "cfg_aliases", - "glow", - "glutin_wgl_sys", - "gpu-allocator", - "gpu-descriptor", - "hashbrown 0.16.1", - "js-sys", - "khronos-egl", - "libc", - "libloading 0.8.9", - "log", - "naga", - "ndk-sys", - "objc2", - "objc2-core-foundation", - "objc2-foundation", - "objc2-metal", - "objc2-quartz-core", - "once_cell", - "ordered-float", - "parking_lot", - "portable-atomic", - "portable-atomic-util", - "profiling", - "range-alloc", - "raw-window-handle", - "raw-window-metal", - "renderdoc-sys", - "smallvec", - "thiserror 2.0.18", - "wasm-bindgen", - "wayland-sys", - "web-sys", - "wgpu-naga-bridge", - "wgpu-types", - "windows", - "windows-core", -] - -[[package]] -name = "wgpu-naga-bridge" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4684f4410da0cf95a4cb63bb5edaac022461dedb6adf0b64d0d9b5f6890d51" -dependencies = [ - "naga", - "wgpu-types", -] - -[[package]] -name = "wgpu-types" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2675540fb1a5cfa5ef122d3d5f390e2c75711a0b946410f2d6ac3a0f77d1f6" -dependencies = [ - "bitflags", - "bytemuck", - "js-sys", - "log", - "raw-window-handle", - "web-sys", -] - -[[package]] -name = "wide" -version = "0.7.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" -dependencies = [ - "bytemuck", - "safe_arch 0.7.4", -] - -[[package]] -name = "wide" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198f6abc41fab83526d10880fa5c17e2b4ee44e763949b4bb34e2fd1e8ca48e4" -dependencies = [ - "bytemuck", - "safe_arch 1.0.0", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "windows" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" -dependencies = [ - "windows-collections", - "windows-core", - "windows-future", - "windows-numerics", -] - -[[package]] -name = "windows-collections" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" -dependencies = [ - "windows-core", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-future" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" -dependencies = [ - "windows-core", - "windows-link", - "windows-threading", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-numerics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" -dependencies = [ - "windows-core", - "windows-link", -] - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows-threading" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - -[[package]] -name = "writeable" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xattr" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix", -] - -[[package]] -name = "xml-rs" -version = "0.8.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" - -[[package]] -name = "xz2" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" -dependencies = [ - "lzma-sys", -] - -[[package]] -name = "yoke" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zip" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" -dependencies = [ - "arbitrary", - "crc32fast", - "crossbeam-utils", - "displaydoc", - "flate2", - "indexmap", - "memchr", - "thiserror 2.0.18", - "zopfli", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" - -[[package]] -name = "zopfli" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" -dependencies = [ - "bumpalo", - "crc32fast", - "log", - "simd-adler32", -] From 7d34743f90fe768a2e986a1f3512614989f3e752 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 13:30:38 -0600 Subject: [PATCH 47/58] Add required paths-aware PR core-test gate (Linux Python + Rust) --- .github/workflows/pr-core-gate.yml | 155 +++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 .github/workflows/pr-core-gate.yml diff --git a/.github/workflows/pr-core-gate.yml b/.github/workflows/pr-core-gate.yml new file mode 100644 index 000000000..7f0f47e95 --- /dev/null +++ b/.github/workflows/pr-core-gate.yml @@ -0,0 +1,155 @@ +name: PR core gate + +# Required pre-merge sentinel: runs the Linux core Python + Rust test suites on +# pull requests. Has NO `paths:` filter so it always reports a status (a +# path-filtered required check would stuck-block PRs that don't touch its +# paths). When a PR changes nothing the core suites depend on, the detect step +# short-circuits to success so docs-only / unrelated-workflow PRs stay fast. + +permissions: + contents: read + +env: + LLVM_VERSION: "14.0.6" + RUSTFLAGS: -C debuginfo=0 + RUST_BACKTRACE: 1 + PYTHONUTF8: 1 + CARGO_HTTP_MULTIPLEXING: "false" + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + CARGO_NET_RETRY: "10" + +on: + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + pr-core: + runs-on: ubuntu-latest + # Python core build/test + Rust debug tests run serially here; a cold cache + # (LLVM + native builds) needs headroom. Measure a cold run before tightening. + timeout-minutes: 90 + steps: + - name: Harden the runner (egress audit) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + fetch-depth: 0 + persist-credentials: false + + # Safe-biased: run the core suites unless EVERY changed file is clearly + # unable to affect them. The markdown/text ignore is anchored to root-level + # files only ([^/]+) -- nested package READMEs are pyproject `readme=` + # build inputs (python/**/README.md, crate README.md) and MUST run. Any + # path not in the ignore set defaults to running. + - name: Detect core-relevant changes + id: detect + run: | + base='${{ github.event.pull_request.base.sha }}' + if [ -z "$base" ]; then + echo "No PR base (manual run); running the core gate." + echo "run=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + changed="$(git diff --name-only "$base"...HEAD)" + echo "Changed files:" + printf ' %s\n' $changed + ignore='^(docs/|\.github/ISSUE_TEMPLATE/|\.github/workflows/(julia-|go-|codeql)|[^/]+\.(md|rst|txt)$|LICENSE|CITATION)' + if printf '%s\n' "$changed" | grep -qvE "$ignore"; then + echo "run=true" >> "$GITHUB_OUTPUT" + echo "Core-relevant changes detected; running core suites." + else + echo "run=false" >> "$GITHUB_OUTPUT" + echo "Only non-core files changed; core gate passes without running suites." + fi + + # The setup below intentionally mirrors the Linux legs of python-test.yml + # (python-core) and rust-test.yml. Keep their action SHAs, uv/just/LLVM + # versions, and cache keys in sync when editing either side. + - name: Free Disk Space (Ubuntu) + if: steps.detect.outputs.run == 'true' + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + android: true + dotnet: true + haskell: true + large-packages: false + docker-images: true + tool-cache: false + swap-storage: true + + - name: Set up Python + if: steps.detect.outputs.run == 'true' + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.12" + + - name: Install the latest version of uv + if: steps.detect.outputs.run == 'true' + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + enable-cache: true + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + + - name: Set up Rust + if: steps.detect.outputs.run == 'true' + run: | + bash scripts/ci/ensure-rust.sh stable minimal + export PATH="$HOME/.cargo/bin:$PATH" + rustup show + + - name: Verify cmake is available (MWPF decoder build) + if: steps.detect.outputs.run == 'true' + run: cmake --version + + - name: Install just + if: steps.detect.outputs.run == 'true' + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Cache Rust + if: steps.detect.outputs.run == 'true' + uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + with: + cache-bin: false + prefix-key: v1-rust-no-bin + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + workspaces: | + python/pecos-rslib + python/pecos-rslib-llvm + + - name: Cache LLVM ${{ env.LLVM_VERSION }} + if: steps.detect.outputs.run == 'true' + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + if: steps.detect.outputs.run == 'true' + run: just ci-env + + - name: Run core Python tests + if: steps.detect.outputs.run == 'true' + run: just python-ci-core + + - name: Run core Rust tests + if: steps.detect.outputs.run == 'true' + # debug profile keeps this sentinel fast; the full release matrix runs + # post-merge on push via rust-test.yml. + run: just rstest debug + + - name: Core gate passed (no core-relevant changes) + if: steps.detect.outputs.run != 'true' + run: echo "No core-relevant paths changed; core suites skipped." From fbecd10145593a16a5f4a237361305f4b27da346 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 15:59:07 -0600 Subject: [PATCH 48/58] Narrow pr-core detect ignore to provably-safe paths so docs fixtures and sources run --- .github/workflows/pr-core-gate.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr-core-gate.yml b/.github/workflows/pr-core-gate.yml index 7f0f47e95..8e92db9f1 100644 --- a/.github/workflows/pr-core-gate.yml +++ b/.github/workflows/pr-core-gate.yml @@ -47,11 +47,16 @@ jobs: fetch-depth: 0 persist-credentials: false - # Safe-biased: run the core suites unless EVERY changed file is clearly - # unable to affect them. The markdown/text ignore is anchored to root-level - # files only ([^/]+) -- nested package READMEs are pyproject `readme=` - # build inputs (python/**/README.md, crate README.md) and MUST run. Any - # path not in the ignore set defaults to running. + # Run the core suites unless EVERY changed file is on a short allowlist of + # paths that PROVABLY cannot affect python-ci-core or `pecos rust test`: + # - other-language CI workflows (julia/go/codeql) and issue templates + # - root-level prose files only ([^/]+\.md|rst|txt, LICENSE, CITATION); + # root README/CHANGELOG are NOT pyproject `readme=` inputs (verified). + # Notably docs/ is NOT ignored: docs/assets/** holds test fixtures (e.g. + # docs/assets/test-data/math.wat) and docs/*.md sources generated tests + # under python/quantum-pecos/tests/docs/generated/, both collected by the + # non-slow core selection. Nested package READMEs (python/**/README.md) are + # also build inputs and run. Anything not on the allowlist runs. - name: Detect core-relevant changes id: detect run: | @@ -64,7 +69,7 @@ jobs: changed="$(git diff --name-only "$base"...HEAD)" echo "Changed files:" printf ' %s\n' $changed - ignore='^(docs/|\.github/ISSUE_TEMPLATE/|\.github/workflows/(julia-|go-|codeql)|[^/]+\.(md|rst|txt)$|LICENSE|CITATION)' + ignore='^(\.github/ISSUE_TEMPLATE/|\.github/workflows/(julia-|go-|codeql)|[^/]+\.(md|rst|txt)$|LICENSE|CITATION)' if printf '%s\n' "$changed" | grep -qvE "$ignore"; then echo "run=true" >> "$GITHUB_OUTPUT" echo "Core-relevant changes detected; running core suites." From 791878bac288e7c9e1755cfbcbf5c9647f013b09 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 16:04:06 -0600 Subject: [PATCH 49/58] Split pr-core gate into parallel pr-core-python and pr-core-rust jobs with a shared detect script --- .github/workflows/pr-core-gate.yml | 148 ++++++++++++++++++++--------- scripts/ci/pr-core-changed.sh | 39 ++++++++ 2 files changed, 144 insertions(+), 43 deletions(-) create mode 100755 scripts/ci/pr-core-changed.sh diff --git a/.github/workflows/pr-core-gate.yml b/.github/workflows/pr-core-gate.yml index 8e92db9f1..7ecd57e6c 100644 --- a/.github/workflows/pr-core-gate.yml +++ b/.github/workflows/pr-core-gate.yml @@ -1,10 +1,18 @@ name: PR core gate -# Required pre-merge sentinel: runs the Linux core Python + Rust test suites on -# pull requests. Has NO `paths:` filter so it always reports a status (a -# path-filtered required check would stuck-block PRs that don't touch its -# paths). When a PR changes nothing the core suites depend on, the detect step -# short-circuits to success so docs-only / unrelated-workflow PRs stay fast. +# Required pre-merge sentinels: run the Linux core Python and Rust test suites +# on pull requests, in parallel. Neither has a `paths:` filter, so each always +# reports a status (a path-filtered required check would stuck-block PRs that +# don't touch its paths). A shared detect script short-circuits to a pass when a +# PR changes nothing the core suites depend on, so docs-only / unrelated PRs +# stay fast. +# +# Required contexts: pr-core-python, pr-core-rust. +# +# The setup below mirrors the Linux legs of python-test.yml (python-core) and +# rust-test.yml. Keep their action SHAs, uv/just/LLVM versions, and cache keys +# in sync when editing either side. The change-detection rule lives in +# scripts/ci/pr-core-changed.sh (single source of truth for both jobs). permissions: contents: read @@ -31,11 +39,9 @@ defaults: shell: bash jobs: - pr-core: + pr-core-python: runs-on: ubuntu-latest - # Python core build/test + Rust debug tests run serially here; a cold cache - # (LLVM + native builds) needs headroom. Measure a cold run before tightening. - timeout-minutes: 90 + timeout-minutes: 45 steps: - name: Harden the runner (egress audit) uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 @@ -47,40 +53,10 @@ jobs: fetch-depth: 0 persist-credentials: false - # Run the core suites unless EVERY changed file is on a short allowlist of - # paths that PROVABLY cannot affect python-ci-core or `pecos rust test`: - # - other-language CI workflows (julia/go/codeql) and issue templates - # - root-level prose files only ([^/]+\.md|rst|txt, LICENSE, CITATION); - # root README/CHANGELOG are NOT pyproject `readme=` inputs (verified). - # Notably docs/ is NOT ignored: docs/assets/** holds test fixtures (e.g. - # docs/assets/test-data/math.wat) and docs/*.md sources generated tests - # under python/quantum-pecos/tests/docs/generated/, both collected by the - # non-slow core selection. Nested package READMEs (python/**/README.md) are - # also build inputs and run. Anything not on the allowlist runs. - name: Detect core-relevant changes id: detect - run: | - base='${{ github.event.pull_request.base.sha }}' - if [ -z "$base" ]; then - echo "No PR base (manual run); running the core gate." - echo "run=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - changed="$(git diff --name-only "$base"...HEAD)" - echo "Changed files:" - printf ' %s\n' $changed - ignore='^(\.github/ISSUE_TEMPLATE/|\.github/workflows/(julia-|go-|codeql)|[^/]+\.(md|rst|txt)$|LICENSE|CITATION)' - if printf '%s\n' "$changed" | grep -qvE "$ignore"; then - echo "run=true" >> "$GITHUB_OUTPUT" - echo "Core-relevant changes detected; running core suites." - else - echo "run=false" >> "$GITHUB_OUTPUT" - echo "Only non-core files changed; core gate passes without running suites." - fi - - # The setup below intentionally mirrors the Linux legs of python-test.yml - # (python-core) and rust-test.yml. Keep their action SHAs, uv/just/LLVM - # versions, and cache keys in sync when editing either side. + run: echo "run=$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" >> "$GITHUB_OUTPUT" + - name: Free Disk Space (Ubuntu) if: steps.detect.outputs.run == 'true' uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 @@ -149,12 +125,98 @@ jobs: if: steps.detect.outputs.run == 'true' run: just python-ci-core + - name: Core Python gate passed (no core-relevant changes) + if: steps.detect.outputs.run != 'true' + run: echo "No core-relevant paths changed; core Python suite skipped." + + pr-core-rust: + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - name: Harden the runner (egress audit) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Detect core-relevant changes + id: detect + run: echo "run=$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" >> "$GITHUB_OUTPUT" + + - name: Free Disk Space (Ubuntu) + if: steps.detect.outputs.run == 'true' + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + android: true + dotnet: true + haskell: true + large-packages: false + docker-images: true + tool-cache: false + swap-storage: true + + - name: Set up Python + if: steps.detect.outputs.run == 'true' + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.12" + + - name: Install the latest version of uv + if: steps.detect.outputs.run == 'true' + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7 + with: + version: "0.11.14" + enable-cache: true + save-cache: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + + - name: Set up Rust + if: steps.detect.outputs.run == 'true' + run: | + bash scripts/ci/ensure-rust.sh stable minimal + export PATH="$HOME/.cargo/bin:$PATH" + rustup show + + - name: Verify cmake is available (MWPF decoder build) + if: steps.detect.outputs.run == 'true' + run: cmake --version + + - name: Install just + if: steps.detect.outputs.run == 'true' + uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Cache Rust + if: steps.detect.outputs.run == 'true' + uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + with: + cache-bin: false + prefix-key: v1-rust-no-bin + save-if: ${{ github.event_name == 'push' && contains(fromJSON('["main", "master", "development", "dev"]'), github.ref_name) }} + workspaces: | + python/pecos-rslib + python/pecos-rslib-llvm + + - name: Cache LLVM ${{ env.LLVM_VERSION }} + if: steps.detect.outputs.run == 'true' + id: cache-llvm + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.pecos/deps/llvm-14 + key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2 + + - name: Ensure LLVM ${{ env.LLVM_VERSION }} + if: steps.detect.outputs.run == 'true' + run: just ci-env + - name: Run core Rust tests if: steps.detect.outputs.run == 'true' # debug profile keeps this sentinel fast; the full release matrix runs # post-merge on push via rust-test.yml. run: just rstest debug - - name: Core gate passed (no core-relevant changes) + - name: Core Rust gate passed (no core-relevant changes) if: steps.detect.outputs.run != 'true' - run: echo "No core-relevant paths changed; core suites skipped." + run: echo "No core-relevant paths changed; core Rust suite skipped." diff --git a/scripts/ci/pr-core-changed.sh b/scripts/ci/pr-core-changed.sh new file mode 100755 index 000000000..78b76b619 --- /dev/null +++ b/scripts/ci/pr-core-changed.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# Decide whether a pull request's changes can affect the core Python/Rust test +# suites the pr-core gate runs (`just python-ci-core` / `just rstest`). Prints +# "true" or "false" on stdout; all diagnostics go to stderr. Requires a +# full-history checkout (fetch-depth: 0). +# +# Usage: scripts/ci/pr-core-changed.sh +set -euo pipefail + +base="${1:-}" +if [ -z "$base" ]; then + echo "No PR base provided (e.g. manual run); running the core gate." >&2 + echo "true" + exit 0 +fi + +changed="$(git diff --name-only "$base"...HEAD)" +{ + echo "Changed files:" + printf ' %s\n' $changed +} >&2 + +# Allowlist of paths that PROVABLY cannot affect python-ci-core or +# `pecos rust test`: +# - other-language CI workflows (julia/go/codeql) and issue templates +# - root-level prose only ([^/]+); root README/CHANGELOG are not pyproject +# `readme=` inputs (verified). +# docs/ is intentionally NOT ignored: docs/assets/** holds test fixtures (e.g. +# docs/assets/test-data/math.wat) and docs/*.md sources generated tests under +# python/quantum-pecos/tests/docs/, both collected by the non-slow core +# selection. Nested package READMEs (python/**/README.md) are also build inputs +# and run. Anything not on the allowlist runs. +ignore='^(\.github/ISSUE_TEMPLATE/|\.github/workflows/(julia-|go-|codeql)|[^/]+\.(md|rst|txt)$|LICENSE|CITATION)' + +if printf '%s\n' "$changed" | grep -qvE "$ignore"; then + echo "true" +else + echo "false" +fi From 7bc72e710a05991c076c2c3af235b103112e1f90 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 17:45:46 -0600 Subject: [PATCH 50/58] Bump pyo3 to 0.29 to resolve RUSTSEC-2026-0176/0177 advisories --- Cargo.lock | 31 ++++++++++--------------------- Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ffffaffbf..599318beb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5003,9 +5003,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.28.3" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12" +checksum = "cd274650b21d4bfc26a0a47587962c1edb425f69287324355cd040c3ea66071c" dependencies = [ "libc", "num-complex 0.4.6", @@ -5018,19 +5018,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.28.3" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e" +checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078" dependencies = [ - "python3-dll-a", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.28.3" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e" +checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b" dependencies = [ "libc", "pyo3-build-config", @@ -5038,9 +5037,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.28.3" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813" +checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -5050,26 +5049,16 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.28.3" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb" +checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362" dependencies = [ "heck 0.5.0", "proc-macro2", - "pyo3-build-config", "quote", "syn 2.0.117", ] -[[package]] -name = "python3-dll-a" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d80ba7540edb18890d444c5aa8e1f1f99b1bdf26fb26ae383135325f4a36042b" -dependencies = [ - "cc", -] - [[package]] name = "quick-error" version = "1.2.3" diff --git a/Cargo.toml b/Cargo.toml index 1e2c2a3b7..3001bac72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ cargo_metadata = "0.23" # at build time, which is what we want when maturin builds the cdylib but is # fatal for plain `cargo test`. Each pecos-rslib* crate gates them behind its # own `extension-module` feature; maturin opts in via pyproject.toml. -pyo3 = "0.28" +pyo3 = "0.29" # --- C/C++ FFI & build --- bindgen = "0.72" From 1d1a711f20263e974bfbcae2f2440f6ceb0f4a01 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 19:21:33 -0600 Subject: [PATCH 51/58] Stop cargo-deny/dependabot watching the untracked native bench crate --- .github/dependabot.yml | 19 ++++--------------- .github/workflows/cargo-deny.yml | 7 +++++-- .github/workflows/dependency-review.yml | 2 -- Justfile | 9 ++------- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 09df212d2..6b7d4be7e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,21 +19,10 @@ updates: - dependency-name: "*" update-types: ["version-update:semver-patch", "version-update:semver-minor", "version-update:semver-major"] - # Rust (Cargo) - native benchmark security updates only - - package-ecosystem: "cargo" - directory: "/scripts/native_bench/bench_pecos" - schedule: - interval: "weekly" - open-pull-requests-limit: 5 - groups: - native-bench-rust-security: - applies-to: security-updates - patterns: ["*"] - allow: - - dependency-type: "all" - ignore: - - dependency-name: "*" - update-types: ["version-update:semver-patch", "version-update:semver-minor", "version-update:semver-major"] + # Note: scripts/native_bench/bench_pecos is intentionally NOT watched here. It + # is a dev-only benchmark (publish = false) whose Cargo.lock is untracked + # (.gitignore), so it is not in the dependency graph. Tracking it would + # reintroduce per-directory security PRs that cannot be suppressed. # Python (pip) - security updates only - package-ecosystem: "pip" diff --git a/.github/workflows/cargo-deny.yml b/.github/workflows/cargo-deny.yml index f2277d17d..7b589c3fe 100644 --- a/.github/workflows/cargo-deny.yml +++ b/.github/workflows/cargo-deny.yml @@ -50,5 +50,8 @@ jobs: - name: Check root Rust workspace run: cargo deny --locked --all-features check advisories bans sources - - name: Check native benchmark crate - run: cargo deny --manifest-path scripts/native_bench/bench_pecos/Cargo.toml --locked --all-features check advisories bans sources + # No separate check for scripts/native_bench/bench_pecos: that crate is a + # dev-only benchmark (publish = false) whose Cargo.lock is intentionally + # untracked (.gitignore), so it is neither pinned here nor watched by + # Dependabot. Re-add a tracked lock + a --locked check here if it ever + # gains shipped or CI-executed status. diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index c6db9b723..338240030 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -6,8 +6,6 @@ on: paths: - 'Cargo.toml' - 'Cargo.lock' - - 'scripts/native_bench/bench_pecos/Cargo.toml' - - 'scripts/native_bench/bench_pecos/Cargo.lock' - 'pyproject.toml' - 'python/**/pyproject.toml' - 'uv.lock' diff --git a/Justfile b/Justfile index bd3343447..32f0ff781 100644 --- a/Justfile +++ b/Justfile @@ -163,20 +163,15 @@ dependency-integrity-check: [group('security')] security-check: dependency-integrity-check cargo-deny -# Run cargo-deny against every Rust lockfile covered by CI +# Run cargo-deny against the root Rust workspace (the only tracked lockfile) [group('security')] -cargo-deny: cargo-deny-workspace cargo-deny-native-bench +cargo-deny: cargo-deny-workspace # Check the root Rust workspace with cargo-deny [group('security')] cargo-deny-workspace: cargo deny --locked --all-features check advisories bans sources -# Check the standalone native benchmark crate with cargo-deny -[group('security')] -cargo-deny-native-bench: - cargo deny --manifest-path scripts/native_bench/bench_pecos/Cargo.toml --locked --all-features check advisories bans sources - # List installed and cached dependencies [group('setup')] list-deps: _msvc-bootstrap From ed102c19a846b604ae40f00ebd6d2abf07bd718b Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 19:21:37 -0600 Subject: [PATCH 52/58] Fix pr-core detect fail-open and anchor LICENSE/CITATION ignore --- .github/workflows/pr-core-gate.yml | 28 ++++++++++++++++++++++++++-- scripts/ci/pr-core-changed.sh | 2 +- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-core-gate.yml b/.github/workflows/pr-core-gate.yml index 7ecd57e6c..e14aad5e1 100644 --- a/.github/workflows/pr-core-gate.yml +++ b/.github/workflows/pr-core-gate.yml @@ -55,7 +55,19 @@ jobs: - name: Detect core-relevant changes id: detect - run: echo "run=$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" >> "$GITHUB_OUTPUT" + # Assign on its own line so a git failure in the detect script aborts the + # step under `set -e` (fail closed) instead of writing an empty `run=`, + # which would let this required gate pass green having run no tests. + run: | + run="$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" + case "$run" in + true|false) ;; + *) + echo "unexpected pr-core detect output: <$run>" >&2 + exit 1 + ;; + esac + printf 'run=%s\n' "$run" >> "$GITHUB_OUTPUT" - name: Free Disk Space (Ubuntu) if: steps.detect.outputs.run == 'true' @@ -145,7 +157,19 @@ jobs: - name: Detect core-relevant changes id: detect - run: echo "run=$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" >> "$GITHUB_OUTPUT" + # Assign on its own line so a git failure in the detect script aborts the + # step under `set -e` (fail closed) instead of writing an empty `run=`, + # which would let this required gate pass green having run no tests. + run: | + run="$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" + case "$run" in + true|false) ;; + *) + echo "unexpected pr-core detect output: <$run>" >&2 + exit 1 + ;; + esac + printf 'run=%s\n' "$run" >> "$GITHUB_OUTPUT" - name: Free Disk Space (Ubuntu) if: steps.detect.outputs.run == 'true' diff --git a/scripts/ci/pr-core-changed.sh b/scripts/ci/pr-core-changed.sh index 78b76b619..9a4aa6846 100755 --- a/scripts/ci/pr-core-changed.sh +++ b/scripts/ci/pr-core-changed.sh @@ -30,7 +30,7 @@ changed="$(git diff --name-only "$base"...HEAD)" # python/quantum-pecos/tests/docs/, both collected by the non-slow core # selection. Nested package READMEs (python/**/README.md) are also build inputs # and run. Anything not on the allowlist runs. -ignore='^(\.github/ISSUE_TEMPLATE/|\.github/workflows/(julia-|go-|codeql)|[^/]+\.(md|rst|txt)$|LICENSE|CITATION)' +ignore='^(\.github/ISSUE_TEMPLATE/|\.github/workflows/(julia-|go-|codeql)|[^/]+\.(md|rst|txt)$|LICENSE$|CITATION(\.cff)?$)' if printf '%s\n' "$changed" | grep -qvE "$ignore"; then echo "true" From 4b10002754926600e6266ee4926ab2d028dff81e Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 21:28:07 -0600 Subject: [PATCH 53/58] Bump quinn-proto to 0.11.15 to resolve RUSTSEC-2026-0185 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 599318beb..6b9288771 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5087,9 +5087,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" dependencies = [ "aws-lc-rs", "bytes", From 24b74cf78ab9a267c9681503d528bd68d6a0a473 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 22:26:54 -0600 Subject: [PATCH 54/58] Remove dead TRIGGER_ON_PR_PUSH env and correct pr-core required-context comments --- .github/workflows/pr-core-gate.yml | 15 ++++++++------- .github/workflows/python-test.yml | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pr-core-gate.yml b/.github/workflows/pr-core-gate.yml index e14aad5e1..e7e7a044a 100644 --- a/.github/workflows/pr-core-gate.yml +++ b/.github/workflows/pr-core-gate.yml @@ -1,13 +1,14 @@ name: PR core gate -# Required pre-merge sentinels: run the Linux core Python and Rust test suites -# on pull requests, in parallel. Neither has a `paths:` filter, so each always -# reports a status (a path-filtered required check would stuck-block PRs that -# don't touch its paths). A shared detect script short-circuits to a pass when a -# PR changes nothing the core suites depend on, so docs-only / unrelated PRs -# stay fast. +# Pre-merge test sentinels (intended to become the required contexts +# pr-core-python / pr-core-rust once promoted in branch protection -- NOT yet +# required): run the Linux core Python and Rust test suites on pull requests, in +# parallel. Neither has a `paths:` filter, so each always reports a status (a +# path-filtered required check would stuck-block PRs that don't touch its paths). +# A shared detect script short-circuits to a pass when a PR changes nothing the +# core suites depend on, so docs-only / unrelated PRs stay fast. # -# Required contexts: pr-core-python, pr-core-rust. +# Intended required contexts (not yet enforced): pr-core-python, pr-core-rust. # # The setup below mirrors the Linux legs of python-test.yml (python-core) and # rust-test.yml. Keep their action SHAs, uv/just/LLVM versions, and cache keys diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 11b717ccb..2dbe2d889 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -4,7 +4,6 @@ permissions: contents: read env: - TRIGGER_ON_PR_PUSH: true RUSTFLAGS: -C debuginfo=0 RUST_BACKTRACE: 1 PYTHONUTF8: 1 From 62c8661dec97705ae0a34de0944d30b63664a891 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 22:55:25 -0600 Subject: [PATCH 55/58] Fail release artifact uploads on missing files; fix pr-core comment overclaim --- .github/workflows/pr-core-gate.yml | 4 ++-- .github/workflows/python-release.yml | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-core-gate.yml b/.github/workflows/pr-core-gate.yml index e7e7a044a..fd93d6d26 100644 --- a/.github/workflows/pr-core-gate.yml +++ b/.github/workflows/pr-core-gate.yml @@ -58,7 +58,7 @@ jobs: id: detect # Assign on its own line so a git failure in the detect script aborts the # step under `set -e` (fail closed) instead of writing an empty `run=`, - # which would let this required gate pass green having run no tests. + # which would let this gate pass green having run no tests. run: | run="$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" case "$run" in @@ -160,7 +160,7 @@ jobs: id: detect # Assign on its own line so a git failure in the detect script aborts the # step under `set -e` (fail closed) instead of writing an empty `run=`, - # which would let this required gate pass green having run no tests. + # which would let this gate pass green having run no tests. run: | run="$(bash scripts/ci/pr-core-changed.sh '${{ github.event.pull_request.base.sha }}')" case "$run" in diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 355b33284..1f031495e 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -193,6 +193,7 @@ jobs: dist/pecos-rslib/*.whl dist/pecos-rslib-llvm/*.whl dist/quantum-pecos/*.whl + if-no-files-found: error pr_smoke_test: needs: [resolve_release_mode, pr_smoke_build] @@ -455,6 +456,7 @@ jobs: with: name: wheel-pecos-rslib-${{ matrix.os }}-${{ matrix.architecture }} path: ./wheelhouse/*.whl + if-no-files-found: error # Build pecos-rslib-llvm wheel (reuses LLVM already installed by pecos-rslib build) - name: Build pecos-rslib-llvm wheels @@ -519,6 +521,7 @@ jobs: with: name: wheel-pecos-rslib-llvm-${{ matrix.os }}-${{ matrix.architecture }} path: ./wheelhouse-llvm/*.whl + if-no-files-found: error test_abi3_wheels: needs: build_wheelspecos_rslib @@ -663,6 +666,7 @@ jobs: with: name: sdist-quantum-pecos path: python/quantum-pecos/dist/*.tar.gz + if-no-files-found: error build_wheels_quantum_pecos: needs: build_wheelspecos_rslib @@ -722,6 +726,7 @@ jobs: with: name: wheel-quantum-pecos path: python/quantum-pecos/dist/*.whl + if-no-files-found: error collect_artifacts: needs: [build_wheelspecos_rslib, build_sdist_quantum_pecos, build_wheels_quantum_pecos, test_abi3_wheels] From 5db98980b9fb8db0d346735bba489fbe0cc2af78 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 23:28:42 -0600 Subject: [PATCH 56/58] Fail all remaining release artifact uploads on missing files (julia, selene, python collector output) --- .github/workflows/julia-release.yml | 3 +++ .github/workflows/python-release.yml | 1 + .github/workflows/selene-plugins.yml | 2 ++ 3 files changed, 6 insertions(+) diff --git a/.github/workflows/julia-release.yml b/.github/workflows/julia-release.yml index 802636ffe..21e544c23 100644 --- a/.github/workflows/julia-release.yml +++ b/.github/workflows/julia-release.yml @@ -270,6 +270,7 @@ jobs: with: name: julia-binary-${{ matrix.os }}-${{ matrix.architecture }} path: pecos_julia-*.tar.gz + if-no-files-found: error test_binaries: needs: build_julia_binaries @@ -506,6 +507,7 @@ jobs: with: name: pecos-julia-distribution path: dist/ + if-no-files-found: error create_release_bundle: needs: [build_julia_binaries, test_binaries] @@ -664,6 +666,7 @@ jobs: with: name: pecos-julia-release-bundle path: pecos-julia-release-bundle-*.tar.gz + if-no-files-found: error retention-days: 30 # Keep for 30 days - name: Determine if pre-release diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 1f031495e..e5fe19535 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -853,3 +853,4 @@ jobs: with: name: pecos-distribution path: dist/ + if-no-files-found: error diff --git a/.github/workflows/selene-plugins.yml b/.github/workflows/selene-plugins.yml index 3c3a902c2..d39ae88d5 100644 --- a/.github/workflows/selene-plugins.yml +++ b/.github/workflows/selene-plugins.yml @@ -223,6 +223,7 @@ jobs: with: name: wheel-${{ matrix.plugin.name }}-${{ matrix.os }} path: python/selene-plugins/${{ matrix.plugin.name }}/dist/*.whl + if-no-files-found: error # Collect all wheels into a single artifact collect-wheels: @@ -254,3 +255,4 @@ jobs: with: name: selene-plugin-wheels path: wheels/*.whl + if-no-files-found: error From 42f7610f56d5c298b4067b203b08574a6173bfd7 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sat, 27 Jun 2026 23:36:16 -0600 Subject: [PATCH 57/58] Bump tar to 0.4.46 and Go toolchain to 1.26.4 to clear stdlib/dependency advisories --- Cargo.lock | 4 ++-- go/pecos/go.mod | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b9288771..35b698e71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6467,9 +6467,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.45" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", diff --git a/go/pecos/go.mod b/go/pecos/go.mod index 8a912d4d5..5e83b19bb 100644 --- a/go/pecos/go.mod +++ b/go/pecos/go.mod @@ -1,3 +1,3 @@ module github.com/PECOS-packages/PECOS/go/pecos -go 1.26.3 +go 1.26.4 From 866eaf1f97ea94330a0d1e2f9b6961f04fc66e67 Mon Sep 17 00:00:00 2001 From: Ciaran Ryan-Anderson Date: Sun, 28 Jun 2026 00:07:50 -0600 Subject: [PATCH 58/58] Bump examples jupyter chain and ignore structopt RUSTSEC-2022-0104 to clear OSV reds --- osv-scanner.toml | 7 +++++ uv.lock | 67 +++++++++++++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/osv-scanner.toml b/osv-scanner.toml index 1787157a3..0a2685200 100644 --- a/osv-scanner.toml +++ b/osv-scanner.toml @@ -65,3 +65,10 @@ id = "RUSTSEC-2021-0139" # Chain: mwpf -> slp -> structopt 0.3 -> clap 2.34. # Upstream owner: https://github.com/yuewuo/mwpf. reason = "Transitive via mwpf -> slp -> clap2; unmaintained-crate warning, terminal-color path unused." + +[[IgnoredVulns]] +id = "RUSTSEC-2022-0104" +# structopt@0.3.26 -- maintenance mode. +# Chain: pecos-mwpf -> mwpf -> slp -> structopt 0.3. +# Upstream owner: https://github.com/yuewuo/mwpf. +reason = "Transitive via mwpf -> slp -> structopt; maintenance-mode warning for upstream CLI parser, no direct PECOS use." diff --git a/uv.lock b/uv.lock index a8a4f2929..103435b89 100644 --- a/uv.lock +++ b/uv.lock @@ -239,14 +239,14 @@ wheels = [ [[package]] name = "bleach" -version = "6.3.0" +version = "6.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/07/18/3c8523962314be6bf4c8989c79ad9531c825210dd13a8669f6b84336e8bd/bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22", size = 203533, upload-time = "2025-10-27T17:57:39.211Z" } +sdist = { url = "https://files.pythonhosted.org/packages/48/3c/e12ac860709702bd5ebeb9b56a4fe334f1001246ee1b8f2b7ee28912df7d/bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452", size = 204857, upload-time = "2026-06-05T13:01:13.734Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6", size = 164437, upload-time = "2025-10-27T17:57:37.538Z" }, + { url = "https://files.pythonhosted.org/packages/58/9d/40b6267367182187139a4000b82a3b287d84d745bccd808e75d916920e9d/bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081", size = 165109, upload-time = "2026-06-05T13:01:12.504Z" }, ] [package.optional-dependencies] @@ -1675,6 +1675,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657, upload-time = "2024-08-30T07:15:47.045Z" }, ] +[[package]] +name = "jupyter-builder" +version = "1.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'extra-13-quantum-pecos-cuda12' and extra == 'extra-13-quantum-pecos-cuda13') or (extra == 'extra-15-pecos-workspace-cuda12' and extra == 'extra-15-pecos-workspace-cuda13') or (extra == 'group-15-pecos-workspace-cuda12' and extra == 'group-15-pecos-workspace-cuda13')" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/45/d0df8b43c10a61529c0f4a8af5e19ebe108f0c3af8f57e0fc358969907af/jupyter_builder-1.0.2.tar.gz", hash = "sha256:6155d78a5325010532a6419ffcba89eac643fd1aa56ea83115e661924d6f6aab", size = 968638, upload-time = "2026-06-12T02:33:25.767Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/b6/c418e0b3256f67c04933566b80bfce947350682db92c4b786a8653db32d6/jupyter_builder-1.0.2-py3-none-any.whl", hash = "sha256:b024f65d36e1d530542db597b00dd513261aa59842e0d0fbbb1015a9f1935e9c", size = 910789, upload-time = "2026-06-12T02:33:23.317Z" }, +] + [[package]] name = "jupyter-client" version = "8.8.0" @@ -1757,7 +1771,7 @@ wheels = [ [[package]] name = "jupyter-server" -version = "2.18.2" +version = "2.20.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1780,9 +1794,9 @@ dependencies = [ { name = "traitlets" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/15/1eacb0fcb79ef86e8a0a79a708e6ad7435f6f223097dd29a4ce861fabc44/jupyter_server-2.18.2.tar.gz", hash = "sha256:06b4f40d8a7a00bb39d5216859c81374a0e7cfefe6d8a5a7facc5a5c37c679a7", size = 753177, upload-time = "2026-05-06T07:04:36.274Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/dc/db3a582633170186f8c8b31298d7eb26ad0eb031a1f53476c258b64eed05/jupyter_server-2.20.0.tar.gz", hash = "sha256:b5778ba337d8015a3dc2b80803ecdd5ac18d3797fddf61a50ea5fb472b4ebe14", size = 756523, upload-time = "2026-06-17T12:09:09.435Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/50/ecf4f70d65bdb7519b28a33d1b2fee8a4b4ba1ae1a92f15d97e877c5de21/jupyter_server-2.18.2-py3-none-any.whl", hash = "sha256:fa5e46539ded65791838035a2b6001f13e54d5f64b8b3752eb1e91fdd641a5b8", size = 391907, upload-time = "2026-05-06T07:04:34.014Z" }, + { url = "https://files.pythonhosted.org/packages/f3/71/8c002223e873a870f5c41dc69b0a7c922301123e4a31d5d01ecb700aef77/jupyter_server-2.20.0-py3-none-any.whl", hash = "sha256:c3b67c93c471e947c18b5026f04f21614218adb706df8f48227d3ee8e0a7cdcc", size = 393143, upload-time = "2026-06-17T12:09:07.234Z" }, ] [[package]] @@ -1800,27 +1814,27 @@ wheels = [ [[package]] name = "jupyterlab" -version = "4.5.7" +version = "4.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, { name = "httpx" }, { name = "ipykernel" }, { name = "jinja2" }, + { name = "jupyter-builder" }, { name = "jupyter-core" }, { name = "jupyter-lsp" }, { name = "jupyter-server" }, { name = "jupyterlab-server" }, { name = "notebook-shim" }, { name = "packaging" }, - { name = "setuptools" }, { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'extra-13-quantum-pecos-cuda12' and extra == 'extra-13-quantum-pecos-cuda13') or (extra == 'extra-15-pecos-workspace-cuda12' and extra == 'extra-15-pecos-workspace-cuda13') or (extra == 'group-15-pecos-workspace-cuda12' and extra == 'group-15-pecos-workspace-cuda13')" }, { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2b/22/8440ec827762146e7cdecf04335bd348795899d29dc6ae82238707353a2c/jupyterlab-4.5.7.tar.gz", hash = "sha256:55a9822c4754da305f41e113452c68383e214dcf96de760146af89ce5d5117b0", size = 23992763, upload-time = "2026-04-29T16:43:51.328Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/3c/1ebd737b860cdbe61eed71536d06aab4e1781fbdcf07ecd5a1afe05b8adf/jupyterlab-4.6.0.tar.gz", hash = "sha256:6a8b88f2aae7ed4d012c634fc957c1a27f3aa217c32f0ced0175fac9ee17f9e5", size = 28181861, upload-time = "2026-06-18T13:52:56.039Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/aa/537b8f7d80e799af19af35fb3ddfc970b951088a13c57dd9387dcfbb7f61/jupyterlab-4.5.7-py3-none-any.whl", hash = "sha256:fba4cb0e2c44a52859669d8c98b45de029d5e515f8407bf8534d2a8fc5f0964d", size = 12450123, upload-time = "2026-04-29T16:43:46.639Z" }, + { url = "https://files.pythonhosted.org/packages/0a/eb/aa48075d0aa3d0188db34ba2704f53791757743c0bb02e18c4eef989b6de/jupyterlab-4.6.0-py3-none-any.whl", hash = "sha256:b6938cb8a1ef3d43860ff4745a680c62cc0a9385f9672295bb56cd2e7cfeebe2", size = 17143447, upload-time = "2026-06-18T13:52:51.42Z" }, ] [[package]] @@ -2629,18 +2643,19 @@ wheels = [ [[package]] name = "notebook" -version = "7.5.6" +version = "7.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "jupyter-builder" }, { name = "jupyter-server" }, { name = "jupyterlab" }, { name = "jupyterlab-server" }, { name = "notebook-shim" }, { name = "tornado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/c2/cf59bd2e6f2c8b976b52477e3e53bf6f97bc714ed046a51821afb428eaee/notebook-7.5.6.tar.gz", hash = "sha256:621174aade80108f0020b0f00738000b215f75fa3cd90771ad7aa0f24536a4e1", size = 14170814, upload-time = "2026-04-30T11:46:26.613Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/44/d5c65783f490298473bb1c05722e05ee2256231389559c2c5ae0a3e5d975/notebook-7.6.0.tar.gz", hash = "sha256:ea13e79e601bf273074895fdfb17dd3f2da916d3c045e0b9c47d18b16ab62481", size = 5497344, upload-time = "2026-06-18T16:18:55.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/d6/1fd0646b9bbd9efbb0b8ae21b2325fbef515769a5621c03e31d8eb8da587/notebook-7.5.6-py3-none-any.whl", hash = "sha256:4dde3f8fb55fa8fb7946d58c6e869ce9baf46d00fc070664f62604569d0faca0", size = 14581730, upload-time = "2026-04-30T11:46:22.342Z" }, + { url = "https://files.pythonhosted.org/packages/93/d1/e617c40db57ff40e75f43a7d4d1c305e3a54c053ab5cb0534a6c314664f9/notebook-7.6.0-py3-none-any.whl", hash = "sha256:98aa2811b54ac191321d5dfce12ca700f8a511a33a26e4de2fa106a357c43d6a", size = 5544575, upload-time = "2026-06-18T16:18:52.551Z" }, ] [[package]] @@ -4842,19 +4857,19 @@ wheels = [ [[package]] name = "tornado" -version = "6.5.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" }, - { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" }, - { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" }, - { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" }, - { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" }, - { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" }, - { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" }, - { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" }, - { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" }, +version = "6.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/24/95ec527ad67b76d59299e5465b3935d05e4294b7e0290a3924b7487df30b/tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2", size = 519252, upload-time = "2026-06-08T17:34:51.232Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/dc/c7043cab6fed8ae159fc1923ce829ada35c4dbd797d408a43858ffaf9639/tornado-6.5.7-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163", size = 448543, upload-time = "2026-06-08T17:34:38.052Z" }, + { url = "https://files.pythonhosted.org/packages/92/4f/090b1431e5a43df696feceffc268c5383cc079ecb5f08ce58f917109aafe/tornado-6.5.7-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100", size = 446707, upload-time = "2026-06-08T17:34:39.594Z" }, + { url = "https://files.pythonhosted.org/packages/37/d8/ef374952fd5da67d4463122c2b8e5a96536ec10b4b339254c6dcde81d01c/tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972", size = 449774, upload-time = "2026-06-08T17:34:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/35/37/d434c73f4c6e014b745b9b37085f34f40c022f007efff3d7fe65991899f3/tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b", size = 450745, upload-time = "2026-06-08T17:34:42.531Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2b/56b9aff361d7f1ab728a805ec7d7ea835f8807afa9f5cc690ea0e630efb9/tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92", size = 450578, upload-time = "2026-06-08T17:34:43.787Z" }, + { url = "https://files.pythonhosted.org/packages/02/30/a7444fb23aa76860a14198fab96ac79f1866b0a6e19e26c4381b0938e50f/tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5", size = 449985, upload-time = "2026-06-08T17:34:45.326Z" }, + { url = "https://files.pythonhosted.org/packages/5c/42/5f0e56c01e8d9d36f4e23f367b85ae6cae0c1ecddd5e6977d8388ad27488/tornado-6.5.7-cp39-abi3-win32.whl", hash = "sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4", size = 451047, upload-time = "2026-06-08T17:34:46.784Z" }, + { url = "https://files.pythonhosted.org/packages/c9/a4/b393076ffb21b469eec5b328a0534cf03a3b90bfc6b1f09507cdd075d938/tornado-6.5.7-cp39-abi3-win_amd64.whl", hash = "sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4", size = 451485, upload-time = "2026-06-08T17:34:48.248Z" }, + { url = "https://files.pythonhosted.org/packages/71/2e/7b1c769803121b809112cf9a00681c472eae1d80e32d7ec0e0bd61d0d0e1/tornado-6.5.7-cp39-abi3-win_arm64.whl", hash = "sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796", size = 450506, upload-time = "2026-06-08T17:34:49.702Z" }, ] [[package]]