Skip to content

fix(quality): explain strict gate failures#72

Merged
caverav merged 1 commit into
mainfrom
fix/quality-gate-diagnostics
Apr 25, 2026
Merged

fix(quality): explain strict gate failures#72
caverav merged 1 commit into
mainfrom
fix/quality-gate-diagnostics

Conversation

@caverav

@caverav caverav commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • improve strict quality-gate failure diagnostics after artifact generation
  • explain why low-confidence runs fail and point users at the generated artifacts
  • include exploratory rerun hints for placeholder-heavy libapp.so cases

Testing

  • nix develop -c cargo test -p flutterdec-core --quiet
  • reproduced issue bug:placeholder if-count exceeded threshold #71 on the reporter sample input from https://litter.catbox.moe/xz6tvw.7z
  • verified origin/main and this branch both produce the same quality outcome on that input:
    • placeholder_ifs = 1691
    • indirect_call_ratio = 0.12557602191154899
    • disassembly_ratio = 1.0
    • failure remains placeholder if-count exceeded threshold
  • verified the only behavior change is the CLI error message, which now explains that artifacts were written and suggests next steps

@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown

Walkthrough

The pull request enhances error reporting for quality-gate failures in the decompilation pipeline. When a quality gate fails, the error message now includes detailed diagnostic information: paths to quality.json and report.json artifacts, specific failure reasons, numeric metrics (placeholder IFs, unresolved control flow, indirect call ratio, disassembly ratio), and contextual notes based on input type and backend configuration. A new formatting helper function generates this comprehensive message, and a corresponding unit test validates the output for strict mode placeholder IF-count rejections.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description covers the summary and testing sections comprehensively, but the Validation and Scope sections required by the template are not addressed. Add the Validation section with checkboxes confirming cargo fmt, clippy, and test results, and address the Scope section regarding atomic commits and documentation updates.
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(quality): explain strict gate failures' clearly and concisely describes the main change: improved error messaging for quality gate failures.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (2)
crates/flutterdec-core/src/pipeline/runners/tests.rs (1)

31-83: LGTM — test coverage matches the formatter branches.

The constructed QualityReport/SymbolQualityCounts exercise each conditional branch in format_quality_gate_failure_message (failures non-empty, non-APK input, internal backend, all-placeholder symbols) and the assertions match the literal strings produced by the formatter (including the hardcoded --max-placeholder-ifs 999999 example). The numeric inputs (placeholder_ifs=1691, indirect_call_ratio≈0.1256, placeholder=5394) faithfully reproduce the scenario from PR #71.

One minor observation: the loaded_adapter_kind = "dynamic_snapshot_string_model_v1" branch is exercised but not explicitly asserted. Optional — consider adding assert!(msg.contains("adapter kind is dynamic_snapshot_string_model_v1")); to lock that note in too.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/flutterdec-core/src/pipeline/runners/tests.rs` around lines 31 - 83,
The test exercises the branch that includes the loaded_adapter_kind string but
doesn't assert it; update the test function
quality_gate_failure_message_explains_strict_placeholder_rejection to add an
assertion that msg contains the adapter-kind note emitted by
format_quality_gate_failure_message (referencing the loaded adapter string
"dynamic_snapshot_string_model_v1" and the message text produced by
format_quality_gate_failure_message), e.g. add assert!(msg.contains("adapter
kind is dynamic_snapshot_string_model_v1")); so the test explicitly locks that
branch.
crates/flutterdec-core/src/pipeline/runners.rs (1)

148-207: Diagnostic message reads well; consider deriving the example threshold from opt.

The composition is clear and each branch maps cleanly to the test. One optional improvement: the suggested relaxed flags are hardcoded constants (999999, 1.0, 0.0). If you thread &DecompileOptions (or just the relevant gate values) into this helper, you could surface the current configured thresholds alongside the relaxed example, e.g. "current --max-placeholder-ifs N (observed M); for exploratory runs try …". That would make the hint more actionable when users have already customized gates. Not blocking — the static example is still useful.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/flutterdec-core/src/pipeline/runners.rs` around lines 148 - 207, The
diagnostic currently prints hardcoded example thresholds inside
format_quality_gate_failure_message; change the function signature to accept the
current gate config (e.g., &DecompileOptions or a small struct with
max_placeholder_ifs, max_unresolved_cf, max_indirect_call_ratio,
min_disassembly_ratio) and use those values when constructing the hint text so
the message shows the user's current thresholds (refer to the DecompileOptions
fields or new small GateValues struct) alongside observed metrics (use
report.placeholder_ifs, report.unresolved_cf, report.indirect_call_ratio,
report.disassembly_ratio) and then print the suggested relaxed flags with the
example values — update all call sites that invoke
format_quality_gate_failure_message to pass the options or gate values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/flutterdec-core/src/pipeline/runners.rs`:
- Around line 148-207: The diagnostic currently prints hardcoded example
thresholds inside format_quality_gate_failure_message; change the function
signature to accept the current gate config (e.g., &DecompileOptions or a small
struct with max_placeholder_ifs, max_unresolved_cf, max_indirect_call_ratio,
min_disassembly_ratio) and use those values when constructing the hint text so
the message shows the user's current thresholds (refer to the DecompileOptions
fields or new small GateValues struct) alongside observed metrics (use
report.placeholder_ifs, report.unresolved_cf, report.indirect_call_ratio,
report.disassembly_ratio) and then print the suggested relaxed flags with the
example values — update all call sites that invoke
format_quality_gate_failure_message to pass the options or gate values.

In `@crates/flutterdec-core/src/pipeline/runners/tests.rs`:
- Around line 31-83: The test exercises the branch that includes the
loaded_adapter_kind string but doesn't assert it; update the test function
quality_gate_failure_message_explains_strict_placeholder_rejection to add an
assertion that msg contains the adapter-kind note emitted by
format_quality_gate_failure_message (referencing the loaded adapter string
"dynamic_snapshot_string_model_v1" and the message text produced by
format_quality_gate_failure_message), e.g. add assert!(msg.contains("adapter
kind is dynamic_snapshot_string_model_v1")); so the test explicitly locks that
branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 448af212-7f71-46ce-b50b-854d01078d48

📥 Commits

Reviewing files that changed from the base of the PR and between 08b8ea3 and b9162bd.

📒 Files selected for processing (2)
  • crates/flutterdec-core/src/pipeline/runners.rs
  • crates/flutterdec-core/src/pipeline/runners/tests.rs

@caverav caverav merged commit a408817 into main Apr 25, 2026
5 checks passed
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