Skip to content

fix(ga): pre-publish wheel-import guard for sdk-python + repair stale isolation marker - #84

Open
yakimoto wants to merge 2 commits into
mainfrom
fix/cleanroom-registry-defects
Open

fix(ga): pre-publish wheel-import guard for sdk-python + repair stale isolation marker#84
yakimoto wants to merge 2 commits into
mainfrom
fix/cleanroom-registry-defects

Conversation

@yakimoto

@yakimoto yakimoto commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Tracking: claude-workstation#4321 item 6 — fix the SOURCE causes of the wave-av/sdks registry clean-room acceptance failures (run 33933317710, 7 checks failing across 6 published artifacts).

Finding, independently re-verified in this lane (not taken on trust from existing docs): all 7 failing checks were already root-cause fixed in source before this PR, spread across three repositories, and every one is blocked solely on an operator-triggered publish this lane may not perform:

# Check Root cause Where it's fixed Status
1 @wave-av/cli npm-provenance-attested release.yml already runs npm publish --provenance under id-token: write OIDC wave-av/cli origin/main (verified: .github/workflows/release.yml) different repo — nothing to change here; pending publish
2 @wave-av/cli bin-version-matches-package src/lib/version.ts derives CLI_VERSION from package.json at runtime instead of a hardcoded literal wave-av/cli origin/main (verified directly) different repo — nothing to change here; pending publish
3 @wave-av/cli declared-dep-ranges-pinned @wave-av/sdk pinned to exact 2.0.14 (was ^2.0.11) wave-av/cli package.json on origin/main (verified directly) different repo — nothing to change here; pending publish
4,6 wave-sdk (PyPI) py-import-module / py-no-stdlib-shadow top-level module renamed wavewave_sdk wave-av/sdk-python origin/main, version 2.1.0 (verified directly — separate repo, confirmed via the live package's own project_urls.Repository) different repo — nothing to change here; pending publish
5,7 wave-av-sdk (PyPI) py-import-module / py-no-stdlib-shadow same rename, sdk-python/ in this repo, version 3.0.0 already on origin/main before this PR re-verified in this PR by actually building the wheel, installing into a fresh venv, and running scripts/ga/cleanroom_python_assert.py against the installed artifact — both checks pass; pytest 31/31 (36/36 with the new tests this PR adds)

None of that needed a source change. What this PR actually changes:

Changes

  1. scripts/ga/cleanroom_python_assert.py — the cleanroom-isolation guard (meant to catch a repo checkout accidentally on sys.path, which would make the whole clean-room probe meaningless) was keyed on a hardcoded "wave" directory name. That was the pre-rename package directory. After wavewave_sdk landed, the guard silently stopped matching either checkout's real layout and could never again detect a genuine leak. Demonstrated the regression directly: with PYTHONPATH pointed at the repo root, the old code reported cleanroom-isolation ok=true (wrong); the fix — keyed on args.module, the same name already used for the import check — reports ok=false (correct). Re-ran the full probe against a real built wheel afterward to confirm cleanroom-isolation / py-import-module / py-no-stdlib-shadow still all pass.

  2. sdk-python/tests/test_packaging.py (new) — offline packaging guards: no shipped top-level package may shadow a stdlib name, bare import wave still resolves to the stdlib from inside the checkout, wave_sdk.__version__ matches pyproject.toml, and the distribution name is still wave-av-sdk. These run in the normal pytest pass, before any wheel is built — closing the gap that let 2.0.0 ship broken in the first place (an editable install / repo-checkout test run hides exactly this class of stdlib-shadow bug, because the checkout directory wins import wave under pytest regardless of what the built wheel would actually ship). Mirrors the equivalent guard already proven out in wave-av/sdk-python's tests/test_packaging.py, adapted to this package's name/module. pyproject.toml gains the matching tomli dev-extra for Python < 3.11 (tomllib is stdlib only from 3.11).

  3. .github/workflows/test-python.yml — new smoke-install job: builds the real wheel, installs it (no -e, no repo on sys.path) into a throwaway venv, and runs this repo's own cleanroom_python_assert.py probe against the installed artifact, on every PR touching sdk-python. This is the same probe the GA registry clean-room gate runs against the live PyPI package after a publish — the difference is this one runs pre-publish, offline, on every PR, so the wave/wave_sdk defect class cannot reach a registry a second time.

Verification performed (all run in this lane, not asserted from docs)

  • pytest -q in sdk-python: 36/36 pass (31 pre-existing + 5 new in test_packaging.py)
  • ruff check tests/test_packaging.py: clean
  • actionlint .github/workflows/test-python.yml: clean
  • Built the real wheel (python -m build --wheel), installed into a fresh venv with no repo checkout on sys.path, ran the actual scripts/ga/cleanroom_python_assert.py --dist wave-av-sdk --module wave_sdk --symbol Wave against it: cleanroom-isolation / py-import-module / py-no-stdlib-shadow all pass
  • Demonstrated the isolation-marker regression concretely: same probe run with PYTHONPATH pointed at the repo root reports cleanroom-isolation ok=false with the fix, ok=true (silently wrong) with the pre-fix code
  • Independently confirmed (read-only, no changes) that wave-av/cli's origin/main already carries the version-derivation, provenance, and exact-pin fixes, and that wave-av/sdk-python's origin/main already carries the wave_sdk rename — both are separate repositories this PR cannot and does not touch

What still requires a republish (explicitly out of scope for this lane)

All 7 originally-failing checks remain failing against the live registries until an operator publishes: @wave-av/cli (npm), wave-sdk (PyPI, from wave-av/sdk-python), and wave-av-sdk (PyPI, via a sdk-python-v3.0.0 tag on this repo). No npm/PyPI publish, git tag push, or workflow dispatch of a publish workflow was performed or attempted in this lane, per the hard constraint on this task.

Test plan

  • pytest -q sdk-python: 36/36 pass
  • ruff check on new test file: clean
  • actionlint on modified workflow: clean
  • Manual wheel build + fresh-venv install + clean-room probe: pass
  • Manual regression demonstration of the isolation-marker fix (before/after)
  • CI run of the new smoke-install job on this PR (will run automatically; not yet observed since this PR was just opened)

🤖 Generated with Claude Code

https://claude.ai/code/session_01MLCfz2w3xiGLfFFgFmbe5j


Note

Low Risk
Changes are CI, GA probe logic, and test-only packaging guards; no runtime SDK API or auth/data-path changes.

Overview
Hardens Python packaging and clean-room checks so a broken wheel or a false “clean” probe cannot slip through CI again after the wavewave_sdk rename.

The GA probe’s cleanroom-isolation check no longer looks for a stale sdk-python/wave path; it detects checkout leaks via checkout_paths_providing() keyed on the module under test, treats '' as cwd, and ignores interpreter-owned paths (site-packages, stdlib, venv). cleanroom-targets.mjs copies cleanroom_python_assert.py into the throwaway room before execution so running the script from the repo does not put scripts/ga on sys.path.

CI adds a smoke-install job: build wheel → fresh venv → non-editable install → run the same clean-room probe as registry GA. Workflow path filters now include the probe script.

Offline pytest guards in test_packaging.py (stdlib shadow, bare import wave, version/name vs pyproject.toml) and test_cleanroom_probe.py (isolation helper behavior). tomli added to dev extras on Python < 3.11 for packaging tests.

Reviewed by Cursor Bugbot for commit b419a85. Bugbot is set up for automated code reviews on this repo. Configure here.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Review in cubic

Summary by Sourcery

Harden Python SDK packaging and clean-room validation so source-checkout leaks and standard-library collisions are detected before publication.

New Features:

  • Add pre-publish packaging tests that detect standard-library name collisions and verify SDK metadata consistency.
  • Add a fresh-venv smoke-install workflow job that validates the built wheel with the clean-room import probe on Python 3.10 and 3.12.

Bug Fixes:

  • Restore clean-room isolation detection for current and future checkout layouts, including root-level, nested, and single-file module paths.
  • Prevent the registry clean-room probe from contaminating its own environment by copying the probe into the temporary room before execution.

Enhancements:

  • Make isolation checks derive from the module under test while excluding interpreter-owned paths from leak detection.

Build:

  • Add the Python <3.11 tomli development dependency required by packaging tests.

CI:

  • Run packaging and clean-install regression checks when the Python SDK or clean-room probe changes.

Tests:

  • Add unit coverage for clean-room isolation across repository layouts, current-working-directory entries, false positives, and reported leak paths.

… isolation marker

All 7 checks the registry clean-room gate (run 33933317710) reported failing were
already root-cause fixed in source before this change, across three repositories
(verified independently in this lane, not merely re-read from docs):

  - @wave-av/cli npm-provenance-attested / bin-version-matches-package /
    declared-dep-ranges-pinned: fixed on wave-av/cli's origin/main (release.yml already
    runs `npm publish --provenance` under `id-token: write` OIDC; src/lib/version.ts
    derives CLI_VERSION from package.json at runtime; @wave-av/sdk pinned to exact
    "2.0.14"). Owned by a different repository; nothing to change here.
  - wave-sdk (PyPI) py-import-module / py-no-stdlib-shadow: fixed on
    wave-av/sdk-python's origin/main (module renamed wave -> wave_sdk, version 2.1.0,
    with its own tests/test_packaging.py + smoke-install.yml). Owned by a different
    repository; nothing to change here.
  - wave-av-sdk (PyPI) py-import-module / py-no-stdlib-shadow: fixed on THIS repo's
    origin/main already (sdk-python/ renamed wave/ -> wave_sdk/, version 3.0.0).
    Re-verified here by actually building the wheel, installing it into a fresh venv,
    and running scripts/ga/cleanroom_python_assert.py against the installed artifact —
    py-import-module and py-no-stdlib-shadow both pass; full pytest suite 31/31 (36/36
    with the new tests below).

