fix: preserve ONNX external data in HF streaming#1635
Conversation
|
@codex review |
Performance BenchmarksCompared
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b7e346ab85
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…t08-onnx-external-data-streaming-20260610
|
@codex review |
|
Codex Review: Didn't find any major issues. 👍 ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
Codex Review: Didn't find any major issues. You're on a roll. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Additional pinned QA: |
|
Pinned XLM-R ONNX external_data QA on exact PR head Target:
Commands run: git fetch origin main
git fetch origin mdangelo/codex/hf-fp-t08-onnx-external-data-streaming-20260610
gh pr view 1635 --repo promptfoo/modelaudit --json headRefOid,headRefName,baseRefOid,mergeStateStatus,reviewDecision,url
PROMPTFOO_DISABLE_TELEMETRY=1 uv run python - <<'PY'
# HfApi().repo_info(repo_id, revision=revision, files_metadata=True)
# patch _list_repo_files_with_timeout -> (repo_files, revision, None)
# scan_model_streaming(download_model_streaming(url, cache_dir=None, max_size=2236000000,
# timeout_seconds=7200, scannable_extensions={'.onnx'}, scannable_scanner_ids={'onnx'}),
# timeout=7200, delete_after_scan=False, cache_enabled=False, scanners=['onnx'], skip_file_types=False)
PY
PROMPTFOO_DISABLE_TELEMETRY=1 uv run python - <<'PY'
# scan_model_directory_or_file('~/.cache/huggingface/hub/models--FacebookAI--xlm-roberta-large/snapshots/c23d21b0620b635a76227c604d44e43a9f0ee389/onnx',
# cache_enabled=False, scanners=['onnx'], skip_file_types=False)
PYTerminal outcomes:
Bounded-read evidence: the ONNX parent is parsed with Controls preserved: PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest -q tests/test_streaming_scan.py::test_scan_model_directory_hf_cache_onnx_external_data_uses_snapshot_alias tests/test_streaming_scan.py::test_scan_model_streaming_hf_onnx_external_data_sidecar_matches_local_directory tests/test_streaming_scan.py::test_scan_model_streaming_hf_onnx_missing_external_data_still_warns tests/test_streaming_scan.py::test_scan_model_streaming_hf_onnx_escaping_external_data_remains_cve tests/utils/sources/test_huggingface.py::TestModelDownloadStreaming::test_download_model_streaming_preserves_onnx_external_data_before_parent_yield tests/utils/sources/test_huggingface.py::TestModelDownloadStreaming::test_download_model_streaming_preserves_content_routed_renamed_onnx_external_data tests/utils/sources/test_huggingface.py::TestModelDownloadStreaming::test_download_model_streaming_include_all_counts_selected_onnx_sidecar_once tests/utils/sources/test_huggingface.py::TestModelDownloadStreaming::test_download_model_streaming_default_hf_cache_preserves_onnx_external_data_sidecar tests/utils/sources/test_huggingface.py::TestModelDownloadStreaming::test_download_model_streaming_does_not_fetch_escaping_onnx_external_data tests/utils/sources/test_huggingface.py::TestModelDownloadStreaming::test_download_model_streaming_blocks_oversized_onnx_external_data
# 10 passed
PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest -q tests/scanners/test_onnx_scanner.py::test_onnx_scanner_external_data_missing tests/scanners/test_onnx_scanner.py::test_onnx_scanner_external_data_exists tests/scanners/test_onnx_scanner.py::TestCVE202551480SavePathTraversal tests/scanners/test_onnx_scanner.py::TestCVE202634447SymlinkTraversal tests/scanners/test_onnx_scanner.py::TestCVE202427318NestedPathTraversal tests/scanners/test_onnx_scanner.py::TestExternalDataSizeValidation
# 44 passed
PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest -q tests/test_streaming_scan.py::test_scan_model_streaming_keeps_hf_snapshot_symlink_families_separate tests/test_streaming_scan.py::test_cross_directory_shard_reconciliation_rejects_sequential_hardlinks tests/test_streaming_scan.py::test_scan_model_streaming_does_not_reconcile_duplicate_shard_targets tests/test_streaming_scan.py::test_scan_model_streaming_symlink_outside_directory_matches_normal_scan tests/test_streaming_scan.py::test_scan_model_streaming_symlink_outside_directory_without_safe_files_returns_security_exit_code tests/test_streaming_scan.py::test_scan_model_streaming_hf_cache_symlink_allowed tests/test_streaming_scan.py::test_scan_model_streaming_hf_home_cache_symlink_allowed tests/test_streaming_scan.py::test_scan_model_streaming_symlink_reports_source_path_consistently tests/test_streaming_scan.py::test_scan_model_streaming_hf_cache_symlink_reports_snapshot_path tests/test_streaming_scan.py::test_scan_model_streaming_oversized_renamed_safetensors_fails_before_hashing tests/utils/file/test_advanced_file_handler.py::TestShardedModelDetector::test_validated_shard_target_mapping_rejects_alias_swap tests/utils/file/test_advanced_file_handler.py::TestShardedModelDetector::test_shard_target_swap_after_detection_fails_closed tests/utils/file/test_advanced_file_handler.py::TestShardedModelDetector::test_shard_target_swap_during_scan_discards_clean_result tests/utils/file/test_advanced_file_handler.py::TestShardedModelDetector::test_shard_target_swap_during_scan_preserves_security_findings tests/utils/file/test_advanced_file_handler.py::TestShardedModelDetector::test_sharded_model_rejects_config_symlink_swap_without_nofollow tests/utils/file/test_advanced_file_handler.py::TestAdvancedFileHandler::test_duplicate_hardlinked_shard_family_members_are_not_cacheable
# 16 passed
PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest -q tests/test_streaming_scan.py tests/scanners/test_onnx_scanner.py tests/utils/sources/test_huggingface.py
# 604 passed, 1 skipped, 1 warning
uv run ruff check modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
# All checks passed
uv run ruff format --check modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
# 419 files already formatted
uv run mypy modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
# Success: no issues found in 474 source files
git diff --check
# clean@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7975772a51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
CI diagnosis for current head |
|
@codex review Fresh exact-head review requested for commit |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4ed5fd23b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fresh exact-head review requested for commit |
|
Codex Review: Didn't find any major issues. 🚀 ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review CI is green on head |
|
Codex Review: Didn't find any major issues. Keep it up! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8411e1104f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 500064663d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: efdd9159d7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a8f5c676d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…t08-onnx-external-data-streaming-20260610 # Conflicts: # modelaudit/core.py # tests/test_streaming_scan.py
…t08-onnx-external-data-streaming-20260610 # Conflicts: # modelaudit/utils/sources/huggingface.py
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f81171fb9b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…t08-onnx-external-data-streaming-20260610 # Conflicts: # modelaudit/utils/sources/huggingface.py # tests/utils/sources/test_huggingface.py
…t08-onnx-external-data-streaming-20260610
…t08-onnx-external-data-streaming-20260610
…t08-onnx-external-data-streaming-20260610
…t08-onnx-external-data-streaming-20260610
…t08-onnx-external-data-streaming-20260610
…t08-onnx-external-data-streaming-20260610 # Conflicts: # modelaudit/utils/sources/huggingface.py
…t08-onnx-external-data-streaming-20260610
…t08-onnx-external-data-streaming-20260610 # Conflicts: # modelaudit/core.py # tests/test_streaming_scan.py
…t08-onnx-external-data-streaming-20260610 # Conflicts: # modelaudit/utils/sources/huggingface.py
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f9ff39421e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…t08-onnx-external-data-streaming-20260610
…t08-onnx-external-data-streaming-20260610 # Conflicts: # tests/test_streaming_scan.py
Summary
external_datacompanions during Hugging Face streaming downloads.load_external_data=False, require repo-listing membership, and keep them beside the parent until the parent scan completes.Root Cause
HF streaming selected files by scanner-owned suffix/content routing.
BAAI/bge-m3declaresonnx/model.onnx_datafromonnx/model.onnx, but.onnx_datais not a scanner extension, so streaming downloaded onlymodel.onnx. The ONNX scanner then resolved the declared sidecar relative to the streamed temp path and reported a false missing-external-data warning. Local scans did not warn because the sibling file was present.Security Tradeoffs
OnnxScannerstill sees the original model metadata and reports the existing CVE/missing checks.max_sizebefore download, then verified after materialization.Pinned BGE-M3 QA
Pinned revision:
BAAI/bge-m3@5617a9f61b028005a4858fdac845db406aefb181.Pre-fix confirmation on the pinned main SHA
2f782ba1f18ab5aac4716c8c7ac6f0a16f0c6f60:Outcome: streaming scanned only
onnx/model.onnx(724923bytes), exited1, and emittedExternal data reference found (file may not be present): 'model.onnx_data' (389 tensors affected).Post-fix live test:
Outcome:
1 passed in 14.34s.Post-fix streaming/local comparison script outcome:
The remaining exit
2is the existing ONNX weight-distribution coverage outcome and now matches local behavior; the missing-sidecar warning is gone.Validation
Outcomes: focused suites passed; full mypy passed (
474 source files); full non-slow/non-integration pytest passed (18065 passed, 793 skipped, 31 warnings in 780.49s); Ruff and diff checks passed.Follow-up Validation (4ed5fd2)
Resolved the three follow-up P2 threads:
downloaded_selected_paths, so they are not re-downloaded or counted twice under an exactmax_sizebudget..onnxsnapshot aliases now keep scan identity by snapshot context, while ordinary non-sharded HF cache aliases still scan and dedupe by blob path.snapshots/<revision>/...aliases for the same cache root/revision; arbitrary directories undermodels--*retain CVE-2026-34447 checks.Pinned XLM-R streaming/local QA:
Additional validation:
Follow-up Validation (da12fe6)
snapshots/<revision>/...symlink leaves; symlinked parent directories intoblobsnow retain CVE-2026-34447 coverage.delete_after_scan=Trueremoved them before the parent ONNX scan, without double-counting the exact selected-file max-size budget.ruff check --fix,ruff format --check,mypy,git diff --check, andPROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest -n auto -m "not slow and not integration" --maxfail=1(18556 passed, 793 skipped).Final-head pinned XLM-R QA (
da12fe667b743bad11e09caf5976ad7ad1291b84):FacebookAI/xlm-roberta-large@c23d21b0620b635a76227c604d44e43a9f0ee389, exact budget2235909178bytes. Streaming summary:files_scanned=1,bytes_scanned=545850,passed_external=1,failed_external=0,size_failures=0,cves=[],exit=2only from existing fail-closed weight coverage. Local snapshot summary:files_scanned=2,bytes_scanned=2235909178,passed_external=1,failed_external=0,size_failures=0,cves=[],exit=2for the same coverage reason. Resource evidence:elapsed_seconds=16.87,ru_maxrss_kb=154384, far below the 2.235 GB sidecar size.