Skip to content

Fail closed on Puzzletron correctness failures - #2114

Open
j-rausch wants to merge 6 commits into
feature/puzzletron_v2from
ptv2-sanity-correctness
Open

Fail closed on Puzzletron correctness failures#2114
j-rausch wants to merge 6 commits into
feature/puzzletron_v2from
ptv2-sanity-correctness

Conversation

@j-rausch

@j-rausch j-rausch commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Type of change: Bug fix and documentation.

Puzzletron sanity stages could record passed: false while still returning a successful stage. That allowed the campaign DAG to advance after full-width sorting or dynamic-versus-physical slicing had failed a correctness check. Reports also described width-ranking findings as advisory without explaining what they measured or how stage completion differs from campaign qualification.

This change:

  • centralizes sanity-stage completion so sort and slicing-equivalence failures are correctness errors that fail the stage;
  • makes every distributed rank consume the same persisted sort verdict, preventing a non-master rank from overwriting a failure with success;
  • keeps width-ranking misses as quality warnings by default, with sanity.fail_on_warnings available when a campaign requires warnings to fail the stage;
  • preserves gate outcomes in report empty states, including blocking slicing failures when no numeric chart can be rendered;
  • propagates the same verdict and finding semantics through parent sweeps, aggregation, stage outputs, and the progress report; and
  • keeps the quick-start README focused while a linked sanity-validation guide documents sorting, dynamic and physical slicing, measured metric families, original-order and reverse controls, equivalence tolerances, and the separate qualification decision.

The outcome is that downstream stages no longer proceed using evidence from a correctness-invalid model transformation. Users can also distinguish a weak importance ranking from a broken sorting or slicing implementation and apply a stricter warning policy when scientific or release qualification requires it.

Campaign qualification remains an explicit policy decision. This change does not add a separate qualification_blocked verdict or prescribe universal acceptance thresholds for ranking quality.

Usage

Sort and slicing correctness failures always fail their stages. To also fail a sanity stage on ranking-quality warnings, enable strict warning handling:

sanity:
  fail_on_warnings: true

Testing

Unit coverage exercises sanity-verdict completion, distributed sort-verdict propagation, warning escalation, parent-sweep propagation, width and slicing aggregation, and report rendering for ranking-quality findings, blocking equivalence failures, and no-metric empty states.

Treat sort and slicing-equivalence mismatches as blocking correctness errors while keeping ranking-quality findings advisory. Propagate the same contract through parent sweeps and progress reports.

Signed-off-by: Johannes Rausch <jrausch@nvidia.com>
Explain how width-ranking quality checks differ from sort and slicing equivalence failures, including what is measured and how strict qualification can promote warnings.

Signed-off-by: Johannes Rausch <jrausch@nvidia.com>
Keep the main README focused on the first-run workflow while retaining the detailed ranking, slicing, and qualification reference in a linked topic guide.

Signed-off-by: Johannes Rausch <jrausch@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2cd80674-0bf5-4c5e-a106-3d58e97432da

📥 Commits

Reviewing files that changed from the base of the PR and between 39ed844 and cc70a2a.

📒 Files selected for processing (2)
  • modelopt/torch/puzzletron/stages/diagnostics.py
  • tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • modelopt/torch/puzzletron/stages/diagnostics.py

📝 Walkthrough

Walkthrough

Sanity handling separates blocking sort and slicing correctness failures from advisory width-ranking warnings. Verdicts, diagnostics, campaign reports, tests, and Puzzletron documentation reflect the new severity and qualification behavior.

Changes

Sanity policy and execution

