Skip to content

fix: paginate large Hugging Face inventories - #1659

Merged
mldangelo-oai merged 16 commits into
mainfrom
mdangelo/codex/hf-fp-t32-hf-large-inventory-pagination-20260610
Jun 12, 2026
Merged

mldangelo-oai merged 16 commits into
mainfrom
mdangelo/codex/hf-fp-t32-hf-large-inventory-pagination-20260610

Conversation

@mldangelo-oai

Copy link
Copy Markdown
Contributor

Summary

Fixes ModelAudit false-positive task 32 by replacing the hard include_all_files streaming failure above 128 unfiltered Hugging Face candidates with a bounded, deterministic, revision-pinned repository inventory.

Root cause: default/header-routed Hugging Face streaming uses include_all_files=True; _select_streamable_hf_files() counted every unknown or extensionless filename against _MAX_HF_STREAMING_UNFILTERED_FILES = 128 and raised before any scan or aggregate size accounting. The pinned xai-org/grok-1 revision declares 773 files, so it failed before reaching a truthful bounded terminal outcome.

Security tradeoffs

  • Inventory is now fetched from the Hugging Face tree API at an immutable resolved commit SHA, across all pages, before any download starts.
  • Repository filenames are validated, deduplicated, sorted deterministically, and bounded by explicit inventory/page caps.
  • The old unfiltered 128-file abort is removed only after inventory acceptance; extensionless candidate caps, content-sniff file/byte caps, scanner selection filters, and no-scannable fail-closed behavior remain intact.
  • Selected-file size metadata is batched and conflict-checked before transfer, preserving aggregate --max-size enforcement for large selections.
  • Malformed/truncated/unstable paginated inventories fail closed before download rather than producing partial clean coverage.

Pinned real-model QA

Pre-fix proof on exact main SHA 8d6c4864fe2ea833ceaef1b9803d225afb1e8d69:

HF_HUB_DISABLE_IMPLICIT_TOKEN=1 PROMPTFOO_DISABLE_TELEMETRY=1 uv run python - <<'PY'
from huggingface_hub import HfApi
from modelaudit.utils.sources.huggingface import _select_streamable_hf_files
repo_id = "xai-org/grok-1"
revision = "5de83eb225f49624b424f1c8aa74f96983b5885c"
files = HfApi().list_repo_files(repo_id, repo_type="model", revision=revision)
print("declared_files", len(files))
try:
    _select_streamable_hf_files(repo_id, files, revision, include_all_files=True)
except Exception as exc:
    print(type(exc).__name__, str(exc))
PY

Outcome before fix: declared_files 773; Refusing to stream-download unfiltered files ... bounded unfiltered candidate limit (128).

Post-fix selector proof:

HF_HUB_DISABLE_IMPLICIT_TOKEN=1 PROMPTFOO_DISABLE_TELEMETRY=1 uv run python - <<'PY'
from huggingface_hub import HfApi
from modelaudit.utils.sources.huggingface import _select_streamable_hf_files
repo_id = "xai-org/grok-1"
revision = "5de83eb225f49624b424f1c8aa74f96983b5885c"
files = HfApi().list_repo_files(repo_id, repo_type="model", revision=revision)
selected = _select_streamable_hf_files(repo_id, files, revision, include_all_files=True)
print("declared_files", len(files))
print("selected_stream_files", len(selected))
PY

Outcome after fix: declared_files 773; selected_stream_files 773.

Post-fix all-format bounded planning proof:

HF_HUB_DISABLE_IMPLICIT_TOKEN=1 PROMPTFOO_DISABLE_TELEMETRY=1 uv run python - <<'PY'
from modelaudit.utils.sources.huggingface import (
    _ensure_huggingface_selection_within_max_size,
    _list_huggingface_repo_files_at_revision,
    _select_streamable_hf_files,
)
repo_id = "xai-org/grok-1"
revision = "5de83eb225f49624b424f1c8aa74f96983b5885c"
files, resolved_revision = _list_huggingface_repo_files_at_revision(repo_id, requested_revision=revision, timeout_seconds=30)
selected = _select_streamable_hf_files(repo_id, files, resolved_revision, include_all_files=True)
print("declared_files", len(files))
print("selected_stream_files", len(selected))
try:
    _ensure_huggingface_selection_within_max_size(repo_id, selected, 10 * 1024, resolved_revision=resolved_revision)
except Exception as exc:
    print("terminal_outcome", type(exc).__name__, str(exc))
PY

Outcome: declared_files 773; selected_stream_files 773; terminal outcome is an aggregate max-size refusal at 3221229327 bytes > 10240 bytes, before downloading weights.

Metadata-only real streaming test:

HF_HUB_DISABLE_IMPLICIT_TOKEN=1 PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest tests/utils/sources/test_huggingface.py::TestModelDownloadStreaming::test_pinned_grok_large_inventory_metadata_streaming_reaches_terminal -q

Outcome: 1 passed; fetched the pinned 773-file inventory and downloaded only README.md under a 10KB cap.

Validation

PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest tests/utils/sources/test_huggingface.py -q -m 'not integration'
# 278 passed, 1 skipped, 1 deselected

PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest tests/test_scanner_selection.py -q
# 42 passed, 2 skipped

PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest tests/test_streaming_scan.py -q
# 80 passed

PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest tests/test_cli.py -q -k 'huggingface or stream'
# 43 passed, 214 deselected

