# ADR 0002: Method Inventory - Status: accepted - Date: 2026-10-01 - PR: #4 ## Context A result listener only sees methods that have mutation results. The specification (4.4) demands that methods without results stay visible and that a report never claims a completeness it cannot prove. It also demands an unambiguous origin of the analysed bytes (3.4) and no invented complexity (5.3). ## Decision **Scope.** The classes PIT selected for mutation, `ReportOptions.getMutationClassPaths().code()`. They already respect `targetClasses` and `excludedClasses`. **Code roots.** A class is read only from the code roots, by PIT's own rule: the classpath elements matching `codePaths` if configured, otherwise every directory that is not a test output. Dependency archives are never code roots. This replaces ADR 0001's "first classpath element", which could read a selected class from a dependency JAR. **Origin.** A class is read from every code root that holds it. Identical copies are one origin; differing copies are `ambiguous-class-file`, since nobody can tell which one PIT mutated. A selected class that cannot be read is `class-file-not-found`. Either makes the scope incomplete. **Inventory.** Every method with a body of every readable selected class. Abstract and native methods have no body and are left out; they get no complexity. **Methods JaCoCo filters.** JaCoCo analyses every method with code and drops only what its filters remove. A declared method with code that JaCoCo does not report on the very same bytes has therefore been filtered — proven, not guessed. It is `EXCLUDED` with the reason `jacoco-filtered:`, the hint read from the class file: `bridge`, `synthetic`, `generated-annotation`, or `other` (for example enum `values()` or record accessors). **Methods PIT does not mutate.** A method whose name matches PIT's `excludedMethods` lies outside the selection of the run. It is `EXCLUDED` with the reason `pit-excluded-method:` and keeps its complexity. **Joining.** Only by `MethodId` (class, JVM name, descriptor), never by name or line. Results whose class is unreadable carry that class's reason; results without inventory method carry `method-not-in-inventory`. Both are `COMPLEXITY_UNAVAILABLE` and never dropped. ## Consequences - Every selected method appears in the report exactly once, with a score or a reason. - A strict gate (step 6) can fail on an incomplete scope and on unavailable complexity as analysis errors. - `jacoco-filtered:other` covers several JaCoCo filters; the report names no finer reason for them. A wrong exclusion would need JaCoCo to report a method it should have filtered, which a JaCoCo upgrade with changed filters could do; the JaCoCo version is in every report.