None of the above needed a source change; all are blocked solely on an operator
publish, which this lane may not perform.

What this commit actually changes:

1. scripts/ga/cleanroom_python_assert.py: the cleanroom-isolation guard keyed its
   repo-checkout-on-sys.path detection on a hardcoded "wave" directory name. That was
   the PRE-rename package directory; after wave -> wave_sdk landed (in the same source
   fix this file is supposed to help verify), the guard silently stopped matching
   either checkout's real layout and could never again detect a genuine repo-on-path
   leak. Demonstrated the regression directly: with PYTHONPATH pointed at the repo
   root, the old code reports cleanroom-isolation ok=true (wrong); the fix (keyed on
   `args.module`, the same name already used for the import check) reports ok=false
   (correct). Re-ran the full probe against a real built wheel afterward to confirm it
   still passes cleanroom-isolation / py-import-module / py-no-stdlib-shadow.

2. sdk-python/tests/test_packaging.py (new): offline packaging guards — no shipped
   top-level package may shadow a stdlib name, `import wave` (bare) still resolves to
   the stdlib from inside the checkout, `wave_sdk.__version__` matches
   pyproject.toml's version, and the distribution name is still `wave-av-sdk`. These
   run in the normal `pytest` pass, before any wheel is ever built — closing the gap
   that let 2.0.0 ship broken in the first place (an editable install / repo-checkout
   test run hides the exact stdlib-shadow class this guards). Mirrors the equivalent
   guard already proven out in wave-av/sdk-python's tests/test_packaging.py, adapted
   to this package's name/module. pyproject.toml gains the matching `tomli` dev-extra
   for Python < 3.11 (tomllib is stdlib only from 3.11).