uv run ruff format modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
uv run ruff check --fix modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
uv run mypy modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
# Success: no issues found in 474 source files

PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest -n auto -m "not slow and not integration" --maxfail=1
# 17377 passed, 1292 skipped, 39 warnings

uv run ruff check modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
uv run ruff format --check modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/
git diff --check

Malformed controls added

  • Duplicate paginated names dedupe deterministically.
  • Traversal, absolute, empty-component, backslash, and NUL/control filenames fail closed.
  • Repeated pagination cursors fail closed.
  • Later page failures/truncation fail closed before download.
  • Excessive inventory totals fail closed via explicit bounds.
  • Conflicting duplicate selected-file size metadata fails closed before transfer.
  • Existing extensionless and renamed-content probe caps remain covered.

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@github-actions

github-actions Bot commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

Workflow run and artifacts

Performance Benchmarks

Compared 12 shared benchmarks with a regression threshold of 15%.
Status: 0 regressions, 0 improved, 12 stable, 0 new, 0 missing.
Aggregate shared-benchmark median: 1.461s -> 1.468s (+0.5%).

Workload Benchmark Target Size Files Baseline Current Change Status
warm-cache-rescan tests/benchmarks/test_scan_benchmarks.py::test_scan_warm_cached_repository_rescan release-candidate 547.3 KiB 32 128.30ms 123.27ms -3.9% stable
single-checkpoint-preflight tests/benchmarks/test_scan_benchmarks.py::test_scan_single_checkpoint_before_load single_checkpoint.pkl 183.0 KiB 1 74.39ms 71.90ms -3.3% stable
mixed-model-repository tests/benchmarks/test_scan_benchmarks.py::test_scan_release_candidate_repository release-candidate 547.3 KiB 32 490.01ms 499.17ms +1.9% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_base64] nested_base64 98 B 1 592.9us 600.8us +1.3% stable
duplicate-heavy-registry tests/benchmarks/test_scan_benchmarks.py::test_scan_duplicate_registry_snapshot registry-snapshot 915.2 KiB 13 398.22ms 401.98ms +0.9% stable
clean-training-checkpoint tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_clean_training_checkpoint safe_large 278.2 KiB 1 109.26ms 110.20ms +0.9% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_hex] nested_hex 130 B 1 620.9us 624.8us +0.6% stable
suspicious-pickle-intake tests/benchmarks/test_scan_benchmarks.py::test_scan_suspicious_pickle_intake suspicious-intake 183.8 KiB 4 144.50ms 145.30ms +0.6% stable
nested-payload-review tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_nested_payload_review[nested_raw] nested_raw 78 B 1 596.3us 594.6us -0.3% stable
direct-malicious-upload tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_direct_malicious_upload malicious_reduce 52 B 1 528.0us 527.1us -0.2% stable
padded-multi-stream-upload tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_padded_multi_stream_upload multi_stream_padded 4.1 KiB 1 649.1us 650.1us +0.1% stable
chunked-upload-stream tests/benchmarks/test_picklescan_benchmarks.py::test_picklescan_chunked_upload_stream chunked_stream 278.2 KiB 1 113.14ms 113.13ms -0.0% stable

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

ℹ️ 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".

Comment thread tests/utils/sources/test_huggingface.py Fixed
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 713877a765

ℹ️ 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".

Comment thread modelaudit/utils/sources/huggingface.py Outdated
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

ℹ️ 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".

Copy link
Copy Markdown
Contributor Author

Independent exact-head review of 45f27835c186f09266e7da415aec3b10ee5834db: request changes.

P1: _extract_huggingface_tree_page_files() silently skips every item whose type is not exactly file. A page containing benign.bin plus {"type":"unexpected","path":"malicious.pkl"} is accepted as a complete inventory containing only benign.bin. Missing/unknown types can therefore omit a malicious artifact while the remaining repository scans clean.

Explicitly accept known directory item types, validate file, and fail closed on missing/unknown types before any download. Add missing/unknown/new-type regressions. The pagination, immutable revision, duplicate, size metadata, and pinned 773-file inventory behavior otherwise validated successfully.

Full report: modelaudit-pr-swarm/outputs/pr-1659-independent-review-20260611.md.

@codex fix the type handling, add regressions, push, and request exact-head review after CI.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45f27835c1

ℹ️ 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".

Comment thread modelaudit/utils/sources/huggingface.py Outdated
@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ 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".

@mldangelo-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

ℹ️ 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".

@mldangelo-oai
mldangelo-oai requested a review from mldangelo June 11, 2026 07:20
@mldangelo-oai
mldangelo-oai enabled auto-merge (squash) June 11, 2026 07:20
…t32-hf-large-inventory-pagination-20260610

# Conflicts:
#	modelaudit/utils/sources/_huggingface_download_worker.py
#	modelaudit/utils/sources/huggingface.py
#	tests/utils/sources/test_huggingface.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51c35a0008

ℹ️ 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".

Comment thread modelaudit/utils/sources/huggingface.py
Comment thread modelaudit/utils/sources/huggingface.py
…t32-hf-large-inventory-pagination-20260610

# Conflicts:
#	modelaudit/utils/sources/huggingface.py
@mldangelo-oai
mldangelo-oai merged commit e393dc0 into main Jun 12, 2026
29 checks passed
@mldangelo-oai
mldangelo-oai deleted the mdangelo/codex/hf-fp-t32-hf-large-inventory-pagination-20260610 branch June 12, 2026 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant