Skip to content

Framework under-assertion: what the coverage + mutation round actually left, after #434 #453

Description

@Yaraslaut

What this replaces

Four issues — #409 (offline coverage), #410 (forms coverage), #431 (core survivors), #432 (forms survivors) — were split out of one measurement round on 2026-09-03. Each has since had its own acceptance criteria withdrawn, by the same two events, and each carries a comment saying so. This issue is the surviving work; each original stays readable at its link with its evidence and its triage history intact.

The two events.

  1. The percentage clauses were superseded by their own authors (2026-09-03, identical comments on coverage: include/morph/offline is the library's worst subsystem at 85.20%, and one header inside it reads 57.04% #409 and coverage: include/morph/forms sits at 94.37%, and forms.hpp alone holds 36 of the subsystem's 41 unhit lines #410). The first mutation run scored 64.06% against a library measuring 95.69% lines — the gap between executed and would be noticed if it were wrong. A percentage target is what produced a suite on the wrong side of it.
  2. The survivor lists were invalidated by mutation: a Mull survivor is not evidence of a missing assertion — four sampled survivors all turn the suite red when applied by hand #434 (mechanism confirmed 2026-09-04, landed in PR mutation: confirm the false-positive mechanism -- cxx_remove_void_call is broken for member-call sites #448). Mull 0.34.0's cxx_remove_void_call does not remove the call it claims to, for member/operator call sites — confirmed by disassembling the mutant in a single-TU build. That is 148 of the 352 survivors, and it is the shape of remote.hpp's reply(...)/complete(...) and bridge.hpp's stored-callback sites — 211 of the 352 between them.

Both "start here" sections are therefore closed: #431's twenty deletable replies are tool artifacts, and #431/#432's named boundary sites are already killed (scripts/mutation_survivors.json, runs[1].movement_against_baseline).

What is actually left

A. The survivors from mutator families #434 does not implicate. runs[1].survivors_by_mutator: cxx_replace_scalar_call 97, cxx_init_const 26, cxx_assign_const 23, cxx_add_to_sub 13, cxx_gt_to_ge 8, other 37 — ~204 of the 352. A boundary-comparison mutator was independently confirmed in #434's investigation to mutate and kill correctly, so this family's survivors should still be read as real. Classify each: killed, equivalent with a reason, or side-channel. None left unclassified.

B. The shape, checked by reading rather than by tooling. "A test whose name claims a boundary and whose body tests the middle" was found in wire.hpp by reading the test, not by trusting a survivor — the case named "decode accepts an envelope at the size limit boundary" asserted a 1 KiB payload against an 8 MiB cap. The forms boundaries deserve the same read; it needs no mutation tooling and is unblocked today.

C. offline's coverage, re-measured now that the denominator is fixed. #409's blockers are both closed (#403 coverage.sh profiling, #440 the SQLite3 IMPORTED_LOCATION fix), and its own text says the honest first step is to re-measure rather than to start writing tests. sqlite_offline_queue.hpp's 57.04% was measured with its own test binary unprofiled; record both the before and after numbers, so it is visible how much of the gap was reporting and how much was tests. If it barely moves, morph_offline_sqlite_tests is thin, which is a worse finding than the percentage suggested.

D. The codecov components neither subsystem has. codecov.yml today carries framework, ladder and one component per rung. Neither include/morph/offline nor include/morph/forms has one, so neither can regress into a red status. Add them with targets derived from measured ceilings, after C.

The constraint that carries over unchanged

Do not chase the number. A mutant killed by an assertion written to kill that mutant, on a path nobody cares about, is worse than a survivor — it is a test with no reason to exist. Each new test must be justifiable from the behaviour, with the survivor as evidence the assertion was missing. Classifying a survivor equivalent with a stated reason is a valid outcome; the run already found 11.

Not in scope

#434 (the Mull defect itself, still open with an upstream filing outstanding) and #408 (the CI gate) stay separate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: ciSubsystem: cienhancementNew feature or requesttriage: validWell-framed; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions