chore(msrv): feature-gate eframe/egui behind opt-in gui feature#39
Merged
Conversation
`eframe = "0.34"` (and the egui chain it pulls) raises MSRV above
1.85.0, which conflicts with the project's declared `rust-version =
"1.85.0"`. The MSRV CI job ran `cargo check --all-features` against
1.85, so any push silently passed (the job is currently red on main)
or would fail once toolchain caches refresh.
Move eframe into a new opt-in `gui` feature. The default and existing
optional features (`signing`, `http`) stay MSRV-clean; users who want
the native viewer build with `--features gui` on a newer toolchain.
Changes:
- Cargo.toml: `eframe = { ..., optional = true }`; add `gui = ["eframe"]`.
- src/report/mod.rs: cfg-gate `mod gui` and the `pub use ReportGui`.
- src/main.rs: cfg-gate the `Commands::Gui` clap variant and its match arm.
- .github/workflows/rust-ci.yml: MSRV `cargo check` now uses
`--features signing,http` (drops `--all-features` to exclude `gui`).
Verified locally:
* `cargo check` — OK (default)
* `cargo check --features signing,http` — OK (the new MSRV check command)
* `cargo check --features gui` — OK (opt-in build still works)
* `cargo clippy --all-features --all-targets -- -D warnings` — clean
* `cargo test --features signing,http --no-fail-fast` — all 17 suites OK
* `cargo fmt --check` — clean
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 Hypatia Security ScanFindings: 50 issues detected
View findings[
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Nickel file missing SPDX-License-Identifier header (1 occurrences, CWE-1104)",
"type": "ncl_missing_spdx",
"file": "/home/runner/work/panic-attack/panic-attack/reports/panic-attack-20260211180017.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (2 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/panic-attack/panic-attack/src/attestation/chain.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unwrap_or(0) with dangerous default (1 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/attestation/evidence.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "unwrap_or(0) with dangerous default (1 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/ambush/mod.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "unwrap_or(0) with dangerous default (3 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/kanren/strategy.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "unwrap_or(0) with dangerous default (3 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/axial/mod.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "expect() in hot path (4 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/panic-attack/panic-attack/src/assail/analyzer.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unwrap() without prior check -- DoS via panic (4 occurrences, CWE-754)",
"type": "unwrap_without_check",
"file": "/home/runner/work/panic-attack/panic-attack/benches/scan_bench.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "expect() in hot path (2 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/panic-attack/panic-attack/benches/scan_bench.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
🔍 Hypatia Security ScanFindings: 49 issues detected
View findings[
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Nickel file missing SPDX-License-Identifier header (1 occurrences, CWE-1104)",
"type": "ncl_missing_spdx",
"file": "/home/runner/work/panic-attack/panic-attack/reports/panic-attack-20260211180017.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (2 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/panic-attack/panic-attack/src/attestation/chain.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unwrap_or(0) with dangerous default (1 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/attestation/evidence.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "unwrap_or(0) with dangerous default (1 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/ambush/mod.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "unwrap_or(0) with dangerous default (3 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/kanren/strategy.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "unwrap_or(0) with dangerous default (3 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/panic-attack/panic-attack/src/axial/mod.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "expect() in hot path (4 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/panic-attack/panic-attack/src/assail/analyzer.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unwrap() without prior check -- DoS via panic (4 occurrences, CWE-754)",
"type": "unwrap_without_check",
"file": "/home/runner/work/panic-attack/panic-attack/benches/scan_bench.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "expect() in hot path (2 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/panic-attack/panic-attack/benches/scan_bench.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
7 tasks
hyperpolymath
added a commit
that referenced
this pull request
May 26, 2026
## Summary Root-cause fix for the CI failures that survived PR #39's merge. The readiness test \`readiness_d_gui_headless_runs\` and the \`Readiness\` workflow have been red on main since #39 hid \`Commands::Gui\` behind \`#[cfg(feature = \"gui\")]\` — the subcommand no longer exists in default builds, but the readiness test (which runs against default features) still invokes \`panic-attack gui --headless\`. The headless renderer is **pure text output** — it touches \`ReportFormatter\` and the report data structures, never \`eframe\` or \`egui\`. Moving it into a feature-independent module fixes the underlying contract: the subcommand should always exist; only the windowed renderer needs the feature. ## Changes | File | Change | |------|--------| | \`src/report/gui_text.rs\` (new) | \`run_headless\` lifted verbatim from \`gui::ReportGui::run_headless\`. Always compiled. | | \`src/report/gui.rs\` | \`run_headless\` removed (now in \`gui_text\`); header docstring updated. | | \`src/report/mod.rs\` | \`pub mod gui_text;\` always; \`pub mod gui;\` stays \`#[cfg(feature = \"gui\")]\` | | \`src/main.rs:472\` | drop \`#[cfg(feature = \"gui\")]\` from \`Commands::Gui\` variant | | \`src/main.rs:1703\` | match arm: \`--headless\` always calls \`gui_text::run_headless\`; non-headless path is feature-gated with a \`#[cfg(not(feature = \"gui\"))]\` arm that does \`anyhow::bail!(\"rebuild with --features gui\")\` | ## User-visible result Default build (\`cargo build\`): - \`panic-attack gui --headless report.json\` ✅ works (prints text panels) - \`panic-attack gui report.json\` → clear error: *"windowed GUI requires the \`gui\` feature; rebuild with \`cargo build --features gui\`, or pass --headless"* GUI build (\`cargo build --features gui\`): - Both modes work as before ## Test plan - [x] \`cargo build\` — default, OK - [x] \`cargo build --features gui\` — opt-in, OK - [x] \`cargo clippy --all-targets --features signing,http -- -D warnings\` — clean - [x] \`cargo clippy --all-targets --all-features -- -D warnings\` — clean - [x] \`cargo test --test readiness\` — **20 passed, 0 failed** (including \`readiness_d_gui_headless_runs\`) - [x] \`cargo fmt --check\` — clean - [x] Signed commit ## Why this is the principled fix - The readiness test stays meaningful on the MSRV-clean default build (it actually exercises the headless path). - The windowed GUI stays opt-in because eframe raises MSRV. - A user who tries the windowed mode without the feature gets a precise actionable error instead of clap's "unrecognized subcommand" stack trace. - No conditional skip, no \`#[ignore]\`, no workflow-level allow — the test runs every time and exercises real code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
eframe = "0.34"(and theeguichain it pulls) raises MSRV above 1.85.0, which conflicts with the project's declaredrust-version = "1.85.0"and breaks the MSRV CI job.Move
eframeinto a new opt-inguifeature so default + non-GUI optional builds stay MSRV-clean. Users who want the native viewer build with--features guion a newer toolchain.Changes (4 files, +12/-3)
Cargo.tomleframe = { ..., optional = true }; addgui = ["eframe"]featuresrc/report/mod.rspub mod gui+pub use gui::ReportGuisrc/main.rs:472Commands::Guiclap variantsrc/main.rs:1703Commands::Gui { .. }match arm.github/workflows/rust-ci.ymlcargo check --features signing,http(was--all-features)Why
--features signing,httpnot--all-featuresThe MSRV job should test what users actually consume on the declared MSRV.
signing(ed25519-dalek 2.1) andhttp(ureq 3.3) are both 1.85-compatible. The newguifeature explicitly raises MSRV — building it on 1.85 will fail, which is correct behaviour.Test plan
cargo check— default build OKcargo check --features signing,http— the new MSRV check command OKcargo check --features gui— opt-in build still workscargo clippy --all-features --all-targets -- -D warnings— cleancargo test --features signing,http --no-fail-fast— all 17 suites passcargo fmt --check— cleanFollow-up
Future improvement: add a
cargo check --features guijob pinned to a recent stable Rust so the GUI path stays buildable. Out of scope for this PR (single-concern unbreakage).🤖 Generated with Claude Code