3. .github/workflows/test-python.yml: new `smoke-install` job — builds the real wheel,
   installs it (no `-e`, no repo on sys.path) into a throwaway venv, and runs THIS
   repo's own scripts/ga/registry-cleanroom.mjs probe (cleanroom_python_assert.py)
   against the installed artifact on every PR touching sdk-python. This is the same
   probe the GA gate runs against the live PyPI package after a publish — the
   difference is this one runs pre-publish, offline, on every PR, so the wave/wave_sdk
   defect class cannot reach a registry a second time. Verified end-to-end locally:
   built the wheel, installed into a fresh venv, ran the exact copy/probe/parse
   sequence the job runs — all three checks (cleanroom-isolation, py-import-module,
   py-no-stdlib-shadow) pass; actionlint clean on the workflow file.

Verified: `pytest -q` sdk-python 36/36 pass (31 pre-existing + 5 new); `ruff check
tests/test_packaging.py` clean; `actionlint .github/workflows/test-python.yml` clean;
manual wheel build + fresh-venv install + cleanroom_python_assert.py probe pass
against the real built artifact, both before and after the isolation-marker fix (with
the fix demonstrated to catch a real injected leak the old code missed).

Tracking: claude-workstation#4321 item 6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MLCfz2w3xiGLfFFgFmbe5j
@codeant-ai

codeant-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your workspace is out of credits. Ask your workspace admin to add credits to resume reviews. Manage billing

@sourcery-ai sourcery-ai 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.

Sorry @yakimoto, this account has used its review budget of 2,500,000 diff characters for the last 7 days.

You can request another review in 22 hours and 48 minutes by commenting @sourcery-ai review.

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_b479bfc2-c5df-4549-9ab9-4db2bd400765)

@sourcery-ai

sourcery-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds pre-publish safeguards for the Python SDK by fixing the stale repository-isolation marker, testing packaging metadata and stdlib-shadowing risks offline, and exercising the real wheel in a clean virtual environment on pull requests.

Sequence diagram for pre-publish Python wheel smoke validation

sequenceDiagram
    participant CI as GitHub Actions
    participant Build as Wheel Builder
    participant Venv as Fresh Virtualenv
    participant Probe as cleanroom_python_assert.py

    CI->>Build: python -m build --wheel
    Build-->>CI: wave-av-sdk wheel
    CI->>Venv: Install wheel without editable mode
    Venv->>Probe: Run probe with --dist wave-av-sdk --module wave_sdk --symbol Wave
    Probe->>Probe: Check cleanroom-isolation
    Probe->>Probe: Check py-import-module
    Probe->>Probe: Check py-no-stdlib-shadow
    Probe-->>CI: Report clean-room checks
Loading

Flow diagram for offline Python packaging safeguards

flowchart LR
    Checkout[Repository checkout] --> Tests[pytest packaging guards]
    Tests --> Metadata[Validate distribution and version metadata]
    Tests --> Imports[Validate wave_sdk import and Wave symbol]
    Tests --> Stdlib[Validate import wave resolves to stdlib]
    Tests --> Wheel[Build real wheel]
    Wheel --> Install[Install into fresh virtualenv]
    Install --> Probe[Run cleanroom_python_assert.py]
    Probe --> Publish[Safe to publish]
Loading

File-Level Changes

Change Details Files
Repair the clean-room isolation check to detect repository leakage after the package rename.
  • Derive the checkout marker directory from the requested module argument instead of the obsolete wave literal.
  • Preserve validation that the installed module, distribution, and stdlib-shadow checks pass.
scripts/ga/cleanroom_python_assert.py
Add offline packaging tests that catch metadata drift and stdlib-shadow regressions before publication.
  • Detect shipped top-level packages that collide with standard-library module names.
  • Verify bare import wave resolves to the stdlib from the checkout.
  • Verify wave_sdk.__version__ matches pyproject.toml and the distribution name remains wave-av-sdk.
  • Add the Python <3.11 tomli development dependency needed to parse project metadata.
sdk-python/tests/test_packaging.py
sdk-python/pyproject.toml
Add a pre-publish wheel smoke test that validates the actual installed artifact in isolation.
  • Build and install a non-editable wheel into a fresh virtual environment on Python 3.10 and 3.12.
  • Run the clean-room probe against the installed wheel and fail on any unsuccessful check.
  • Trigger the workflow when the probe script changes as well as when the SDK or workflow changes.
