Use Nix shell for reproducible builds:
nix developnix develop also exports FLUTTERDEC_BLUTTER_CMD to a Nix-managed flutterdec-blutter
wrapper, so --adapter-backend blutter can run without manual Blutter path wiring.
Common commands:
nix flake check
cargo fmt --all --check
./scripts/lint-shell.sh
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspaceCI-parity local check:
scripts/ci-check.sh
# or
nix run .#ci-checkcrates/flutterdec-cli: command parsing and dispatchcrates/flutterdec-core: orchestration, quality, reports, symbol map, engine fingerprintcrates/flutterdec-loader: APK/ELF loading and snapshot extractioncrates/flutterdec-adapter: adapter install/run boundariescrates/flutterdec-disasm-arm64: ARM64 disassemblycrates/flutterdec-ir: IR + CFGcrates/flutterdec-decompiler: pseudo-Dart emission and readability passesadapters/: adapter metadata and Python adapter implementationschemas/: adapter schemascripts/: regression tooling
When modifying decompiler behavior:
- add/adjust focused unit tests first
- run crate tests
- validate against real binaries (not only synthetic tests)
Real-binary regression helpers:
scripts/real-golden.shscripts/real-golden-matrix.sh- baselines now also capture
report_metrics.json, a focused subset ofreport.jsoncovering startup evidence, bootflow coverage, bootstrap-chain source/path counts, manifest-anchored startup-path counts, entrypoint recovery, and engine-symbol-ingestion metrics
decompile writes:
quality.json(quality gate results)report.json(semantic/fallback/metadata summaries)
Analysis profile and resolved engine options are written into report.json under analysis.
Core quality KPIs used to evaluate changes:
- semantic rewrite rates:
semantic_direct_calls,semantic_indirect_calls, and ratios - unresolved fallback pressure: selector fallback and dynamic/indirect fallback summaries
- symbol quality: placeholder replacement progress and generic name prevalence
- app-focused selection quality in capped runs: selected scope mix and preferred-package ratios
- metadata coverage: pool value/semantic/target symbol counters
- reproducibility: stable output under repeated runs for same input/options
CI runs on:
- pull requests
- pushes to
main - Linux and macOS runners
Workflow checks:
nix flake checkcargo fmt --checkscripts/lint-shell.shcargo clippywith warnings deniedcargo test --workspacecargo build -p flutterdec-cli --release
See: .github/workflows/ci.yml
Tag pushes matching v* build release CLI artifacts for Linux and macOS and publish them in a GitHub release via .github/workflows/release.yml.
Issue and PR templates live under .github/ and should be used for all external contributions.
Repository defaults also include .github/CODEOWNERS for review routing and .github/dependabot.yml for weekly Cargo/Actions update PRs.
- keep commits atomic
- use commit format:
type(scope): description - keep docs updated when behavior changes
- avoid broad refactors mixed with feature logic in a single commit
- internals: how-it-works.md
- architecture: architecture.md
- research constraints: research-decisions.md
- project context/history: ../context.md