Layer / File(s) Summary
Verdict and finding severity contract
modelopt/torch/puzzletron/diagnostics/campaign_findings.py, modelopt/torch/puzzletron/diagnostics/sanity_verdict.py, tests/unit/torch/puzzletron/test_campaign_findings.py, tests/unit/torch/puzzletron/test_sanity_verdict.py
Findings support warning and error severities. Verdicts record blocking status and apply sanity.fail_on_warnings only to non-blocking failures.
Diagnostic aggregation and fail-closed stages
modelopt/torch/puzzletron/diagnostics/width_sanity.py, modelopt/torch/puzzletron/stages/diagnostics.py, tests/unit/torch/puzzletron/test_hidden_width_diagnostic.py, tests/unit/torch/puzzletron/test_width_sanity_aggregation.py, tests/unit/torch/puzzletron/test_width_slice_equivalence.py
Parent-sweep and slicing diagnostics publish equivalence failures as failed, blocking results with error findings while retaining width-ranking warnings.
Campaign progress reporting
modelopt/torch/puzzletron/diagnostics/campaign_progress_report.py, tests/unit/torch/puzzletron/test_campaign_progress_report.py
Reports detect failed correctness stages and render separate ranking-warning and equivalence-failure gates, DAG statuses, legends, and styles.
Distributed equivalence validation
modelopt/torch/puzzletron/stages/diagnostics.py, tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py
Sort-equivalence finalization writes canonical failure evidence and propagates the master verdict to all ranks.
Sanity validation documentation
examples/puzzletron/README.md, examples/puzzletron/docs/sanity_validation.md, examples/puzzletron/docs/v2_architecture.md
Documentation defines ranking and equivalence checks, stage outcomes, strict warning handling, and campaign or release qualification inputs.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ParentSweep
  participant SanityVerdict
  participant CampaignReport
  ParentSweep->>SanityVerdict: combine width, sort, and slicing findings
  SanityVerdict->>SanityVerdict: classify warnings and blocking errors
  SanityVerdict->>CampaignReport: publish stage verdict and finding severities
  CampaignReport->>CampaignReport: render gate badges and DAG status
Loading

Suggested reviewers: separius

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: Puzzletron correctness failures now fail closed.
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.
Security Anti-Patterns ✅ Passed The PR adds no prohibited load, eval/exec, trust_remote_code, or # nosec patterns in modelopt/examples Python, and changes no dependency manifests.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ptv2-sanity-correctness

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

@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.70833% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.22%. Comparing base (3485fd0) to head (cc70a2a).

Files with missing lines Patch % Lines
modelopt/torch/puzzletron/stages/diagnostics.py 87.50% 7 Missing ⚠️
Additional details and impacted files
@@                    Coverage Diff                    @@
##           feature/puzzletron_v2    #2114      +/-   ##
=========================================================
+ Coverage                  54.76%   55.22%   +0.46%     
=========================================================
  Files                        704      704              
  Lines                      90869    90907      +38     