.github/workflows/test-python.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@socket-security

socket-security Bot commented Sep 5, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpypi/​tomli@​2.4.1100100100100100

View full report

@macroscopeapp

macroscopeapp Bot commented Sep 5, 2026

Copy link
Copy Markdown

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR hardens packaging and clean-room validation without changing customer-facing SDK runtime behavior. Human review is still appropriate because every modified file is explicitly owned by the sdk-owners team rather than the author.

Not approved because:

  • Credit balance exhausted. Approvability relies on correctness review in order to determine eligibility

Review your spending limits in Billing settings. You can add or adjust custom eligibility rules. Learn more.

@gitar-bot

gitar-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

Note

Automatic reviews are paused because your team has used its included automatic processing for this billing period (headroom scales with your seat count). You can still comment "Gitar review" to run one anytime, and automatic reviews resume on their own by October 1. Add seats for more headroom.
Learn more

Code Review ✅ Approved

Fixes the cleanroom-isolation guard in scripts/ga/cleanroom_python_assert.py by updating the stale wave directory name check to use the actual module name (wave_sdk), adds comprehensive offline packaging tests in sdk-python/tests/test_packaging.py to prevent stdlib shadowing regressions, and introduces a pre-publish smoke-install workflow job that validates the built wheel against the clean-room probe before deployment. All 36 tests pass, and manual verification confirms the isolation marker now correctly detects leaks.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

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: ASSERTIVE

Plan: Team

Run ID: 69e878e1-4588-41a3-a064-f38622de34cb

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

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: b03efe05-41ce-490c-bf2d-521e9b6ec40e

📥 Commits

Reviewing files that changed from the base of the PR and between 6fe7c01 and 80576ba.

📒 Files selected for processing (4)
  • .github/workflows/test-python.yml
  • scripts/ga/cleanroom_python_assert.py
  • sdk-python/pyproject.toml
  • sdk-python/tests/test_packaging.py

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Analyze (rust)
⚠️ CI failures not shown inline (2)

GitHub Actions: registry clean-room acceptance / 0_cleanroom.txt: fix(ga): pre-publish wheel-import guard for sdk-python + repair stale isolation marker

Conclusion: failure

View job details

