All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.2.2] - 2026-10-10

Fixed

  • Resolve descendant coverage ownership after out-of-order process spawn traces, preserving loading-file attribution and detecting unfinished descendants.

[0.2.1] - 2026-10-03

Added

  • Verified native binaries for Linux and macOS on x86_64 and ARM64, automatic installation, and promotion of tested CI artifacts into stable releases.
  • A worktree-isolated native daemon with prewarmed disposable BEAM workers.

Changed

  • Reuse instrumented BEAMs, validated fingerprints, coverage unions, and bulk filesystem reads to reduce incremental coverage overhead.
  • Keep mixed production and test edits focused with runtime-attributed coverage, including file-loading ownership and incremental shared-setup refreshes.

Fixed

  • Save attributed coverage baselines before enforcing the coverage gate.
  • Accept Erlang compiler warnings when instrumenting Elixir modules.

[0.2.0] - 2026-09-29

Added

  • Runtime-attributed line coverage for mix test.qlover on OTP 29 and Elixir 1.20.2–1.20.x: changed test files replace their own hits while unchanged files' valid hits remain reusable. Coverage loss fails without advancing the baseline.
  • Versioned executable-line inventories, separate suite-level evidence, spawn ancestry for async tasks, source/dependency fingerprints, atomic cache writes, attributed HTML reports, and a zero-test gate for unreferenced new modules.
  • End-to-end regressions for edits, deletions, async tasks, lifecycle callbacks, worktree caches, source shifts, and missing coverage; native-cover parity and a repeatable small-fixture benchmark.

Changed

  • Legacy baselines receive one full attributed refresh on supported runtimes. Other Elixir runtimes retain the conservative native-cover path.
  • Filtered or skipped test executions cannot establish reusable attributed coverage; ambiguous worker hits are not reused as test-file evidence.

[0.1.4] - 2026-09-21

Added

  • mix test.qlover --dry to print the planned test files and their selection reasons without executing tests or updating the coverage baseline.

Fixed

  • Silence cover's Analysis includes data from imported files notice, which the incremental gate emitted once for every proven module.

[0.1.3] - 2026-09-18

Added

  • mix test.qlover --no-stale to force a full test-suite rerun and refresh the coverage baseline.

[0.1.2] - 2026-09-18

Fixed

  • Treat test_helper.exs as a suite-wide input: no missing-attribution warning, and helper additions, edits, or deletions always require a full run, including when tracer records exist.
  • Round coverage percentages down to two decimals in mix test.qlover, so coverage below 100% displays as 99.99% rather than 100.00%. Threshold checks still use exact counts.

[0.1.1] - 2026-09-18

Added

  • ./release to bump the version (patch by default), update the changelog, commit and push the release tag, and publish the GitHub release that triggers Hex package and documentation publishing.
  • Per-invocation test counts: qlover: ran X tests; didn't run Y tests., including failed and unchanged runs, with ExUnit skips/exclusions listed separately. Per-file counts follow edits and deletions and are shared with cached baselines.
  • Automatic releases: pull-request quality checks, rolling dev GitHub packages on successful pushes to main, and Hex package/docs publishing for non-prerelease GitHub releases whose tags match VERSION.
  • Per-test-file attribution: test-only edits gate incrementally via a compiler-tracer reference graph (Qlover.Tracer, enabled with elixirc_options + test_elixirc_options) with transitive lib closure, focused expansion runs, and fresh-export union. Non-code fixture changes and tests without reference data still fall back to the full suite, fail-closed.
  • Baseline format v4 (non-test gate inputs, per-test-file hashes, reference snapshot, lib edge graph). Older baselines are treated as invalid and trigger one full re-baseline.
  • Beam hashing ignores path-volatile chunks (Dbgi, Docs, CInf, ExCk, Line): identical sources hash equally in any checkout and pure line shifts need no fresh proof. Unreadable beams fall back to raw content hashes.
  • MIX_ENV=test guard on both tasks (same rule as mix test itself), with preferred_envs setup documented for host projects.
  • Second scratch export (--expansion-export) for the focused expansion run; both exports are unioned (same code version) and cleaned up. The expansion run passes --no-stale so host test aliases that inject --stale cannot silently empty its explicit file list, and compiled support files are excluded from it (requiring them would reload plain code over instrumented code and zero their coverage).
  • examples/demo: runnable 48-test shop plus compare.sh measuring full-suite vs incremental across 11 scenarios (table in README.md); exits non-zero on any verdict mismatch. Now also carries a hostile test: ["test --stale"] alias mirroring the labqoat convention, proving qlover's explicit --no-stale-first argv cannot be shrunk by it.
  • Shared content-addressed cache (QLOVER_CACHE_DIR, default ~/.cache/qlover): snapshots write through under content keys, missing baselines fetch and heal locally, tracer records merge across directories. Verified with a cross-directory gating test.

[0.1.0] - 2026-09-17

Added

  • mix qlover gate task with three modes: --eligible, --write-baseline, and default gating of changed beams on fresh line coverage alone.
  • mix test.qlover single-command runner: stale + gate when eligible, full + snapshot otherwise, with test-arg passthrough, managed-flag rejection, and fail-closed subprocess exit codes. cover.sh delegates to it.
  • Hermetic test suite (33 tests) covering baseline roundtrip, eligibility, gate-input drift, changed-beam pass/reject, missing export, deleted-beam pruning, single-command orchestration, and fail-closed error paths.
  • Hex packaging metadata, Apache-2.0 license, and documentation.