=========================================================
+ Hits                       49761    50200     +439     
+ Misses                     41108    40707     -401     
Flag Coverage Δ
puzzletron 32.94% <92.70%> (+0.07%) ⬆️
regression 9.03% <0.00%> (?)
unit 29.73% <0.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@j-rausch
j-rausch marked this pull request as ready for review August 7, 2026 18:44
@j-rausch
j-rausch requested a review from a team as a code owner August 7, 2026 18:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/puzzletron/docs/sanity_validation.md`:
- Around line 39-44: Standardize the deterministic control terminology across
all listed documentation sites: in examples/puzzletron/docs/sanity_validation.md
lines 39-44, choose one canonical label and identify random as a legacy alias
only where needed; in examples/puzzletron/README.md lines 484-503, clarify that
random denotes the original or unsorted prefix; in
examples/puzzletron/docs/v2_architecture.md line 142 and lines 361-386, replace
inconsistent control names and align gate and qualification terminology with the
canonical label.

In `@modelopt/torch/puzzletron/diagnostics/campaign_progress_report.py`:
- Around line 503-504: Update the later empty-state return for non-empty rows
with empty axes or metrics to prefix its message with gate_summary, matching the
not-rows branch. Preserve the existing empty-state content while ensuring failed
slicing-equivalence gates remain visible.

In `@modelopt/torch/puzzletron/stages/diagnostics.py`:
- Line 3343: Unify the post-barrier completion flow around the shared verdict in
the diagnostics stage: after rank 0 evaluates the sort result, broadcast or
otherwise derive the same passed/failed value on every rank, and ensure all
ranks either follow the same failure return path or use rank 0 exclusively for
persisting the stage manifest. Update the `verdict` construction and surrounding
rank-specific handling so a failed result cannot be overwritten by another
rank’s `SanityVerdict(passed=True)`.
- Line 1615: Move the SanityVerdict import at
modelopt/torch/puzzletron/stages/diagnostics.py:1615 and the
complete_sanity_stage import at
modelopt/torch/puzzletron/stages/diagnostics.py:2741-2743 into the module-level
import section. Remove both local imports while preserving their existing
usages.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 642ff8c6-994d-42ec-8334-e1b25f5a47a2

📥 Commits

Reviewing files that changed from the base of the PR and between 3485fd0 and 7ca3cd2.

📒 Files selected for processing (15)
  • examples/puzzletron/README.md
  • examples/puzzletron/docs/sanity_validation.md
  • examples/puzzletron/docs/v2_architecture.md
  • modelopt/torch/puzzletron/diagnostics/campaign_findings.py
  • modelopt/torch/puzzletron/diagnostics/campaign_progress_report.py
  • modelopt/torch/puzzletron/diagnostics/sanity_verdict.py
  • modelopt/torch/puzzletron/diagnostics/width_sanity.py
  • modelopt/torch/puzzletron/stages/diagnostics.py
  • tests/unit/torch/puzzletron/test_campaign_findings.py
  • tests/unit/torch/puzzletron/test_campaign_progress_report.py
  • tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py
  • tests/unit/torch/puzzletron/test_hidden_width_diagnostic.py
  • tests/unit/torch/puzzletron/test_sanity_verdict.py
  • tests/unit/torch/puzzletron/test_width_sanity_aggregation.py
  • tests/unit/torch/puzzletron/test_width_slice_equivalence.py
💤 Files with no reviewable changes (1)
  • tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py

Comment thread examples/puzzletron/docs/sanity_validation.md
Comment thread modelopt/torch/puzzletron/diagnostics/campaign_progress_report.py
Comment thread modelopt/torch/puzzletron/stages/diagnostics.py Outdated
Comment thread modelopt/torch/puzzletron/stages/diagnostics.py Outdated
Make every rank consume the persisted sort verdict, keep empty-state gates visible, and distinguish the deterministic original-order control from seeded random permutations.

Signed-off-by: Johannes Rausch <jrausch@nvidia.com>
Finalize summary evidence and stage manifests before process-group teardown so one rank writes the result and every rank consumes the same completed verdict.

Signed-off-by: Johannes Rausch <jrausch@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py (1)

125-128: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the blocking contract this test names.

The test is named ..._records_blocking_drift, but it does not check the two fields that carry the blocking semantics: the finding severity and the summary verdict. _write_sort_equivalence_summary sets severity="error" and "verdict": "failed", and _complete_sort_equivalence_stage consumes those values. A regression that downgrades the severity to "warning" would still pass this test.

💚 Proposed additional assertions
     summary = json.loads(summary_path.read_text(encoding="utf-8"))
     assert summary["passed"] is False
     assert summary["delta"] == 0.25
     assert summary["findings"][0]["stage"] == "sort_sanity"
+    assert summary["findings"][0]["severity"] == "error"
+    assert summary["verdict"] == "failed"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py` around lines
125 - 128, Extend the assertions in the diagnostic scoring test around
_write_sort_equivalence_summary to verify the blocking contract: assert the
finding severity is "error" and the summary verdict is "failed". Keep the
existing passed, delta, and stage assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@modelopt/torch/puzzletron/stages/diagnostics.py`:
- Around line 3349-3365: Update _finalize_sort_equivalence_stage so the master
rank catches any exception from _write_sort_equivalence_summary, records the
failure state, and still reaches dist.barrier(). After the barrier, propagate
the captured error on every rank so all processes fail consistently without
stranding non-master ranks.

---

Nitpick comments:
In `@tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py`:
- Around line 125-128: Extend the assertions in the diagnostic scoring test
around _write_sort_equivalence_summary to verify the blocking contract: assert
the finding severity is "error" and the summary verdict is "failed". Keep the
existing passed, delta, and stage assertions unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8e7e3206-c631-4b18-9de7-e1aabca23dbd

📥 Commits

Reviewing files that changed from the base of the PR and between 7ca3cd2 and 39ed844.

📒 Files selected for processing (7)
  • examples/puzzletron/README.md
  • examples/puzzletron/docs/sanity_validation.md
  • examples/puzzletron/docs/v2_architecture.md
  • modelopt/torch/puzzletron/diagnostics/campaign_progress_report.py
  • modelopt/torch/puzzletron/stages/diagnostics.py
  • tests/unit/torch/puzzletron/test_campaign_progress_report.py
  • tests/unit/torch/puzzletron/test_diagnostic_scoring_config.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • examples/puzzletron/docs/sanity_validation.md
  • tests/unit/torch/puzzletron/test_campaign_progress_report.py
  • examples/puzzletron/README.md
  • examples/puzzletron/docs/v2_architecture.md
  • modelopt/torch/puzzletron/diagnostics/campaign_progress_report.py

Comment thread modelopt/torch/puzzletron/stages/diagnostics.py
Broadcast rank-zero write errors before consuming the summary so all ranks exit consistently instead of hanging at a barrier.

Signed-off-by: Johannes Rausch <jrausch@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants