Skip to the content.

Code Audit Protocol

This protocol defines how FastMediaSorter audits Android code for correctness, readability, memory safety, lifecycle safety, concurrency safety, and performance.

Scope:

Out of scope:

Goals

Core rule

Audit in layers:

  1. prevent
  2. reproduce
  3. explain
  4. gate

Do not jump straight to profiler sessions for every change. First use the cheapest proof that can reject a bad change.

Evidence ladder

Use the lowest-cost proof that matches the risk.

  1. Static code review
  2. Existing quality gates
  3. Targeted compile or resource validation
  4. Focused unit test
  5. Debug runtime detection
  6. Device smoke
  7. Repeatable benchmark
  8. Trace or heap analysis

Examples:

Finding severity taxonomy

Tag every finding so a leaked Activity is never weighed the same as an extra !!.

Rule:

Audit triggers

Run the protocol when any of these is true:

Layer 1 - Static architecture and readability audit

Check these first:

Class-size methodology - rank by responsibility, not by raw line count:

Readability checks:

Project hooks already present:

Layer 2 - Lifecycle, coroutine, and concurrency audit

For every coroutine or Flow change, verify:

Concurrency correctness (beyond leaks):

Current project gates:

Deterministic lifecycle probe (no profiler needed):

Review questions:

Layer 3 - Memory ownership audit

Focus on object retention, cache growth, and heavy-resource release.

Check:

Register/unregister symmetry (high-value for this MediaStore-heavy app):

ExoPlayer / Media3 ownership:

Glide / bitmap ownership:

Shared-state ownership:

Debug detector:

Project integration already present:

Required leak scenarios for critical flows:

Layer 4 - Database and Room audit

Room is core to the stack (2.7.0). Audit every entity, DAO, query, or migration change.

Check:

Review questions:

Layer 5 - Main-thread and startup audit

Check for avoidable work on the main thread:

Current project hooks:

Required questions:

Layer 6 - Performance audit

Use two levels:

Static performance review:

Measured performance review:

Preferred tooling:

Rule:

Layer 7 - Release-build and R8 correctness audit

A passing debug build does not prove the shipped artifact is correct. For changes that touch reflection, serialization, DI graphs, manifests, or dependencies, verify on the minified release/target variant.

Check:

Rule:

Layer 8 - Mechanical gates

If a review comment appears repeatedly, convert it into a gate.

Preferred order:

  1. project script gate
  2. custom Android Lint check
  3. benchmark threshold

Use script gates for fast pattern enforcement. Use custom Lint when the rule is structural and should appear directly in IDE feedback. Use benchmark thresholds when the problem is quantitative.

Recommended future custom Lint rules for this project:

Recommended CI/CD automated dynamic analysis additions:

Standard audit procedure for a change

  1. Classify the change and assign an expected severity ceiling.
  2. Pick the lowest-cost evidence.
  3. Run static architecture and readability review.
  4. Run lifecycle, concurrency, memory, and Room review if coroutines, shared state, listeners, player, cache, database, or startup are touched.
  5. Run project gates.
  6. Run the cheapest validation command from docs/BUILD_TEST_FAST_PATH.md.
  7. If risk remains, run debug runtime checks (LeakCanary, StrictMode, “Don’t keep activities”).
  8. If the change touches reflection, DI, manifests, or dependencies, prove it on a minified release/target variant.
  9. If regression is observed, capture benchmark evidence.
  10. If the benchmark fails or the issue is still unclear, capture Perfetto trace, allocation trace, or heap dump.
  11. Convert recurring findings into a permanent gate.

Standard audit checklist for PR review

Use this checklist in review comments or self-review; tag each finding with a severity:

Standard incident procedure

For crash, ANR, leak, OOM, or jank:

  1. classify severity and reproduce on the narrowest possible scenario
  2. capture logs
  3. capture LeakCanary evidence for retention issues
  4. capture benchmark numbers for reproducible slowness
  5. capture Perfetto trace for unexplained slowness or jank
  6. reduce to one owner, one resource, one lifecycle edge, one race, or one hot path
  7. add or tighten a gate so the same class of issue becomes cheaper to catch next time

FastMediaSorter current baseline

Already present:

Recommended next additions:

  1. extend perf coverage beyond standard if a flavor-specific hotspot appears
  2. wire selected perf commands into CI or managed-device automation when the local flow stabilizes
  3. ratchet benchmark JSON summaries once representative device baselines are committed

Repo commands and anchors

Useful local commands:

.\a.ps1 fk
.\a.ps1 fr
.\a.ps1 fc
.\a.ps1 fu
.\a.ps1 mb
.\a.ps1 gbp
.\a.ps1 adb launch
.\a.ps1 adb log -Tail 400 -Grep "FATAL|ANR|Sxxxx"
pwsh -NoProfile -File scripts/quality/assert-globalscope.ps1 -Gate
pwsh -NoProfile -File scripts/quality/assert-unsafe-collect.ps1 -Gate
pwsh -NoProfile -File scripts/quality/assert-listener-symmetry.ps1 -Gate
pwsh -NoProfile -File scripts/quality/measure-hotspots.ps1
pwsh -NoProfile -File scripts/quality/audit-shared-state-writers.ps1

Important code anchors:

External references

These references informed the protocol as checked on 2026-06-26:

Reference URLs: