Skip to content

release: bound sdist and wheel verifier member enumeration - #216

Draft
seonghobae wants to merge 9 commits into
mainfrom
release/bound-sdist-verifier-main-7faf
Draft

release: bound sdist and wheel verifier member enumeration#216
seonghobae wants to merge 9 commits into
mainfrom
release/bound-sdist-verifier-main-7faf

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Purpose

Bound release-package verification before attacker-controlled archive member metadata can be retained without limit. The verifier now applies finite member-count and metadata boundaries to both supported distribution formats while preserving exact package integrity checks.

Protected-base identity

  • target: main;
  • exact protected base: 7faf7a3b8a47980113982914000e724ab6a6cda5;
  • exact current head: 7254db0217034890e7500f54492110938f843dae.

Implemented boundary

Source distributions

  • replace TarFile.getmembers() with streaming member iteration;
  • reject the member that would exceed _MAX_DISTRIBUTION_MEMBERS before retaining it;
  • keep only bounded metadata required for final root, path, type, required-file, size, and checksum checks.

Wheels

  • preflight the EOCD and central-directory member count before ZipFile construction;
  • reject ZIP64 rather than accepting an unbounded metadata path;
  • recognize a ZIP64 locator only in its exact structural slot, not merely because the same signature bytes occur inside a legal archive comment;
  • verify the post-construction member count matches the preflight count;
  • preserve every existing path, symlink, size, archive-size, checksum, metadata, and content check.

Test-first lineage

sdist RED → GREEN

  • 266eb7fff5ab01c0d8eca1b57e1c5cc45330dddb: initial regression exposing unbounded sdist member enumeration;
  • d2c3750cb3de43049d4c50ddf88cf922f8434feb: strengthened RED contract requiring bounded tar metadata retention;
  • 7f5ece53338a222e2b2e99fe618e0282782648eb: streaming bounded sdist implementation.

wheel RED → GREEN and structural hardening

  • 89d99625b79e8a32833250ec9e2271d5ef9ec45a: RED regression requiring member-count preflight before ZipFile construction;
  • a6f1bea8b410a19fc3a9f87e0244c6b7826de6c1: bounded wheel central-directory preflight;
  • 9891b1d9cc75e4e47cf58a71c2d4a36b39050a37: regression permitting ZIP64 signature bytes inside legal comments;
  • d8795dede7a74ff7fd60f938c556a8c726d6635a: exact-slot ZIP64 locator recognition;
  • 1a1e56e82afe65ac642097056c825a786a4f5dcd: archive-comment boundary regression;
  • 7254db0217034890e7500f54492110938f843dae: final distinction between wheel comments and ZIP64 locators.

Cancelled or superseded runs are retained as development history only and are not passing evidence.

Exact-head verification

Exact head 7254db0217034890e7500f54492110938f843dae:

  • CI succeeded on Python 3.10, 3.11, 3.12, 3.13, and 3.14;
  • Python 3.14.6 lane: 1,033 tests passed;
  • production coverage: 1,758 / 1,758 statements and 588 / 588 branches (100%);
  • Ruff, compileall, hourly product-guard self-test, wheel/sdist build, archive verification, and installed-wheel smoke test succeeded;
  • current-head SAST Semgrep succeeded;
  • the Security Scan wrapper succeeded, but its actual pinned Dependency Review action was skipped and is therefore not accepted as substantive supply-chain evidence.

Merge contract

Keep Draft. Do not merge until:

  1. the central dependency-review fail-closed repair in ContextualWisdomLab/.github#897 is integrated and a fresh exact-head scan executes the actual pinned Dependency Review action;
  2. the central Strix evidence repair in ContextualWisdomLab/.github#965 is integrated and produces authoritative exact-head evidence;
  3. current-head CodeRabbit/OpenCode/Noema review findings are resolved and qualifying formal approvals exist;
  4. every required exact-head check is terminal and substantively passing; and
  5. exact head, live base, ancestry, reviews, threads, and rulesets are revalidated immediately before normal protected merge.

Non-goals

  • no archive extraction;
  • no runtime egress behavior change;
  • no new dependency or publication credential;
  • no repository-local substitute for organization-owned supply-chain or reviewer authority.

Closes #215. Progresses #217.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9bc5b44b-b0f5-4b45-bde8-f09e1b499c67

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae seonghobae changed the title release: bound sdist verifier member enumeration release: bound sdist and wheel verifier member enumeration Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review exact head 7254db0217034890e7500f54492110938f843dae, including the sdist/wheel RED→GREEN lineage, ZIP64 exact-slot handling, archive-comment boundary, and 1,033-test / 100% statement-and-branch evidence.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review exact head 7254db0217034890e7500f54492110938f843dae and submit a formal verdict on bounded tar/ZIP metadata retention, EOCD/ZIP64 structural validation, and package-integrity preservation.

