C2 (#177): cut MediaProbe's two-probe merge into a seam, and ask which probe wins #187

Merged
JMR-dev merged 3 commits from test/mediaprobe-merge-seam into main 2026-09-02 04:44:21 +00:00
JMR-dev commented 2026-09-02 02:59:02 +00:00 (Migrated from github.com)

Closes #177. Stacked on #186.

probe() runs MediaExtractor and FFprobe independently and merges the two, and every rule in that merge is a decision nothing held. The reason is structural rather than an oversight: RemuxTest drives the whole thing on a device against committed fixtures, but only ever with one probe answering and the other agreeing or also failing. Nothing on any source set can arrange for a real extractor and a real FFprobe to disagree, so every elvis in the merge was taken in one direction and never the other.

The seam

internal fun merge(Extracted?, FFprobeInfo?): InputProbe, pulled out of probe() whole — probe() now reads the two probes, merges, and keeps the log. FFprobeInfo becomes internal alongside it; Extracted already was, with a KDoc giving this exact reason, and FFprobeInfo simply never got the same treatment. Half a signature being private is what made the function unnameable from a test.

Eleven tests, and the mutations that hold them

rule mutation
an image verdict beats a real video codec demote the isImage arm below the video arm
the extractor wins on codecs flip the elvis to FFprobe-first
duration is the larger reading replace maxOf with extractor-first
dimensions prefer the extractor flip the width elvis
no recognised stream is unreadable narrow the guard to extracted == null && info == null

All five red, then restored.

One mutation I tried first was semantically equivalent — moving the image arm above the both-null arm changes nothing for any reachable input — so it stayed green. It is recorded rather than counted: a green mutation is evidence only when the mutation is a real change.

The last row is the arm the ticket was filed for: parsed, carrying no stream either probe recognised — what a container holding only subtitles looks like. Its input was already being constructed elsewhere in the suite (MediaProbeTrackWalkTest calls extractedFrom(emptyList()) and gets exactly it) and had never been handed to the merge.

Numbers

568 → 579 JVM tests, 0 failures. MediaProbe: 35 → 24 missed lines, 72 → 40 missed branches.
Line 2103/2348 → 2173/2348, branch 1029/1340 → 1091/1342.

The branch denominator moved by two, and it is the seam that moved it. Stated separately from the numerator on purpose — CLAUDE.md's coverage entry has a documented history of explaining its own numbers wrongly.

🤖 Generated with Claude Code

Closes #177. Stacked on #186. `probe()` runs `MediaExtractor` and FFprobe independently and merges the two, and **every rule in that merge is a decision nothing held**. The reason is structural rather than an oversight: `RemuxTest` drives the whole thing on a device against committed fixtures, but only ever with one probe answering and the other agreeing or also failing. Nothing on any source set can arrange for a real extractor and a real FFprobe to *disagree*, so every elvis in the merge was taken in one direction and never the other. ### The seam `internal fun merge(Extracted?, FFprobeInfo?): InputProbe`, pulled out of `probe()` whole — `probe()` now reads the two probes, merges, and keeps the log. `FFprobeInfo` becomes `internal` alongside it; `Extracted` already was, **with a KDoc giving this exact reason**, and `FFprobeInfo` simply never got the same treatment. Half a signature being private is what made the function unnameable from a test. ### Eleven tests, and the mutations that hold them | rule | mutation | |---|---| | an image verdict beats a real video codec | demote the `isImage` arm below the video arm | | the extractor wins on codecs | flip the elvis to FFprobe-first | | duration is the larger reading | replace `maxOf` with extractor-first | | dimensions prefer the extractor | flip the width elvis | | no recognised stream is unreadable | narrow the guard to `extracted == null && info == null` | All five red, then restored. **One mutation I tried first was semantically equivalent** — moving the image arm above the both-null arm changes nothing for any reachable input — so it stayed green. It is recorded rather than counted: a green mutation is evidence only when the mutation is a real change. The last row is the arm the ticket was filed for: parsed, carrying no stream either probe recognised — what a container holding only subtitles looks like. Its input was already being constructed elsewhere in the suite (`MediaProbeTrackWalkTest` calls `extractedFrom(emptyList())` and gets exactly it) and had never been handed to the merge. ### Numbers 568 → 579 JVM tests, 0 failures. `MediaProbe`: 35 → 24 missed lines, 72 → 40 missed branches. Line 2103/2348 → **2173/2348**, branch 1029/1340 → **1091/1342**. The branch **denominator** moved by two, and it is the seam that moved it. Stated separately from the numerator on purpose — `CLAUDE.md`'s coverage entry has a documented history of explaining its own numbers wrongly. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.