##[group]Run if [ "$CODE" != "0" ]; then
 �[36;1mif [ "$CODE" != "0" ]; then�[0m
 �[36;1m  echo "::error title=registry clean-room::published artifacts failed clean-room acceptance (exit $CODE) — see the job summary"�[0m

GitHub Actions: registry clean-room acceptance / cleanroom: fix(ga): pre-publish wheel-import guard for sdk-python + repair stale isolation marker

Conclusion: failure

View job details

##[group]Run if [ "$CODE" != "0" ]; then
 �[36;1mif [ "$CODE" != "0" ]; then�[0m
 �[36;1m  echo "::error title=registry clean-room::published artifacts failed clean-room acceptance (exit $CODE) — see the job summary"�[0m
🧰 Additional context used
🪛 zizmor (1.29.0)
.github/workflows/test-python.yml

[warning] 57-57: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[info] 43-43: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)

🔇 Additional comments (4)
sdk-python/tests/test_packaging.py (1)

1-150: LGTM!

sdk-python/pyproject.toml (1)

74-76: LGTM!

scripts/ga/cleanroom_python_assert.py (1)

87-95: LGTM!

.github/workflows/test-python.yml (1)

10-11: LGTM!

Also applies to: 43-86


📝 Summary

Summary by CodeRabbit

  • New Features

    • The Python SDK now ships under the wave_sdk package name while preserving the wave-av-sdk distribution name.
    • The SDK version is consistently reported from its package metadata.
  • Bug Fixes

    • Fixed package resolution so importing Python’s standard-library wave module is no longer shadowed by the SDK.
  • Tests

    • Added packaging and clean-install validation across Python 3.10 and 3.12.

Walkthrough

The pull request adds packaging regression tests, updates clean-room package detection for wave_sdk, adds the Python 3.10 TOML parser fallback, and introduces isolated wheel-install smoke tests for Python 3.10 and 3.12.

Changes

Python packaging validation

Layer / File(s) Summary
Packaging regression tests
sdk-python/tests/test_packaging.py, sdk-python/pyproject.toml
The tests validate wave_sdk, standard-library import resolution, package-name collisions, version metadata, and distribution naming. Python versions below 3.11 use tomli.
Module-aware clean-room detection
scripts/ga/cleanroom_python_assert.py
The clean-room check derives the expected repository package directory from the requested module name.
Isolated CI smoke installation
.github/workflows/test-python.yml
CI builds and installs the SDK wheel in isolated Python 3.10 and 3.12 environments, then runs the clean-room probe.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 80576

This change repairs the clean-room package check and adds packaging and isolated-install validation for the Python SDK. No merge-blocking risk is currently identified.

Sequence Diagram(s)

sequenceDiagram
  participant GitHub Actions
  participant Wheel Builder
  participant Isolated Virtualenv
  participant Clean-room Probe
  GitHub Actions->>Wheel Builder: Build SDK wheel
  Wheel Builder->>Isolated Virtualenv: Install wheel
  Isolated Virtualenv->>Clean-room Probe: Run import checks
  Clean-room Probe-->>GitHub Actions: Return check results
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 2 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately identifies the clean-room wheel-import guard and stale isolation-marker fix. It is specific and related to the main changes.
Description check ✅ Passed The description clearly explains the workflow fix, packaging tests, smoke-install job, verification results, and out-of-scope republishing work.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 2 files. (2 skipped: 2 unsupported.)

✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cleanroom-registry-defects
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/cleanroom-registry-defects

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

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.
Architecture diagram
sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub Actions
    participant Unit as pytest (sdk-python)
    participant Pack as test_packaging.py
    participant Build as Wheel Build
    participant Venv as Fresh Venv
    participant Probe as cleanroom_python_assert.py
    participant Registry as GA Registry Gate (post-publish)

    Note over Dev,Registry: PR-time Guard Flow (new smoke-install job)

    Dev->>GH: Push PR touching sdk-python/**
    GH->>GH: Trigger test-python.yml

    rect rgb(240, 248, 255)
        Note over Unit,Pack: Offline unit tests (existing job)
        GH->>Unit: Run pytest
        Unit->>Pack: Execute test_packaging.py
        Pack->>Pack: Scan top-level packages for stdlib shadow (NEW)
        alt Stdlib collision found
            Pack-->>Unit: FAIL (e.g., wave/ reappears)
        else No collision
            Pack->>Pack: Verify import wave resolves to stdlib
            Pack->>Pack: Check wave_sdk.__version__ vs pyproject
            Pack->>Pack: Confirm dist name is wave-av-sdk
            Pack-->>Unit: Pass
        end
    end

    rect rgb(245, 245, 245)
        Note over GH,Probe: New smoke-install job (pre-publish, offline)
        GH->>Build: Build real wheel (python -m build)
        Build-->>GH: wheel file
        GH->>Venv: Create throwaway venv (no repo on sys.path)
        GH->>Venv: Install wheel (pip install, no -e)
        GH->>Venv: Copy cleanroom probe into venv
        Venv->>Probe: Run probe (--module wave_sdk)
        Note over Probe: Isolation guard keyed on args.module (CHANGED)
        alt Repo checkout leaks onto sys.path
            Probe-->>Venv: cleanroom-isolation ok=false (now correctly detects)
            Venv-->>GH: FAIL (guard catches leak)
        else Clean environment
            Probe->>Probe: Import wave_sdk
            Probe->>Probe: Check no stdlib shadow
            Probe-->>Venv: All checks pass
            Venv-->>GH: Pass
        end
    end

    Note over Registry: Post-publish (unchanged, out of scope)
    GH->>Registry: Publish wave-av-sdk to PyPI (operator action)
    Registry->>Registry: Run same probe against live registry
    Note over Registry: Uses same cleanroom_python_assert.py — now with fixed isolation marker
Loading

Re-trigger cubic

…estable

The `cleanroom-isolation` check is the load-bearing assertion of the registry
clean-room gate: `py-import-module` and `py-no-stdlib-shadow` only mean anything
if no source checkout can satisfy the import the PUBLISHED wheel is supposed to
satisfy. It was keyed on one hardcoded path.

The first fix on this branch replaced the stale `<entry>/sdk-python/wave` literal
with `<entry>/sdk-python/<module>`. That restores the guard for wave-av/sdks'
own layout only. The probe also runs against wave-av/sdk-python, whose package
sits at the REPOSITORY ROOT (`wave_sdk/`, verified on that repo's origin/main) —
a checkout of it on sys.path still passed the guard. Measured, both directions:

  fake root-level checkout on PYTHONPATH, probe at this branch's head
    cleanroom-isolation ok=true   (wrong — leak invisible)
  same sys.path, probe after this commit
    cleanroom-isolation ok=false  REPO ON sys.path: [.../wave_sdk]

`checkout_paths_providing()` now asks the layout-independent question — can this
sys.path entry supply the module under test, at the entry itself or under any of
the conventional source roots — after excluding the entries that legitimately
can (site-packages, stdlib, user-site, the venv prefix), read from sysconfig and
`site` rather than assumed to sit under sys.prefix. It also resolves the `''`
entry to cwd, which the previous code skipped outright.

cleanroom-targets.mjs now COPIES the probe into the throwaway room before running
it. Python unconditionally prepends the executed script's directory to sys.path,
so running it in place put `<repo>/scripts/ga` first on the path of every
clean-room probe — a repository directory inside the clean room, which is the one
thing this suite promises never happens. (`-P`/PYTHONSAFEPATH is 3.11+; the
venv's interpreter version is not ours to assume.) test-python.yml's
smoke-install job already copies it for exactly this reason.

sdk-python/tests/test_cleanroom_probe.py: 8 offline unit tests over real
directory trees — both repository layouts, single-file module, the cwd entry, the
site-packages false-positive control, and the self-maintenance property (rename
the package and the guard follows it). A hardcoded-path guard had no test that
could catch it going blind; that is why the rename disarmed it silently.

Verification in this lane:
- pytest -q in sdk-python: 44/44 pass (36 before this commit + 8 new)
- ruff check under the repo's own config: clean on both changed/added files
- full pypi clean-room gate re-run against the LIVE registries with these
  changes: identical evidence fingerprint 8e6537fd84b4859d003e6787d3c4b585ceb5
  ee39da5e681d4d4f2cb098cc8e04 to the run at this branch's head and to
  origin/main — the hardening changes no verdict on real artifacts

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MLCfz2w3xiGLfFFgFmbe5j
@codeant-ai

codeant-ai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_931c09c3-2ff8-470e-a149-d0ddac726449)

@yakimoto

yakimoto commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Clean-room triage 2026-09-05 — the red cleanroom is the gate working, and it also found a second defect in the guard this PR repairs

Corrections to the description above, measured today (the description was accurate when written and has since been overtaken):

  • It lists wave-av-sdk (PyPI) as pending publish. wave-av-sdk 3.0.0 was published 2026-09-05T03:17:38Z and both of its clean-room checks now PASS against the live artifact. The live failing set is 5, not 7.
  • It describes the isolation-marker fix as restoring the guard for "either checkout's real layout". It does not — see below. b419a85 fixes that.

Bucket triage of every failing check

Run 33940473680 reported 7; the current run on b419a85 (33942707861) reports 5.

# Artifact Check Bucket Status today
1 @wave-av/cli@1.0.8 npm-provenance-attested (a) real artifact defect still failing — #85
2 @wave-av/cli@1.0.8 bin-version-matches-package (a) real artifact defect still failing — #85
3 @wave-av/cli@1.0.8 declared-dep-ranges-pinned (a) real artifact defect still failing — #85
4 wave-sdk@2.0.0 (PyPI) py-import-module (a) real artifact defect still failing — #86
5 wave-sdk@2.0.0 (PyPI) py-no-stdlib-shadow (a) real artifact defect still failing — #86
6 wave-av-sdk (PyPI) py-import-module (a) real artifact defect PASS since 3.0.0
7 wave-av-sdk (PyPI) py-no-stdlib-shadow (a) real artifact defect PASS since 3.0.0

Nothing lands in bucket (c) "introduced by this PR".

Control against main

The gate was run against origin/main (6fe7c01) in a clean detached worktree and against this branch's head, same interpreter, same live registries. Identical verdict and identical evidence fingerprint 8e6537fd84b4859d003e6787d3c4b585ceb5ee39da5e681d4d4f2cb098cc8e04. In CI the same failing set appears on two unrelated Renovate branches (runs 33933317710, 33933289317) whose only diff from main is sdk-typescript/pnpm-lock.yaml.

The second guard defect, fixed in b419a85

The first commit replaced the stale <entry>/sdk-python/wave literal with <entry>/sdk-python/<module>. That restores the guard for this repository's layout only. The probe also runs against wave-av/sdk-python, whose package sits at the repository root (wave_sdk/, verified on that repo's main), so a checkout of it on sys.path still passed the guard. Measured with a fabricated checkout on PYTHONPATH:

probe revision root-level wave_sdk/ sdk-python/wave_sdk/
origin/main ok=true (blind) ok=true (blind)
this branch, 80576ba ok=true (still blind) ok=false
this branch, b419a85 ok=false ok=false

checkout_paths_providing() now asks the layout-independent question — can this sys.path entry supply the module under test, at the entry itself or under any conventional source root — after excluding the entries that legitimately can (site-packages, stdlib, user-site, venv prefix), read from sysconfig/site rather than assumed to sit under sys.prefix. It also resolves the '' entry to cwd, which the old code skipped outright.

The clean room was not actually clean

cleanroom-targets.mjs executed the probe from scripts/ga/. Python unconditionally prepends the executed script's directory to sys.path, so a repository directory was first on the path of every clean-room probe — the one thing the suite promises never happens. It is now copied into the throwaway room first, exactly as test-python.yml's smoke-install job already does.

sdk-python/tests/test_cleanroom_probe.py adds 8 offline unit tests over real directory trees: both repository layouts, single-file module, the cwd entry, the site-packages false-positive control, and the self-maintenance property (rename the package and the guard follows it). A hardcoded-path guard had no test that could catch it going blind, which is why the rename disarmed it silently.

Verification on b419a85

  • python test: all four jobs green (test and smoke-install, 3.10 and 3.12)
  • local pytest -q in sdk-python: 44/44
  • ruff check under the repo's own config: clean on both changed files and the new test
  • registry parity, license consistency, governance-enforce, public-repo-guard, foundation-gate: green
  • cleanroom: red with exactly the 5 published-artifact defects above, evidence artifact ga-evidence-registry-cleanroom on run 33942707861

Still advisory

cleanroom is not a required status check on main. The only required context is Secrets + content policy (org ruleset public-repo-guard-required); classic branch protection 404s on this repo because it is ruleset-protected, and a sibling-repo control returns a populated list, so the short answer is a measurement rather than a permissions artifact. Tracked in #87 together with the stale "Arming window" ledger in GA-READINESS.md, which still reports 7 outstanding failures.

Deferred deliberately, not fixed here: all five live artifact defects (#85, #86) — no change in this repository can alter what a registry already serves, and both fixes need an operator-gated publish from a different repo. GA-READINESS.md's arming ledger was left alone too: its ART-001/VER-001/SUPPLY-001 blocks carry verified_revision and evidence sha256 fields that must be regenerated from a real run, not hand-edited (#87).

🤖 Generated with Claude Code

https://claude.ai/code/session_01MLCfz2w3xiGLfFFgFmbe5j

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