Copy link
Copy Markdown
Contributor Author

@cwl-noema-review independently review exact head 7254db0217034890e7500f54492110938f843dae after a qualifying primary verdict and submit a formal current-head decision.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='7faf7a3b8a47980113982914000e724ab6a6cda5'
head='7254db0217034890e7500f54492110938f843dae'

echo '== Checkout and ancestry =='
git rev-parse HEAD
git cat-file -t "$base"
git cat-file -t "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'
git diff --stat "$base" "$head"
echo
echo '== Changed files =='
git diff --name-status "$base" "$head"
echo
echo '== Commit lineage =='
git log --oneline --reverse "$base..$head"
echo
echo '== Changed Python outlines =='
git diff --name-only "$base" "$head" -- '*.py' | while IFS= read -r f; do
  [ -n "$f" ] || continue
  echo "--- $f"
  ast-grep outline "$f" --items all --type function,class --view compact || true
done
echo
echo '== Archive-related implementation and test references =='
rg -n -C 5 --glob '*.py' \
  '(_MAX_DISTRIBUTION_MEMBERS|TarFile|getmembers|ZipFile|ZIP64|zip64|EOCD|central.directory|central_directory|comment|infolist|member)' \
  .
echo
echo '== Exact modified hunks =='
git diff --unified=80 "$base" "$head" -- '*.py'
echo
echo '== GitHub PR metadata and exact-head check runs =='
gh pr view 216 --repo ContextualWisdomLab/EgressWeave \
  --json number,state,isDraft,baseRefOid,headRefOid,commits,reviews,statusCheckRollup \
  --jq '{number,state,isDraft,baseRefOid,headRefOid,commits:[.commits[]|{oid:.oid,messageHeadline:.messageHeadline}],reviews:[.reviews[]|{author:.author.login,state:.state,submittedAt:.submittedAt}],checks:[.statusCheckRollup[]|{name:.name,status:.status,conclusion:.conclusion,startedAt:.startedAt,completedAt:.completedAt}]}'

Length of output: 185064


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='7faf7a3b8a47980113982914000e724ab6a6cda5'
head='7254db0217034890e7500f54492110938f843dae'
repo='ContextualWisdomLab/EgressWeave'

echo '== Focused verifier implementation =='
sed -n '250,480p' scripts/ci/verify_distribution.py
echo
echo '== Focused new regression tests =='
sed -n '1,220p' tests/test_distribution_verifier_wheel_member_bound.py
sed -n '1,160p' tests/test_distribution_verifier_sdist_member_bound.py
echo
echo '== Post-construction count checks and preflight consumers =='
rg -n -C 4 --glob '*.py' \
  '(_preflight_wheel_members\s*\(|len\(.*(?:namelist|infolist)|len\(names\)|actual_entries|total_entries)' \
  scripts/ci/verify_distribution.py tests
echo
echo '== Requested RED-to-GREEN patches =='
for commit in \
  266eb7fff5ab01c0d8eca1b57e1c5cc45330dddb \
  d2c3750cb3de43049d4c50ddf88cf922f8434feb \
  7f5ece53338a222e2b2e99fe618e0282782648eb \
  89d99625b79e8a32833250ec9e2271d5ef9ec45a \
  a6f1bea8b410a19fc3a9f87e0244c6b7826de6c1 \
  9891b1d9cc75e4e47cf58a71c2d4a36b39050a37 \
  d8795dede7a74ff7fd60f938c556a8c726d6635a \
  1a1e56e82afe65ac642097056c825a786a4f5dcd \
  7254db0217034890e7500f54492110938f843dae
do
  echo "--- $commit"
  git show --format='%H%n%s' --stat --oneline "$commit"
  git show --format= --unified=20 "$commit" -- scripts/ci/verify_distribution.py tests
done
echo
echo '== Exact-head workflow runs =='
gh run list --repo "$repo" --commit "$head" --limit 100 \
  --json databaseId,name,workflowName,status,conclusion,event,createdAt,updatedAt,url \
  --jq '.[] | select(.status == "completed") | {databaseId,workflowName,name,conclusion,createdAt,updatedAt,url}'
echo
echo '== Exact-head PR check details =='
gh pr checks 216 --repo "$repo" --json name,state,workflow,link,completedAt,bucket \
  --jq '.[] | {name,state,workflow,completedAt,link}'

Length of output: 96000


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/EgressWeave'
run='31692030018'
ci_run='31692030893'
security_run='31692030938'

echo '== Coverage-evidence job log matches =='
gh run view "$run" --repo "$repo" --job '94434931789' --log 2>&1 \
  | rg -n -i -C 3 '(1033|1,033|1758|1,758|588|coverage|statement|branch|passed|fail)' \
  || true
echo
echo '== Source-tree coverage job log matches =='
gh run view "$run" --repo "$repo" --job '94427619008' --log 2>&1 \
  | rg -n -i -C 3 '(1033|1,033|1758|1,758|588|coverage|statement|branch|passed|fail)' \
  || true
echo
echo '== Python 3.14 test job log matches =='
gh run view "$ci_run" --repo "$repo" --job '94421261334' --log 2>&1 \
  | rg -n -i -C 3 '(1033|1,033|passed|failed|coverage|statement|branch)' \
  || true
echo
echo '== Build and distribution-verification job log matches =='
gh run view "$ci_run" --repo "$repo" --job '94421261203' --log 2>&1 \
  | rg -n -i -C 3 '(verify_distribution|wheel|sdist|compileall|ruff|passed|fail)' \
  || true
echo
echo '== Dependency-review job log matches =='
gh run view "$security_run" --repo "$repo" --job '94421261527' --log 2>&1 \
  | rg -n -i -C 4 '(dependency.review|dependency-review|actions/dependency-review|skipp|pin|success|fail)' \
  || true
echo
echo '== Security Scan job definitions =='
gh run view "$security_run" --repo "$repo" --json jobs \
  --jq '.jobs[] | select(.databaseId == 94421261527) | {name,conclusion,startedAt,completedAt,steps:[.steps[]|{name,conclusion,status}]}'

Length of output: 74697


@seonghobae, I reviewed exact head 7254db0217034890e7500f54492110938f843dae.

Finding

P2 — Verify the ZipFile member count after preflight.

At Line 441, _verify_wheel() calls _preflight_wheel_members(). The preflight scans the complete central directory and verifies actual_entries == total_entries. It then returns only the optional member-comment mask offset.

At Line 451, ZipFile constructs its own member list. The verifier checks member names and required paths, but it does not compare len(wheel_archive.infolist()) with the preflight count.

This leaves the custom ZIP parser and the stdlib ZIP parser unbound. If they accept different member counts, verification can continue without detecting that disagreement. The stated wheel contract requires a post-construction count check.

Return the bounded preflight count with the optional mask offset. Then reject if len(wheel_archive.infolist()) differs from that count. Add a regression test that simulates a post-construction count mismatch and requires fail-closed rejection.

Verified items

  • The checked-out head equals the requested SHA. The protected base is an ancestor.
  • The nine commits provide the requested sdist and wheel RED→GREEN lineage.
  • The sdist path uses streaming tarfile iteration. It rejects the first member above MAX_SDIST_MEMBERS and clears the TarFile.members cache.
  • The wheel path performs bounded EOCD and central-directory preflight before ZipFile construction.
  • ZIP64 locator recognition requires the exact EOCD-adjacent slot and a consistent ZIP64 end record.
  • A locator-shaped final member comment is handled in a parser-only snapshot. The original archive digest remains unchanged.
  • The Python 3.14.6 job checked out the exact SHA and reported 1033 passed in 5.39s.
  • The build job checked out the exact SHA, built both distributions, ran verify_distribution.py, and completed the installed-wheel smoke test.
  • Python 3.10 through 3.14, Semgrep, and the listed exact-head checks completed successfully.

The aggregate 1,758 / 1,758 statement and 588 / 588 branch totals were not independently retrievable. The delegated coverage workflow endpoint returned HTTP 404. The dependency-review delegated workflow endpoint also returned HTTP 404. Therefore, I cannot treat the substantive Dependency Review execution as verified.

Verdict: changes requested.

You are interacting with an AI system.

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Current-head source review for 7254db0217034890e7500f54492110938f843dae found no blocking defect in the three-file archive-enumeration scope. The implementation preflights a bounded single-disk/non-ZIP64 central directory before ZipFile construction, keeps sdist enumeration streaming with a finite member ceiling, preserves duplicate/unsafe-path and unsupported-entry rejection, and covers exact-slot ZIP64-signature comment regressions. This is author-side review evidence only, not an independent approval. Keep Draft until the actual pinned Dependency Review action executes successfully under the corrected central workflow, authoritative exact-head Strix and independent review evidence exist, and the release-history writer lane is reconciled without losing unrelated [Unreleased] entries.

Copy link
Copy Markdown
Contributor Author

@cwl-noema-review review

Review exact current head 7254db0217034890e7500f54492110938f843dae against protected main@7faf7a3b8a47980113982914000e724ab6a6cda5. Validate the bounded streaming sdist member admission, pre-ZipFile wheel central-directory count/framing checks, exact structural ZIP64-locator distinction, parser-snapshot masking, preserved package metadata/path/link/size/digest contracts, and all finite-resource failure paths. Submit a formal independent verdict only for this head. Do not mutate, merge, or infer acceptance from wrapper-green Dependency Review.

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.

release: bound sdist member enumeration in distribution verifier

1 participant