modelaudit 0.2.51__tar.gz → 0.2.52__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/release-please.yml +438 -3
- modelaudit-0.2.52/.release-please-manifest.json +4 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/AGENTS.md +1 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/CHANGELOG.md +18 -3
- {modelaudit-0.2.51 → modelaudit-0.2.52}/Dockerfile.full +1 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/PKG-INFO +2 -2
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/agents/release-process.md +14 -2
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/user/compatibility-matrix.md +1 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/scan_results_cache.py +3 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/core.py +6 -6
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/archive_dispatch.py +16 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/gguf_scanner.py +131 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/joblib_scanner.py +23 -3
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/llamafile_scanner.py +71 -24
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/pickle_scanner.py +2 -2
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/tar_scanner.py +25 -16
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/weight_distribution_scanner.py +0 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/detection.py +6 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/huggingface.py +0 -6
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/AGENTS.md +2 -2
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/CHANGELOG.md +6 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/Cargo.lock +1 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/Cargo.toml +1 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/pyproject.toml +1 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/src/modelaudit_picklescan/call_graph.py +31 -3
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_api.py +4 -4
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_import_statements.py +62 -2
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/uv.lock +1 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/pyproject.toml +2 -2
- {modelaudit-0.2.51 → modelaudit-0.2.52}/release-please-config.json +0 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/cache/test_cache_correctness.py +58 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_gguf_scanner.py +408 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_joblib_scanner_codecs.py +222 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_llamafile_scanner.py +200 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_pickle_scanner.py +11 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_tar_scanner.py +53 -12
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_text_scanner.py +1 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_auth_config.py +25 -1
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_core.py +37 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_dependency_lock.py +1 -1
- modelaudit-0.2.52/tests/test_release_workflow.py +1574 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_security_enhancements.py +22 -2
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_interrupt_handling.py +5 -5
- {modelaudit-0.2.51 → modelaudit-0.2.52}/uv.lock +85 -85
- modelaudit-0.2.51/.release-please-manifest.json +0 -4
- modelaudit-0.2.51/tests/test_release_workflow.py +0 -595
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.dockerignore +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.editorconfig +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.gitattributes +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/CODEOWNERS +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/markdown-link-check-config.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/README.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/codeql.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/docker-image-test.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/docker-publish.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/docs-check.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/nightly.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/perf.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/test.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.github/workflows/validate-pr-title.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.gitignore +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.mailmap +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.modelaudit.toml.example +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/.prettierignore +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/CLAUDE.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/CODE_OF_CONDUCT.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/CONTRIBUTING.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/Dockerfile +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/Dockerfile.tensorflow +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/LICENSE +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/MAINTAINERS.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/MANIFEST.in +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/README.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/RULES.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/SECURITY.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/SUPPORT.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/THIRD_PARTY_NOTICES.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/codecov.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docker-compose.yml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docker-entrypoint.sh +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/agents/architecture.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/agents/dependencies.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/agents/new-scanner-quickstart.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/agents/performance-audit.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/agents/picklescan-package-split.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/maintainers/cve-process.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/maintainers/dependency-policy.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/maintainers/scanner-cve-coverage.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/maintainers/triage-playbook.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/security/threat-model.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/user/metadata-extraction.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/user/offline-air-gapped.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/user/scanner-selection.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/docs/user/security-model.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/__main__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/anomaly_detector.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/entropy_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/framework_patterns.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/integrated_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/ml_context_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/opcode_sequence_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/semantic_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/analysis/unified_context.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/auth/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/auth/client.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/auth/config.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/adaptive_cache_keys.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/batch_operations.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/cache_manager.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/cache_policy.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/optimized_config.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cache/trusted_config_store.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/cli.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/constants.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/data/public_suffix_list.dat +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/data/spdx_licenses.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/explanations.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/generated_keras_layers.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/local_config.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/name_blacklist.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/config/rule_config.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/core_results.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/detectors/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/detectors/cve_patterns.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/detectors/jit_script.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/detectors/network_comm.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/detectors/secrets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/detectors/suspicious_symbols.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/integrations/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/integrations/jfrog.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/integrations/license_checker.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/integrations/mlflow.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/integrations/sarif_formatter.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/integrations/sbom_generator.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/integrations/source_redaction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/metadata_extractor.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/models.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/progress/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/progress/base.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/progress/console.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/progress/file.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/progress/hooks.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/progress/multi_phase.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/LICENSE +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/NOTICE +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/py.typed +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/allocation_description_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/api_def_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/attr_value_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/cost_graph_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/cpp_shape_inference_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/dataset_metadata_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/dataset_options_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/dataset_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/device_attributes_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/full_type_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/function_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/graph_debug_info_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/graph_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/graph_transfer_info_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/kernel_def_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/log_memory_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/model_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/node_def_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/op_def_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/optimized_function_graph_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/reader_base_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/resource_handle_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/step_stats_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/tensor_description_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/tensor_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/tensor_shape_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/tensor_slice_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/types_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/variable_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/framework/versions_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/cluster_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/composite_tensor_variant_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/control_flow_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/core_platform_payloads_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/critical_section_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/data_service_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/debug_event_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/debug_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/device_filters_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/device_properties_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/fingerprint_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/meta_graph_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/named_tensor_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/remote_tensor_handle_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/rewriter_config_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/saved_model_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/saved_object_graph_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/saver_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/service_config_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/snapshot_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/struct_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/tensor_bundle_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/trackable_object_graph_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/transport_options_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/protos/tensorflow/core/protobuf/verifier_config_pb2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/py.typed +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/rule_catalog.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/rules.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanner_registry_metadata.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanner_results.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanner_selection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/_archive_config.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/_archive_locations.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/_archive_outcomes.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/_catboost_evidence_redaction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/_evidence_redaction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/_string_extraction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/archive_member_security.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/base.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/catboost_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/cntk_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/compressed_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/coreml_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/executorch_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/flax_msgpack_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/jax_checkpoint_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/jinja2_template_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/keras_h5_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/keras_utils.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/keras_zip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/lightgbm_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/manifest_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/metadata_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/mxnet_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/nemo_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/numpy_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/oci_layer_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/onnx_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/openvino_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/paddle_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/picklescan_adapter.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/pmml_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/protobuf_model_candidate_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/pytorch_binary_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/pytorch_zip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/pytorch_zip_support/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/pytorch_zip_support/archive_members.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/r_serialized_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/rar_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/rknn_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/rule_mapper.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/safetensors_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/sevenzip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/skops_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/tensorrt_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/text_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/tf_metagraph_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/tf_savedmodel_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/tflite_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/torch7_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/torchserve_mar_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/xgboost_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/scanners/zip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/telemetry.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/_path_hardening.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/auto_defaults.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/_compression.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/filtering.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/handlers.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/hdf5.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/large_file_handler.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/file/streaming.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/assets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/auto_defaults.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/cache_decorator.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/code_validation.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/disk_space.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/file_hash.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/file_iterator.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/interrupt_handler.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/ml_context.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/result_conversion.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/retry.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/secure_hasher.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/helpers/types.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/lfs.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/model_extensions.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/repository_context.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/_huggingface_cache.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/_huggingface_download_worker.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/cloud_storage.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/dvc.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/huggingface_paths.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/jfrog.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/sources/pytorch_hub.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/utils/tensorflow_compat.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/version.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/whitelists/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/whitelists/huggingface_organizations.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/modelaudit/whitelists/huggingface_popular.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/package-lock.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/package.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/README.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/README.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/expansion.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/lib.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/nested.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/nested_surface.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/opcode.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/options.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/policy.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/post_budget.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/pybridge.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/report.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/stack.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/state.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/strings.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/rust/src/strings_policy.rs +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/src/modelaudit_picklescan/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/src/modelaudit_picklescan/api.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/src/modelaudit_picklescan/options.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/src/modelaudit_picklescan/py.typed +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/src/modelaudit_picklescan/report.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/conftest.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/parity_corpus.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_adversarial_pickle_oracle.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_assignment_alias_cycle.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_click.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_execnet.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_instance_defaults.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_local_imports.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_safe_spec_resolution.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_six.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_call_graph_tkinter.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_import_boundary.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_known_size_streams.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_native_interface.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_nested_budget_limits.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_options.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_protocol0_line_operands.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_report.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/packages/modelaudit-picklescan/tests/test_rust_engine.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/pyproject.toml.example +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/renovate.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/requirements-tensorflow.txt +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/README.md +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/benchmark_report.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/check_circular_imports.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/compile_tensorflow_protos.sh +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/fetch_hf_org_models.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/fetch_hf_top_models.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/generate_keras_layer_inventory.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/jax_flax_scanning_demo.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/large_pickle_corpus_qa.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/minimal_circular_check.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/profile_scan.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/scripts/validate_docker_publish_tag.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/analysis/test_analysis_modules.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/analysis/test_anomaly_detector.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/analysis/test_entropy_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/analysis/test_framework_patterns.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/analysis/test_ml_context_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/analysis/test_opcode_sequence_analyzer.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/analysis/test_unified_context.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit1_basic_torch_bypass.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit2_advanced_torch_bypass.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit3_sophisticated_hybrid.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit4_supply_chain_attack.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit5_ultra_high_confidence.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit6_ordereddict_bypass.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit7_nested_collections.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit9_manual_construction.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/exploits/exploit_ultimate_50pct.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_7z_test_assets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_advanced_pickle_tests.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_evil_pickle.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_jinja2_test_assets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_nested_pickle_assets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_os_alias_tests.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_safe_nested_assets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_safetensors_assets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/generators/generate_security_assets.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/huggingface_false_positive_manifest.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/pickles/memo_attack.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/pickles/multiple_stream_attack.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/pickles/nt_alias_attack.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/pickles/posix_alias_attack.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/pickles/stack_global_attack.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/archives/path_traversal.zip +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/archives/safe_model.zip +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/benign/chatml_format.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/benign/complex_legitimate.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/benign/conditional_system.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/benign/huggingface_llama.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/benign/simple_roles.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/benign/special_tokens.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/edge_cases/empty_template.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/edge_cases/malformed_template.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/edge_cases/multiple_templates.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/edge_cases/no_template.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/edge_cases/oversized_template.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/attr_bypass.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/combined_attack.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/config_exploit.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/cve_2024_34359_original.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/direct_eval.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/env_extraction.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/file_access.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/hex_bypass.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/loop_discovery.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/network_exfil.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/request_exploit.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/malicious/subprocess_injection.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/obfuscated/base64_payload.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/obfuscated/char_construction.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/obfuscated/format_bypass.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/obfuscated/getattr_bypass.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/standalone/benign_chat.j2 +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/standalone/malicious_standalone.jinja +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/standalone/malicious_subprocess.template +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/standalone/suspicious_benign.template +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/yaml/malicious_config.yaml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/jinja2/yaml/model_config.yaml +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/keras/custom_layer_attack.h5 +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/keras/loss_injection.h5 +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/keras/malicious_lambda.h5 +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/keras/metric_injection.h5 +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/keras/safe_model.h5 +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/manifests/safe_config.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/manifests/suspicious_config.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/decode_exec_chain.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/dill_func.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/malicious_model_realistic.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/malicious_system_call.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/nested_pickle_base64.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/nested_pickle_hex.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/nested_pickle_multistage.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/nested_pickle_raw.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/safe_data.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/safe_large_model.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/safe_model_with_binary.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/safe_model_with_encoding.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/safe_model_with_tokens.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/safe_nested_structure.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pickles/simple_nested.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pipeline.skops +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pytorch/malicious_eval.pt +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/pytorch/safe_model.pt +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/safetensors/malicious_import.safetensors +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/safetensors/safe_model.safetensors +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/sentencepiece/custom_unknown_disabled_specials.model +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/sentencepiece/custom_unknown_disabled_specials_byte_fallback.model +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/tensorflow/malicious_pyfunc/saved_model.pb +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/samples/tensorflow/safe_savedmodel/saved_model.pb +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/agpl_component/agpl_model.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/agpl_component/neural_network.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mit_model/config.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mit_model/model.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mit_model/model_weights.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mixed_licenses/LICENSE +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mixed_licenses/apache_component.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mixed_licenses/dataset_cc_nc.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mixed_licenses/gpl_utility.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/mixed_licenses/mixed_model.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/unlicensed_dataset/embeddings.npy +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/unlicensed_dataset/features.csv +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/license_scenarios/unlicensed_dataset/training_data.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/security_scenarios/mixed_malicious_model/config.json +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/assets/scenarios/security_scenarios/mixed_malicious_model/model.pkl +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/benchmarks/test_picklescan_benchmarks.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/benchmarks/test_scan_benchmarks.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/cache/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/cache/test_optimized_config.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/cli_output.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/config/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/config/test_name_blacklist.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/conftest.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/demo_license_functionality.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_builtin_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_compile_eval_variants.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_cve_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_cve_detection.py_cases/test_pickle_binunicode8_setitem.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_jit_script_detector.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_network_comm_detector.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_runpy_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_secrets_detector.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/detectors/test_suspicious_symbols.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/helpers/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/helpers/file_creators.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/helpers/frameworks.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_jfrog.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_jfrog_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_jfrog_redirect_security.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_license_checker.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_license_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_mlflow_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_sarif_formatter.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_sarif_redaction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_sbom_license_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_sbom_symlink_containment.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/integrations/test_sbom_url_fixes.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/progress/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/progress/test_base.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/progress/test_hooks_egress.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_base_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_catboost_evidence_redaction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_catboost_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_cntk_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_compressed_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_coreml_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_evidence_redaction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_evidence_redaction_authorization_continuation.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_executorch_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_flax_msgpack_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_jax_checkpoint_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_jinja2_template_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_joblib_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_keras_h5_lambda_helpers.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_keras_h5_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_keras_utils.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_keras_zip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_lightgbm_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_manifest_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_metadata_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_mxnet_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_nemo_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_numpy_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_oci_layer_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_onnx_dependency_handling.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_onnx_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_openvino_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_paddle_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_picklescan_adapter.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_pmml_dependency_handling.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_pmml_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_pytorch_binary_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_pytorch_zip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_r_serialized_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_rknn_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_rule_code_registry_consistency.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_rule_mapper.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_safetensors_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_scanner_registry.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_sevenzip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_skops_content_analysis.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_skops_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_tensorrt_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_tf_metagraph_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_tf_savedmodel_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_tflite_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_torch7_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_torchserve_mar_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_weight_distribution_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_xgboost_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scanners/test_zip_scanner.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scripts/test_hf_whitelist_generators.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/scripts/test_large_pickle_corpus_qa.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_asset_inventory_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_asset_list.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_basic.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_benchmark_report.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_bug1_confidence_exploit.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cache_cli.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cache_optimizations.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_checks_recording.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cli.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cli_cache_dir.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cli_default_command.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cli_file_filtering.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cli_license_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cli_logging_handlers.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cli_output.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cloud_url_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_committed_fixture_hygiene.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_core_asset_extraction.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_cve_2025_10155_bin_pickle.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_debug_command.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_dill_joblib_enhanced.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_directory_file_filtering.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_docker_workflow.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_double_interrupt.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_exit_codes.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_false_positive_fixes.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_file_hash.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_gguf_sbom_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_graceful_degradation.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_header_discrepancy.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_huggingface_extensions.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_huggingface_fp_regression_harness.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_huggingface_inconclusive_coverage.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_huggingface_symlinks.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_importlib_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_jax_flax_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_jit_script_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_lazy_loading.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_lazy_loading_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_manifest_name_policy.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_metadata_extractor.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_models.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_nested_pickle_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_network_comm_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_nightly_asset_contracts.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_nightly_prerequisites.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_os_alias_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_os_subprocess_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_path_traversal.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_perf_workflow.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_performance_benchmarks.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_pickle_context_filtering.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_progress.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_pydantic_models.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_python_version_warning.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_pytorch_zip_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_real_world_dill_joblib.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_regression_corpus.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_regular_scan_hash.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_rules.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_safetensors_optimization.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_scanner_selection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_secure_hasher.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_security_asset_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_shebang_context.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_simple_jinja2.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_sklearn_joblib_false_positive.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_streaming_scan.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_telemetry.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_telemetry_decoupling.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_tensorflow_lambda_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_timeout_configuration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_utils.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_weak_hash_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_webbrowser_detection.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_why_explanations.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/test_xdist_status.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_advanced_file_handler.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_advanced_size_limits.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_file_filter.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_file_type_validation_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_filetype.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_integration_file_type_demo.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_large_file_handler.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_streaming_analysis.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/file/test_streaming_preview.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_asset_from_scan_result.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_auto_defaults.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_code_validation.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_disk_space.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_file_iterator.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_ml_context_false_positives.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_py_compile_improvements.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/helpers/test_secure_hasher.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/sources/test_cloud_storage.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/sources/test_dvc_integration.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/sources/test_huggingface.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/sources/test_pytorch_hub.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/test_lfs.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/utils/test_result_conversion.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/whitelists/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/whitelists/test_combined.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/whitelists/test_huggingface_popular.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/whitelists/test_organizations.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/workflows/__init__.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/workflows/test_docker_workflow.py +0 -0
- {modelaudit-0.2.51 → modelaudit-0.2.52}/tests/xdist_status.py +0 -0
|
@@ -22,6 +22,10 @@ on:
|
|
|
22
22
|
description: "Publish an already-versioned modelaudit-picklescan release, for example 0.1.2"
|
|
23
23
|
required: false
|
|
24
24
|
type: string
|
|
25
|
+
root_provenance_run_id:
|
|
26
|
+
description: "Recover root provenance from the original verified publish run, for example 29787069929"
|
|
27
|
+
required: false
|
|
28
|
+
type: string
|
|
25
29
|
|
|
26
30
|
jobs:
|
|
27
31
|
release-please:
|
|
@@ -36,6 +40,8 @@ jobs:
|
|
|
36
40
|
picklescan_release_created: ${{ steps.manual.outputs.manual_release == 'true' && steps.manual.outputs.picklescan_release_created || steps.release.outputs['packages/modelaudit-picklescan--release_created'] }}
|
|
37
41
|
picklescan_tag_name: ${{ steps.manual.outputs.manual_release == 'true' && steps.manual.outputs.picklescan_tag_name || steps.release.outputs['packages/modelaudit-picklescan--tag_name'] }}
|
|
38
42
|
picklescan_version: ${{ steps.manual.outputs.manual_release == 'true' && steps.manual.outputs.picklescan_version || steps.release.outputs['packages/modelaudit-picklescan--version'] }}
|
|
43
|
+
root_provenance_recovery: ${{ steps.manual.outputs.root_provenance_recovery }}
|
|
44
|
+
root_provenance_run_id: ${{ steps.manual.outputs.root_provenance_run_id }}
|
|
39
45
|
pr_number: ${{ steps.release.outputs.pr && fromJSON(steps.release.outputs.pr).number || '' }}
|
|
40
46
|
pr_branch: ${{ steps.check-pr.outputs.pr_branch || '' }}
|
|
41
47
|
steps:
|
|
@@ -44,7 +50,34 @@ jobs:
|
|
|
44
50
|
env:
|
|
45
51
|
ROOT_VERSION: ${{ github.event.inputs.root_version || '' }}
|
|
46
52
|
PICKLESCAN_VERSION: ${{ github.event.inputs.picklescan_version || '' }}
|
|
53
|
+
ROOT_PROVENANCE_RUN_ID: ${{ github.event.inputs.root_provenance_run_id || '' }}
|
|
47
54
|
run: |
|
|
55
|
+
if [[ -n "$ROOT_PROVENANCE_RUN_ID" ]]; then
|
|
56
|
+
if [[ ! "$ROOT_PROVENANCE_RUN_ID" =~ ^[1-9][0-9]*$ ]]; then
|
|
57
|
+
echo "Root provenance recovery requires a numeric source run ID."
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
if [[ ! "$ROOT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
61
|
+
echo "Root provenance recovery requires root_version in X.Y.Z format."
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
if [[ -n "$PICKLESCAN_VERSION" ]]; then
|
|
65
|
+
echo "Root provenance recovery cannot publish modelaudit-picklescan."
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
{
|
|
70
|
+
echo "manual_release=true"
|
|
71
|
+
echo "release_created=false"
|
|
72
|
+
echo "picklescan_release_created=false"
|
|
73
|
+
echo "root_provenance_recovery=true"
|
|
74
|
+
echo "root_provenance_run_id=$ROOT_PROVENANCE_RUN_ID"
|
|
75
|
+
echo "version=$ROOT_VERSION"
|
|
76
|
+
echo "tag_name=v$ROOT_VERSION"
|
|
77
|
+
} >> "$GITHUB_OUTPUT"
|
|
78
|
+
exit 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
48
81
|
{
|
|
49
82
|
if [[ -n "$ROOT_VERSION" ]]; then
|
|
50
83
|
echo "release_created=true"
|
|
@@ -76,7 +109,7 @@ jobs:
|
|
|
76
109
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
77
110
|
|
|
78
111
|
- name: Ensure manual GitHub releases exist
|
|
79
|
-
if: steps.manual.outputs.manual_release == 'true'
|
|
112
|
+
if: steps.manual.outputs.manual_release == 'true' && steps.manual.outputs.root_provenance_recovery != 'true'
|
|
80
113
|
env:
|
|
81
114
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
82
115
|
ROOT_TAG: ${{ steps.manual.outputs.tag_name }}
|
|
@@ -1264,8 +1297,16 @@ jobs:
|
|
|
1264
1297
|
PY
|
|
1265
1298
|
|
|
1266
1299
|
provenance:
|
|
1267
|
-
if:
|
|
1268
|
-
|
|
1300
|
+
if: >-
|
|
1301
|
+
${{
|
|
1302
|
+
always() &&
|
|
1303
|
+
!cancelled() &&
|
|
1304
|
+
needs.release-please.outputs.release_created == 'true' &&
|
|
1305
|
+
needs.build.result == 'success' &&
|
|
1306
|
+
needs.publish-pypi.result == 'success' &&
|
|
1307
|
+
needs.verify-pypi.result == 'success'
|
|
1308
|
+
}}
|
|
1309
|
+
needs: [build, publish-pypi, verify-pypi, release-please]
|
|
1269
1310
|
runs-on: ubuntu-latest
|
|
1270
1311
|
permissions:
|
|
1271
1312
|
contents: write
|
|
@@ -1316,6 +1357,400 @@ jobs:
|
|
|
1316
1357
|
--repo "${{ github.repository }}" \
|
|
1317
1358
|
--clobber
|
|
1318
1359
|
|
|
1360
|
+
root-provenance-recovery:
|
|
1361
|
+
if: >-
|
|
1362
|
+
${{
|
|
1363
|
+
!cancelled() &&
|
|
1364
|
+
needs.release-please.result == 'success' &&
|
|
1365
|
+
needs.release-please.outputs.root_provenance_recovery == 'true'
|
|
1366
|
+
}}
|
|
1367
|
+
needs: release-please
|
|
1368
|
+
runs-on: ubuntu-latest
|
|
1369
|
+
permissions:
|
|
1370
|
+
actions: read
|
|
1371
|
+
contents: write
|
|
1372
|
+
id-token: write
|
|
1373
|
+
attestations: write
|
|
1374
|
+
steps:
|
|
1375
|
+
- name: Checkout tagged root release
|
|
1376
|
+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
1377
|
+
with:
|
|
1378
|
+
ref: refs/tags/${{ needs.release-please.outputs.tag_name }}
|
|
1379
|
+
sparse-checkout: |
|
|
1380
|
+
pyproject.toml
|
|
1381
|
+
uv.lock
|
|
1382
|
+
persist-credentials: false
|
|
1383
|
+
|
|
1384
|
+
- name: Verify original root publish run
|
|
1385
|
+
id: verify-source
|
|
1386
|
+
env:
|
|
1387
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
1388
|
+
SOURCE_RUN_ID: ${{ needs.release-please.outputs.root_provenance_run_id }}
|
|
1389
|
+
run: |
|
|
1390
|
+
if [[ ! "$SOURCE_RUN_ID" =~ ^[1-9][0-9]*$ ]]; then
|
|
1391
|
+
echo "Root provenance recovery requires a numeric source run ID."
|
|
1392
|
+
exit 1
|
|
1393
|
+
fi
|
|
1394
|
+
|
|
1395
|
+
tag_commit_sha=$(git rev-parse --verify 'HEAD^{commit}')
|
|
1396
|
+
if [[ ! "$tag_commit_sha" =~ ^[0-9a-f]{40}$ ]]; then
|
|
1397
|
+
echo "Root provenance recovery requires a valid tagged commit SHA."
|
|
1398
|
+
exit 1
|
|
1399
|
+
fi
|
|
1400
|
+
|
|
1401
|
+
run_metadata=$(mktemp)
|
|
1402
|
+
jobs_metadata=$(mktemp)
|
|
1403
|
+
repository_metadata=$(mktemp)
|
|
1404
|
+
compare_metadata=$(mktemp)
|
|
1405
|
+
tag_compare_metadata=$(mktemp)
|
|
1406
|
+
source_relation_metadata=$(mktemp)
|
|
1407
|
+
trap 'rm -f "$run_metadata" "$jobs_metadata" "$repository_metadata" "$compare_metadata" "$tag_compare_metadata" "$source_relation_metadata"' EXIT
|
|
1408
|
+
gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${SOURCE_RUN_ID}" > "$run_metadata"
|
|
1409
|
+
gh api --paginate --slurp \
|
|
1410
|
+
"repos/${GITHUB_REPOSITORY}/actions/runs/${SOURCE_RUN_ID}/jobs?per_page=100" > "$jobs_metadata"
|
|
1411
|
+
gh api "repos/${GITHUB_REPOSITORY}" > "$repository_metadata"
|
|
1412
|
+
export RUN_METADATA="$run_metadata"
|
|
1413
|
+
export JOBS_METADATA="$jobs_metadata"
|
|
1414
|
+
export REPOSITORY_METADATA="$repository_metadata"
|
|
1415
|
+
|
|
1416
|
+
source_head_sha=$(python - <<'PY'
|
|
1417
|
+
import json
|
|
1418
|
+
import os
|
|
1419
|
+
import re
|
|
1420
|
+
from pathlib import Path
|
|
1421
|
+
|
|
1422
|
+
repository = os.environ["GITHUB_REPOSITORY"]
|
|
1423
|
+
source_run_id = os.environ["SOURCE_RUN_ID"]
|
|
1424
|
+
run = json.loads(Path(os.environ["RUN_METADATA"]).read_text(encoding="utf-8"))
|
|
1425
|
+
if not isinstance(run, dict):
|
|
1426
|
+
raise SystemExit(f"Source run {source_run_id} returned invalid run metadata")
|
|
1427
|
+
if run.get("path") != ".github/workflows/release-please.yml":
|
|
1428
|
+
raise SystemExit(f"Source run {source_run_id} is not a release-please workflow run")
|
|
1429
|
+
if run.get("event") not in {"push", "workflow_dispatch"}:
|
|
1430
|
+
raise SystemExit(f"Source run {source_run_id} has an unsupported event: {run.get('event')!r}")
|
|
1431
|
+
if run.get("status") != "completed" or run.get("conclusion") not in {"success", "failure"}:
|
|
1432
|
+
raise SystemExit(f"Source run {source_run_id} did not complete with a supported conclusion")
|
|
1433
|
+
source_repository = run.get("repository")
|
|
1434
|
+
if not isinstance(source_repository, dict) or source_repository.get("full_name") != repository:
|
|
1435
|
+
raise SystemExit(f"Source run {source_run_id} belongs to a different repository")
|
|
1436
|
+
repository_metadata = json.loads(Path(os.environ["REPOSITORY_METADATA"]).read_text(encoding="utf-8"))
|
|
1437
|
+
if not isinstance(repository_metadata, dict) or repository_metadata.get("full_name") != repository:
|
|
1438
|
+
raise SystemExit(f"Source run {source_run_id} returned invalid repository metadata")
|
|
1439
|
+
if repository_metadata.get("default_branch") != "main":
|
|
1440
|
+
raise SystemExit(f"Source run {source_run_id} repository does not use main as its default branch")
|
|
1441
|
+
head_repository = run.get("head_repository")
|
|
1442
|
+
if not isinstance(head_repository, dict) or head_repository.get("full_name") != repository:
|
|
1443
|
+
raise SystemExit(f"Source run {source_run_id} has an untrusted head repository")
|
|
1444
|
+
head_sha = run.get("head_sha")
|
|
1445
|
+
if not isinstance(head_sha, str) or not re.fullmatch(r"[0-9a-f]{40}", head_sha):
|
|
1446
|
+
raise SystemExit(f"Source run {source_run_id} returned an invalid head SHA")
|
|
1447
|
+
|
|
1448
|
+
pages = json.loads(Path(os.environ["JOBS_METADATA"]).read_text(encoding="utf-8"))
|
|
1449
|
+
if not isinstance(pages, list) or not pages:
|
|
1450
|
+
raise SystemExit(f"Source run {source_run_id} returned no job pages")
|
|
1451
|
+
jobs = []
|
|
1452
|
+
for page in pages:
|
|
1453
|
+
if not isinstance(page, dict) or not isinstance(page.get("jobs"), list):
|
|
1454
|
+
raise SystemExit(f"Source run {source_run_id} returned invalid job metadata")
|
|
1455
|
+
if not all(isinstance(job, dict) for job in page["jobs"]):
|
|
1456
|
+
raise SystemExit(f"Source run {source_run_id} returned an invalid job")
|
|
1457
|
+
jobs.extend(page["jobs"])
|
|
1458
|
+
for job_name in ("build", "publish-pypi", "verify-pypi"):
|
|
1459
|
+
matching = [job for job in jobs if job.get("name") == job_name]
|
|
1460
|
+
if len(matching) != 1:
|
|
1461
|
+
raise SystemExit(f"Source run {source_run_id} must contain exactly one {job_name} job")
|
|
1462
|
+
job = matching[0]
|
|
1463
|
+
if job.get("status") != "completed" or job.get("conclusion") != "success":
|
|
1464
|
+
raise SystemExit(f"Source run {source_run_id} {job_name} job did not complete successfully")
|
|
1465
|
+
print(head_sha)
|
|
1466
|
+
PY
|
|
1467
|
+
)
|
|
1468
|
+
|
|
1469
|
+
gh api "repos/${GITHUB_REPOSITORY}/compare/${source_head_sha}...main" > "$compare_metadata"
|
|
1470
|
+
gh api "repos/${GITHUB_REPOSITORY}/compare/${tag_commit_sha}...main" > "$tag_compare_metadata"
|
|
1471
|
+
gh api "repos/${GITHUB_REPOSITORY}/compare/${tag_commit_sha}...${source_head_sha}" > "$source_relation_metadata"
|
|
1472
|
+
export COMPARE_METADATA="$compare_metadata"
|
|
1473
|
+
export TAG_COMPARE_METADATA="$tag_compare_metadata"
|
|
1474
|
+
export SOURCE_RELATION_METADATA="$source_relation_metadata"
|
|
1475
|
+
export SOURCE_HEAD_SHA="$source_head_sha"
|
|
1476
|
+
export TAG_COMMIT_SHA="$tag_commit_sha"
|
|
1477
|
+
python - <<'PY'
|
|
1478
|
+
import json
|
|
1479
|
+
import os
|
|
1480
|
+
from pathlib import Path
|
|
1481
|
+
|
|
1482
|
+
source_run_id = os.environ["SOURCE_RUN_ID"]
|
|
1483
|
+
source_head_sha = os.environ["SOURCE_HEAD_SHA"]
|
|
1484
|
+
tag_commit_sha = os.environ["TAG_COMMIT_SHA"]
|
|
1485
|
+
for label, expected_sha, metadata_path in (
|
|
1486
|
+
(f"Source run {source_run_id}", source_head_sha, os.environ["COMPARE_METADATA"]),
|
|
1487
|
+
("Tagged root release", tag_commit_sha, os.environ["TAG_COMPARE_METADATA"]),
|
|
1488
|
+
("Tagged root release relative to source run", tag_commit_sha, os.environ["SOURCE_RELATION_METADATA"]),
|
|
1489
|
+
):
|
|
1490
|
+
comparison = json.loads(Path(metadata_path).read_text(encoding="utf-8"))
|
|
1491
|
+
if not isinstance(comparison, dict):
|
|
1492
|
+
raise SystemExit(f"{label} returned invalid branch comparison metadata")
|
|
1493
|
+
if comparison.get("status") not in {"ahead", "identical"}:
|
|
1494
|
+
raise SystemExit(f"{label} does not belong to protected main history")
|
|
1495
|
+
behind_by = comparison.get("behind_by")
|
|
1496
|
+
if not isinstance(behind_by, int) or isinstance(behind_by, bool) or behind_by != 0:
|
|
1497
|
+
raise SystemExit(f"{label} is not an ancestor of protected main")
|
|
1498
|
+
merge_base = comparison.get("merge_base_commit")
|
|
1499
|
+
if not isinstance(merge_base, dict) or merge_base.get("sha") != expected_sha:
|
|
1500
|
+
raise SystemExit(f"{label} has an untrusted merge base")
|
|
1501
|
+
|
|
1502
|
+
source_relation = json.loads(Path(os.environ["SOURCE_RELATION_METADATA"]).read_text(encoding="utf-8"))
|
|
1503
|
+
changed_files = source_relation.get("files")
|
|
1504
|
+
allowed_source_changes = {".github/workflows/release-please.yml", "tests/test_release_workflow.py"}
|
|
1505
|
+
if not isinstance(changed_files, list) or len(changed_files) > len(allowed_source_changes):
|
|
1506
|
+
raise SystemExit("Tagged root release and source run returned invalid changed-file metadata")
|
|
1507
|
+
if not all(
|
|
1508
|
+
isinstance(entry, dict)
|
|
1509
|
+
and entry.get("filename") in allowed_source_changes
|
|
1510
|
+
and entry.get("status") in {"added", "modified", "removed", "renamed"}
|
|
1511
|
+
and (
|
|
1512
|
+
entry.get("previous_filename") in allowed_source_changes
|
|
1513
|
+
if entry.get("status") == "renamed"
|
|
1514
|
+
else entry.get("previous_filename") is None
|
|
1515
|
+
)
|
|
1516
|
+
for entry in changed_files
|
|
1517
|
+
):
|
|
1518
|
+
raise SystemExit("Tagged root release and source run differ outside the trusted release-repair files")
|
|
1519
|
+
print(
|
|
1520
|
+
f"Verified original modelaudit publish run {source_run_id} at {source_head_sha} "
|
|
1521
|
+
f"and tagged root release at {tag_commit_sha}"
|
|
1522
|
+
)
|
|
1523
|
+
PY
|
|
1524
|
+
{
|
|
1525
|
+
echo "source_head_sha=$source_head_sha"
|
|
1526
|
+
echo "tag_commit_sha=$tag_commit_sha"
|
|
1527
|
+
} >> "$GITHUB_OUTPUT"
|
|
1528
|
+
|
|
1529
|
+
- name: Download original root build artifacts
|
|
1530
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
|
1531
|
+
with:
|
|
1532
|
+
name: dist
|
|
1533
|
+
path: dist/
|
|
1534
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
1535
|
+
repository: ${{ github.repository }}
|
|
1536
|
+
run-id: ${{ needs.release-please.outputs.root_provenance_run_id }}
|
|
1537
|
+
|
|
1538
|
+
- name: Verify recovered root artifacts match PyPI
|
|
1539
|
+
env:
|
|
1540
|
+
EXPECTED_VERSION: ${{ needs.release-please.outputs.version }}
|
|
1541
|
+
run: |
|
|
1542
|
+
python - <<'PY'
|
|
1543
|
+
import hashlib
|
|
1544
|
+
import json
|
|
1545
|
+
import os
|
|
1546
|
+
import posixpath
|
|
1547
|
+
import re
|
|
1548
|
+
import tarfile
|
|
1549
|
+
import unicodedata
|
|
1550
|
+
import urllib.request
|
|
1551
|
+
from pathlib import Path
|
|
1552
|
+
|
|
1553
|
+
try:
|
|
1554
|
+
import tomllib
|
|
1555
|
+
except ModuleNotFoundError:
|
|
1556
|
+
import tomli as tomllib
|
|
1557
|
+
|
|
1558
|
+
version = os.environ["EXPECTED_VERSION"]
|
|
1559
|
+
if not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+", version):
|
|
1560
|
+
raise SystemExit(f"Invalid root release version: {version!r}")
|
|
1561
|
+
|
|
1562
|
+
max_metadata_bytes = 10 * 1024 * 1024
|
|
1563
|
+
max_sdist_members = 10_000
|
|
1564
|
+
max_sdist_member_bytes = 16 * 1024 * 1024
|
|
1565
|
+
max_sdist_bytes = 256 * 1024 * 1024
|
|
1566
|
+
tagged_metadata = {}
|
|
1567
|
+
for filename in ("pyproject.toml", "uv.lock"):
|
|
1568
|
+
tagged_path = Path(filename)
|
|
1569
|
+
tagged_size = tagged_path.stat().st_size
|
|
1570
|
+
if tagged_size > max_metadata_bytes:
|
|
1571
|
+
raise SystemExit(f"Tagged root {filename} exceeds {max_metadata_bytes} bytes")
|
|
1572
|
+
tagged_content = tagged_path.read_bytes()
|
|
1573
|
+
if len(tagged_content) != tagged_size:
|
|
1574
|
+
raise SystemExit(f"Tagged root {filename} changed while it was being read")
|
|
1575
|
+
tagged_metadata[filename] = tagged_content
|
|
1576
|
+
|
|
1577
|
+
try:
|
|
1578
|
+
tagged_project = tomllib.loads(tagged_metadata["pyproject.toml"].decode("utf-8"))
|
|
1579
|
+
except (UnicodeError, ValueError) as error:
|
|
1580
|
+
raise SystemExit(f"Could not parse tagged root pyproject.toml: {error}") from error
|
|
1581
|
+
project = tagged_project.get("project")
|
|
1582
|
+
if not isinstance(project, dict):
|
|
1583
|
+
raise SystemExit("Tagged root pyproject.toml has no valid [project] table")
|
|
1584
|
+
if project.get("name") != "modelaudit" or project.get("version") != version:
|
|
1585
|
+
raise SystemExit(f"Tagged root project does not match modelaudit {version}: {project!r}")
|
|
1586
|
+
|
|
1587
|
+
expected = {f"modelaudit-{version}-py3-none-any.whl", f"modelaudit-{version}.tar.gz"}
|
|
1588
|
+
try:
|
|
1589
|
+
paths = list(Path("dist").iterdir())
|
|
1590
|
+
except OSError as error:
|
|
1591
|
+
raise SystemExit(f"Could not inspect recovered root artifacts: {error}") from error
|
|
1592
|
+
if {path.name for path in paths} != expected or any(not path.is_file() or path.is_symlink() for path in paths):
|
|
1593
|
+
raise SystemExit(f"Expected exactly the root wheel and sdist, found {[path.name for path in paths]!r}")
|
|
1594
|
+
|
|
1595
|
+
try:
|
|
1596
|
+
with urllib.request.urlopen(f"https://pypi.org/pypi/modelaudit/{version}/json", timeout=20) as response:
|
|
1597
|
+
pypi_metadata = response.read(max_metadata_bytes + 1)
|
|
1598
|
+
if len(pypi_metadata) > max_metadata_bytes:
|
|
1599
|
+
raise SystemExit(f"PyPI metadata for modelaudit {version} exceeds {max_metadata_bytes} bytes")
|
|
1600
|
+
payload = json.loads(pypi_metadata)
|
|
1601
|
+
except (OSError, ValueError) as error:
|
|
1602
|
+
raise SystemExit(f"Could not verify PyPI metadata for modelaudit {version}: {error}") from error
|
|
1603
|
+
if not isinstance(payload, dict) or not isinstance(payload.get("info"), dict):
|
|
1604
|
+
raise SystemExit(f"PyPI returned invalid modelaudit metadata for {version}")
|
|
1605
|
+
if payload["info"].get("version") != version:
|
|
1606
|
+
raise SystemExit(f"PyPI returned an unexpected modelaudit version for {version}")
|
|
1607
|
+
|
|
1608
|
+
urls = payload.get("urls")
|
|
1609
|
+
if not isinstance(urls, list) or any(
|
|
1610
|
+
not isinstance(entry, dict) or not isinstance(entry.get("filename"), str) for entry in urls
|
|
1611
|
+
):
|
|
1612
|
+
raise SystemExit(f"PyPI returned an invalid artifact list for modelaudit {version}")
|
|
1613
|
+
published = {entry.get("filename"): entry for entry in urls}
|
|
1614
|
+
if len(published) != len(urls) or set(published) != expected:
|
|
1615
|
+
raise SystemExit(f"PyPI files for modelaudit {version} do not match {sorted(expected)!r}")
|
|
1616
|
+
|
|
1617
|
+
for path in paths:
|
|
1618
|
+
entry = published[path.name]
|
|
1619
|
+
if entry.get("yanked", False):
|
|
1620
|
+
raise SystemExit(f"Refusing to attest yanked PyPI artifact {path.name}")
|
|
1621
|
+
digests = entry.get("digests")
|
|
1622
|
+
if not isinstance(digests, dict):
|
|
1623
|
+
raise SystemExit(f"PyPI did not return valid digests for {path.name}")
|
|
1624
|
+
expected_digest = digests.get("sha256")
|
|
1625
|
+
digest = hashlib.sha256()
|
|
1626
|
+
with path.open("rb") as artifact_file:
|
|
1627
|
+
for chunk in iter(lambda: artifact_file.read(1024 * 1024), b""):
|
|
1628
|
+
digest.update(chunk)
|
|
1629
|
+
actual_digest = digest.hexdigest()
|
|
1630
|
+
if not isinstance(expected_digest, str) or not re.fullmatch(r"[0-9a-f]{64}", expected_digest):
|
|
1631
|
+
raise SystemExit(f"PyPI did not return a valid SHA256 for {path.name}")
|
|
1632
|
+
if actual_digest != expected_digest:
|
|
1633
|
+
raise SystemExit(
|
|
1634
|
+
f"Recovered artifact SHA256 mismatch for {path.name}: {actual_digest} != {expected_digest}"
|
|
1635
|
+
)
|
|
1636
|
+
print(f"Verified {path.name}: {actual_digest}")
|
|
1637
|
+
|
|
1638
|
+
required_members = {
|
|
1639
|
+
f"modelaudit-{version}/{filename}": content for filename, content in tagged_metadata.items()
|
|
1640
|
+
}
|
|
1641
|
+
normalized_required_members = {
|
|
1642
|
+
unicodedata.normalize("NFC", unicodedata.normalize("NFC", name).casefold()): name
|
|
1643
|
+
for name in required_members
|
|
1644
|
+
}
|
|
1645
|
+
seen_members = set()
|
|
1646
|
+
seen_paths = set()
|
|
1647
|
+
seen_files = set()
|
|
1648
|
+
seen_parent_paths = set()
|
|
1649
|
+
member_count = 0
|
|
1650
|
+
declared_size = 0
|
|
1651
|
+
try:
|
|
1652
|
+
with tarfile.open(Path("dist", f"modelaudit-{version}.tar.gz"), "r|gz") as archive:
|
|
1653
|
+
for member in archive:
|
|
1654
|
+
member_count += 1
|
|
1655
|
+
if member_count > max_sdist_members:
|
|
1656
|
+
raise SystemExit(f"Root sdist exceeds {max_sdist_members} members")
|
|
1657
|
+
if member.size < 0 or member.size > max_sdist_member_bytes:
|
|
1658
|
+
raise SystemExit(f"Root sdist member has an unsafe size: {member.name}")
|
|
1659
|
+
declared_size += member.size
|
|
1660
|
+
if declared_size > max_sdist_bytes:
|
|
1661
|
+
raise SystemExit(f"Root sdist exceeds {max_sdist_bytes} declared bytes")
|
|
1662
|
+
if member.issym() or member.islnk():
|
|
1663
|
+
raise SystemExit(f"Root sdist contains a linked member: {member.name}")
|
|
1664
|
+
if not member.isreg() and not member.isdir():
|
|
1665
|
+
raise SystemExit(f"Root sdist contains a non-file member: {member.name}")
|
|
1666
|
+
member_name = member.name.removesuffix("/") if member.isdir() else member.name
|
|
1667
|
+
member_parts = member_name.split("/")
|
|
1668
|
+
if (
|
|
1669
|
+
member.name.startswith("/")
|
|
1670
|
+
or re.match(r"^[A-Za-z]:", member.name)
|
|
1671
|
+
or "\\" in member.name
|
|
1672
|
+
or any(part in {"", ".", ".."} for part in member_parts)
|
|
1673
|
+
or any(part.endswith((".", " ")) or ":" in part for part in member_parts)
|
|
1674
|
+
):
|
|
1675
|
+
raise SystemExit(f"Root sdist contains an unsafe member path: {member.name}")
|
|
1676
|
+
normalized_name = unicodedata.normalize(
|
|
1677
|
+
"NFC", unicodedata.normalize("NFC", posixpath.normpath(member.name)).casefold()
|
|
1678
|
+
)
|
|
1679
|
+
canonical_name = normalized_required_members.get(normalized_name)
|
|
1680
|
+
if canonical_name is not None and member.name != canonical_name:
|
|
1681
|
+
raise SystemExit(f"Root sdist contains a metadata path alias: {member.name}")
|
|
1682
|
+
if normalized_name in seen_paths:
|
|
1683
|
+
raise SystemExit(f"Root sdist contains a duplicate or case-normalized path: {member.name}")
|
|
1684
|
+
normalized_parts = normalized_name.split("/")
|
|
1685
|
+
parent_paths = {
|
|
1686
|
+
"/".join(normalized_parts[:index]) for index in range(1, len(normalized_parts))
|
|
1687
|
+
}
|
|
1688
|
+
if parent_paths & seen_files or member.isreg() and normalized_name in seen_parent_paths:
|
|
1689
|
+
raise SystemExit(f"Root sdist contains a file/directory path conflict: {member.name}")
|
|
1690
|
+
seen_paths.add(normalized_name)
|
|
1691
|
+
seen_parent_paths.update(parent_paths)
|
|
1692
|
+
if member.isreg():
|
|
1693
|
+
seen_files.add(normalized_name)
|
|
1694
|
+
expected_content = required_members.get(member.name)
|
|
1695
|
+
if expected_content is None:
|
|
1696
|
+
continue
|
|
1697
|
+
if member.name in seen_members:
|
|
1698
|
+
raise SystemExit(f"Duplicate root metadata member in sdist: {member.name}")
|
|
1699
|
+
seen_members.add(member.name)
|
|
1700
|
+
if not member.isreg():
|
|
1701
|
+
raise SystemExit(f"Root metadata member is not a regular file: {member.name}")
|
|
1702
|
+
if member.size > max_metadata_bytes or member.size != len(expected_content):
|
|
1703
|
+
raise SystemExit(f"Root metadata member has an unexpected size: {member.name}")
|
|
1704
|
+
member_file = archive.extractfile(member)
|
|
1705
|
+
if member_file is None or member_file.read(member.size + 1) != expected_content:
|
|
1706
|
+
raise SystemExit(f"Root metadata member does not match the release tag: {member.name}")
|
|
1707
|
+
except (OSError, tarfile.TarError) as error:
|
|
1708
|
+
raise SystemExit(f"Could not verify root sdist metadata: {error}") from error
|
|
1709
|
+
|
|
1710
|
+
if seen_members != set(required_members):
|
|
1711
|
+
missing = sorted(set(required_members) - seen_members)
|
|
1712
|
+
raise SystemExit(f"Root sdist is missing tagged metadata: {missing!r}")
|
|
1713
|
+
PY
|
|
1714
|
+
|
|
1715
|
+
- name: Generate recovery integrity attestation
|
|
1716
|
+
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
|
|
1717
|
+
with:
|
|
1718
|
+
subject-path: |
|
|
1719
|
+
dist/modelaudit-${{ needs.release-please.outputs.version }}-py3-none-any.whl
|
|
1720
|
+
dist/modelaudit-${{ needs.release-please.outputs.version }}.tar.gz
|
|
1721
|
+
predicate-type: https://promptfoo.dev/modelaudit/attestations/recovery/v1
|
|
1722
|
+
predicate: >-
|
|
1723
|
+
{"package":"modelaudit","version":"${{ needs.release-please.outputs.version }}","tag":"${{ needs.release-please.outputs.tag_name }}","source_run_id":"${{ needs.release-please.outputs.root_provenance_run_id }}","source_commit":"${{ steps.verify-source.outputs.source_head_sha }}","tag_commit":"${{ steps.verify-source.outputs.tag_commit_sha }}","pypi_json_url":"https://pypi.org/pypi/modelaudit/${{ needs.release-please.outputs.version }}/json"}
|
|
1724
|
+
|
|
1725
|
+
- name: Install uv
|
|
1726
|
+
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
1727
|
+
with:
|
|
1728
|
+
enable-cache: true
|
|
1729
|
+
|
|
1730
|
+
- name: Generate SBOM from tagged root lockfile
|
|
1731
|
+
env:
|
|
1732
|
+
EXPECTED_VERSION: ${{ needs.release-please.outputs.version }}
|
|
1733
|
+
run: |
|
|
1734
|
+
uv export \
|
|
1735
|
+
--frozen \
|
|
1736
|
+
--no-dev \
|
|
1737
|
+
--preview-features sbom-export \
|
|
1738
|
+
--format cyclonedx1.5 \
|
|
1739
|
+
--output-file "dist/modelaudit-${EXPECTED_VERSION}.cdx.json" \
|
|
1740
|
+
> /dev/null
|
|
1741
|
+
echo "SBOM generated:"
|
|
1742
|
+
ls -la dist/*.cdx.json
|
|
1743
|
+
|
|
1744
|
+
- name: Upload recovered root artifacts to GitHub Release
|
|
1745
|
+
env:
|
|
1746
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
1747
|
+
ROOT_TAG: ${{ needs.release-please.outputs.tag_name }}
|
|
1748
|
+
run: |
|
|
1749
|
+
gh release view "$ROOT_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null
|
|
1750
|
+
gh release upload "$ROOT_TAG" dist/* \
|
|
1751
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
1752
|
+
--clobber
|
|
1753
|
+
|
|
1319
1754
|
picklescan-provenance:
|
|
1320
1755
|
if: needs.release-please.outputs.picklescan_release_created == 'true'
|
|
1321
1756
|
needs: [build-picklescan-package, publish-picklescan-pypi, release-please]
|
|
@@ -18,7 +18,7 @@ This repo publishes **two PyPI packages with independent versions**:
|
|
|
18
18
|
| `modelaudit` | `./` (root) | `pyproject.toml` + `uv.lock` | `CHANGELOG.md` |
|
|
19
19
|
| `modelaudit-picklescan` | `packages/modelaudit-picklescan/` | `pyproject.toml` + `Cargo.toml` | `packages/modelaudit-picklescan/CHANGELOG.md` |
|
|
20
20
|
|
|
21
|
-
Root `modelaudit` hard-requires `modelaudit-picklescan>=0.1.
|
|
21
|
+
Root `modelaudit` hard-requires `modelaudit-picklescan>=0.1.10,<0.2.0` — when the sibling crosses `0.2.0`, bump the constraint in the same PR or the next `modelaudit` release is uninstallable. Both packages are driven by a single `release-please` workflow (`.github/workflows/release-please.yml`) with components defined in `release-please-config.json` and current versions in `.release-please-manifest.json`. Full publishing details — trusted publishing, manual `workflow_dispatch` recovery (`root_version` / `picklescan_version`), and yank procedure — are in [`docs/agents/release-process.md`](docs/agents/release-process.md). For work inside the picklescan package, start from [`packages/modelaudit-picklescan/AGENTS.md`](packages/modelaudit-picklescan/AGENTS.md).
|
|
22
22
|
|
|
23
23
|
## Mission & Principles
|
|
24
24
|
|
|
@@ -5,14 +5,29 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.52](https://github.com/promptfoo/modelaudit/compare/v0.2.51...v0.2.52) (2026-07-22)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **cache:** retry transient identity barrier churn ([#1778](https://github.com/promptfoo/modelaudit/issues/1778)) ([72c8d22](https://github.com/promptfoo/modelaudit/commit/72c8d228876ef90f861ebdc58773dc3184d09548))
|
|
15
|
+
- **deps:** update GitPython to 3.1.51 ([#1774](https://github.com/promptfoo/modelaudit/issues/1774)) ([e9b331b](https://github.com/promptfoo/modelaudit/commit/e9b331b06cf0b48faa561493fb1a695fd9d3dc5c))
|
|
16
|
+
- **deps:** update pyasn1 to 0.6.4 ([#1772](https://github.com/promptfoo/modelaudit/issues/1772)) ([df81361](https://github.com/promptfoo/modelaudit/commit/df81361f6df8e10a22ac71f81ee2ca15f0fcc12a))
|
|
17
|
+
- **deps:** update setuptools to 83.0.0 ([#1773](https://github.com/promptfoo/modelaudit/issues/1773)) ([8c805ff](https://github.com/promptfoo/modelaudit/commit/8c805fff4a6edf5f913f2cf23c5e04dde6567b9c))
|
|
18
|
+
- harden GGUF/ZIP polyglot detection ([#1775](https://github.com/promptfoo/modelaudit/issues/1775)) ([665ed3a](https://github.com/promptfoo/modelaudit/commit/665ed3ab7c452f639c74e976c23ff0b92ea746d0))
|
|
19
|
+
- harden LZ4-compressed Joblib inspection ([#1776](https://github.com/promptfoo/modelaudit/issues/1776)) ([fac0ede](https://github.com/promptfoo/modelaudit/commit/fac0edee89427e05cff7d8dffec343c1140c7755)); thanks to @PowerliftLog for the report
|
|
20
|
+
- keep root-only release branches componentless ([#1766](https://github.com/promptfoo/modelaudit/issues/1766)) ([9b8c2ce](https://github.com/promptfoo/modelaudit/commit/9b8c2ce04388bc0b1d57d51d7cdad726ad27a9e6))
|
|
21
|
+
- **picklescan:** recognize uv bytes-encoded package overlays ([#1777](https://github.com/promptfoo/modelaudit/issues/1777)) ([e9910fa](https://github.com/promptfoo/modelaudit/commit/e9910fac59db6fe0d286504cc6b85ac380617e0a))
|
|
22
|
+
- recover root release provenance safely ([#1770](https://github.com/promptfoo/modelaudit/issues/1770)) ([1e0dcb6](https://github.com/promptfoo/modelaudit/commit/1e0dcb6e273a13aaa86f36a39b4586b0d2e3a97a))
|
|
23
|
+
- resolve CodeQL quality and logging findings ([#1769](https://github.com/promptfoo/modelaudit/issues/1769)) ([573bbd8](https://github.com/promptfoo/modelaudit/commit/573bbd859501147413b2804df09299dc749e3e0c))
|
|
24
|
+
|
|
8
25
|
## [0.2.51](https://github.com/promptfoo/modelaudit/compare/v0.2.50...v0.2.51) (2026-07-20)
|
|
9
26
|
|
|
10
27
|
### Bug Fixes
|
|
11
28
|
|
|
12
29
|
- recover root release build and PyPI smoke gates ([#1764](https://github.com/promptfoo/modelaudit/issues/1764)) ([fa350d9](https://github.com/promptfoo/modelaudit/commit/fa350d96d2e00e0d54c47f282b7f8e0f9660e077))
|
|
13
30
|
|
|
14
|
-
## [Unreleased]
|
|
15
|
-
|
|
16
31
|
## [0.2.50](https://github.com/promptfoo/modelaudit/compare/v0.2.49...v0.2.50) (2026-07-20)
|
|
17
32
|
|
|
18
33
|
### Security
|
|
@@ -2530,7 +2545,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
2530
2545
|
- **style**: improve code formatting and documentation standards (#12, #23)
|
|
2531
2546
|
- **fix**: improve core scanner functionality and comprehensive test coverage (#11)
|
|
2532
2547
|
|
|
2533
|
-
[unreleased]: https://github.com/promptfoo/modelaudit/compare/v0.2.
|
|
2548
|
+
[unreleased]: https://github.com/promptfoo/modelaudit/compare/v0.2.52...HEAD
|
|
2534
2549
|
[0.2.25]: https://github.com/promptfoo/modelaudit/compare/v0.2.24...v0.2.25
|
|
2535
2550
|
[0.2.24]: https://github.com/promptfoo/modelaudit/compare/v0.2.23...v0.2.24
|
|
2536
2551
|
[0.2.23]: https://github.com/promptfoo/modelaudit/compare/v0.2.22...v0.2.23
|
|
@@ -61,7 +61,7 @@ RUN pip install --no-cache-dir \
|
|
|
61
61
|
RUN pip install --no-cache-dir \
|
|
62
62
|
"torch>=2.13.0,<3.0" --index-url https://download.pytorch.org/whl/cpu
|
|
63
63
|
|
|
64
|
-
RUN pip install --no-cache-dir "setuptools>=
|
|
64
|
+
RUN pip install --no-cache-dir "setuptools>=83.0.0,<84"
|
|
65
65
|
|
|
66
66
|
ARG UID=10001
|
|
67
67
|
RUN adduser \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modelaudit
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.52
|
|
4
4
|
Summary: Static scanning library for detecting malicious code, potential backdoor indicators, and other security risks in ML model files
|
|
5
5
|
Project-URL: Repository, https://github.com/promptfoo/modelaudit
|
|
6
6
|
Project-URL: Homepage, https://github.com/promptfoo/modelaudit
|
|
@@ -27,7 +27,7 @@ Requires-Dist: defusedxml>=0.7.1
|
|
|
27
27
|
Requires-Dist: fsspec>=2025.5.1
|
|
28
28
|
Requires-Dist: gcsfs>=2025.5.1
|
|
29
29
|
Requires-Dist: huggingface-hub>=0.23.0
|
|
30
|
-
Requires-Dist: modelaudit-picklescan<0.2.0,>=0.1.
|
|
30
|
+
Requires-Dist: modelaudit-picklescan<0.2.0,>=0.1.10
|
|
31
31
|
Requires-Dist: msgpack<2.0,>=1.2.1
|
|
32
32
|
Requires-Dist: numpy<2.0,>=1.19.0; python_version == '3.10'
|
|
33
33
|
Requires-Dist: numpy<2.5,>=2.4.3; python_version == '3.11'
|
|
@@ -9,14 +9,16 @@ This repo is a monorepo with **two independently versioned PyPI packages**:
|
|
|
9
9
|
|
|
10
10
|
Both packages are driven by a single [release-please](https://github.com/googleapis/release-please) workflow (`.github/workflows/release-please.yml`) with two components declared in `release-please-config.json` and current versions pinned in `.release-please-manifest.json`.
|
|
11
11
|
|
|
12
|
-
The root `
|
|
12
|
+
The root release intentionally omits `package-name` and `component`. Release-please reads `project.name` from `pyproject.toml` for Python updates, while the empty branch component lets a root-only grouped Release PR match `release-please--branches--main` and keeps the existing `v{X.Y.Z}` tags. Restoring a non-empty `package-name` or `component` makes root-only releases look like a different component and silently skips publication after merge.
|
|
13
|
+
|
|
14
|
+
The root `modelaudit` wheel declares a **hard dependency** on `modelaudit-picklescan>=0.1.10,<0.2.0` in `pyproject.toml`. When the sibling version crosses `0.2.0`, the constraint must be bumped in the same PR.
|
|
13
15
|
|
|
14
16
|
## Normal flow
|
|
15
17
|
|
|
16
18
|
1. **Write Conventional Commits** — `feat:`, `fix:`, `docs:`, etc. Release-please uses these to compute the next version and the changelog entry.
|
|
17
19
|
2. **Merge to `main`** — release-please creates or updates a "Release PR" per changed component. Commits that only touch `packages/modelaudit-picklescan/` feed the picklescan component; everything else feeds the root component.
|
|
18
20
|
3. **Review and merge the Release PR** — release-please tags the release and the workflow runs the matching publish jobs:
|
|
19
|
-
- **For `modelaudit`** — `build` produces sdist+wheel → `publish-pypi` uploads via OIDC → `provenance` attests and uploads SBOM.
|
|
21
|
+
- **For `modelaudit`** — `build` produces sdist+wheel → `publish-pypi` uploads via OIDC → `verify-pypi` confirms the published package → `provenance` attests and uploads SBOM.
|
|
20
22
|
- **For `modelaudit-picklescan`** — `build-picklescan-package` matrix builds 5 native wheels (Linux x86_64, Linux aarch64, macOS arm64, macOS x86_64, Windows x64) + sdist → `publish-picklescan-pypi` uploads → `picklescan-provenance` attests.
|
|
21
23
|
- **When both release together** — the sibling package is published and verified on PyPI before the dependent root package is uploaded.
|
|
22
24
|
|
|
@@ -57,6 +59,16 @@ gh workflow run release-please.yml -f picklescan_version=<X.Y.Z>
|
|
|
57
59
|
|
|
58
60
|
The workflow's `Resolve manual release inputs` step flips `manual_release=true`, skips the release-please action, ensures the GitHub release exists (creating it if not), then feeds `release_created=true` / `picklescan_release_created=true` into the publish jobs. `uv build` always reads from `pyproject.toml` at the current `HEAD`, so the tagged commit must already contain the target version; dispatching a version that does not match what's in `HEAD` will fail the PyPI upload.
|
|
59
61
|
|
|
62
|
+
If root publication and PyPI verification succeeded but `provenance` was skipped or failed, do **not** re-run the publish path: PyPI filenames are immutable and a rebuilt artifact may not match the published bytes. Recover provenance from the original verified publish run instead:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
gh workflow run release-please.yml --ref main \
|
|
66
|
+
-f root_version=<X.Y.Z> \
|
|
67
|
+
-f root_provenance_run_id=<original-run-id>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This provenance-only path skips release creation, builds, and publication. It checks out the fully qualified `refs/tags/v<X.Y.Z>` ref, verifies that the source is a completed release-please push or manual run from this repository with successful `build`, `publish-pypi`, and `verify-pypi` jobs, and requires both the source run's immutable head commit and the checked-out tag commit to be ancestors of the protected `main` branch before downloading the original `dist` artifact. The tag must also be an ancestor of the source run; only `.github/workflows/release-please.yml` and `tests/test_release_workflow.py` may differ, including both sides of any rename, accommodating a release-build repair without allowing runtime source drift. This prevents a branch-dispatched workflow with fabricated release jobs or a moved tag from being signed as trusted. An overall `failure` conclusion is accepted so a failed `provenance` job can be recovered; cancelled, incomplete, or diverged source runs and tags are rejected. The wheel and sdist are hashed in bounded chunks and must exactly match the non-yanked PyPI SHA256 digests. The bounded sdist may contain only regular files and directories with safe paths; links, special files, duplicate paths, case or Unicode aliases, and file/directory conflicts are rejected, and it must contain exactly one `pyproject.toml` and `uv.lock` whose bytes match the tag. The workflow then generates a recovery-integrity attestation recording both immutable commits and an SBOM from the frozen lockfile, and uploads the files to the matching GitHub Release. The recovery attestation does **not** claim original SLSA build provenance; the original PyPI publish attestations remain the publisher record. The source run ID must be numeric, `root_version` must use `X.Y.Z`, and `picklescan_version` cannot be combined with this recovery mode.
|
|
71
|
+
|
|
60
72
|
## PyPI trusted publishing (first-time setup)
|
|
61
73
|
|
|
62
74
|
Both packages publish via PyPI [Trusted Publishing](https://docs.pypi.org/trusted-publishers/). The `publish-pypi` and `publish-picklescan-pypi` jobs both use environment `pypi` and `id-token: write` permissions. PyPI is configured with an **active trusted publisher** on each project, scoped to owner `promptfoo`, repository `modelaudit`, workflow `release-please.yml`, environment `pypi`.
|
|
@@ -13,6 +13,7 @@ This page shows which model formats work in base install and which require optio
|
|
|
13
13
|
| Format family | Common extensions | Base install | Optional dependency / extra |
|
|
14
14
|
| ------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
15
15
|
| Pickle family | `.pkl`, `.pickle`, `.dill` | Yes | `modelaudit[dill]` for broader dill compatibility |
|
|
16
|
+
| Joblib | `.joblib` | Yes (bounded raw and compressed pickle analysis) | `lz4` package optional only for LZ4-compressed `.joblib` payload decompression |
|
|
16
17
|
| PyTorch archive/binary | `.pt`, `.pth`, `.ckpt`, `.bin` | Yes (static archive/pickle checks) | `modelaudit[pytorch]` optional for broader Torch ecosystem tooling |
|
|
17
18
|
| NumPy | `.npy`, `.npz` | Yes | None |
|
|
18
19
|
| R serialized | `.rds`, `.rda`, `.rdata`, signature-valid renamed workspace files | Yes (static analysis only) | None |
|
|
@@ -931,7 +931,9 @@ class ScanResultsCache:
|
|
|
931
931
|
preliminary_change_token = initial_change_token
|
|
932
932
|
preliminary_ancestor_identity = initial_ancestor_identity
|
|
933
933
|
else:
|
|
934
|
-
|
|
934
|
+
last_change_error = ValueError(f"Cache identity barrier did not settle: {file_path}")
|
|
935
|
+
time.sleep(0.01)
|
|
936
|
+
continue
|
|
935
937
|
|
|
936
938
|
monitored_ancestor_identity = self._monitor_ancestor_identity(file_path, initial_ancestor_identity)
|
|
937
939
|
try:
|