Summary
Merge-CoberturaClassesByFilename unions the class-level <lines> of all <class> elements sharing
a filename correctly, but never merges the corresponding <methods> subtrees. It then recomputes
line-rate over the descendant axis .//lines/line, which sees the correct union plus only the
primary class's method-level lines. The emitted per-file line-rate is therefore a blend of two
different denominators and matches neither. This is distinct from, and additional to, issue #441.
Environment
- OS/version: n/a (PowerShell post-processing defect, reproducible from committed data)
- Python version: n/a
- Command/flags used:
scripts/vscode/Invoke-MSTestWithCoverage.ps1 post-processing path
- Data source or fixture:
docs/features/active/2026-08-06-quickfiler-high-confidence-queue-init-stall-424/evidence/qa-gates/coverage-final.cobertura.xml
Steps to Reproduce
- Inspect
Merge-CoberturaClassesByFilename in
scripts/vscode/Invoke-MSTestWithCoverage.Helpers.ps1, beginning at :167.
- Observe the class-level
<lines> union at :217-268. It correctly takes max hits per line number
across every <class> element sharing a filename.
- Observe that the
<methods> subtrees of the non-primary group members are not merged into the
primary class element.
- Observe the rate recomputation, which selects over the descendant axis
.//lines/line. That axis
matches both the merged class-level <lines> and the unmerged, primary-only <methods>/<method>/<lines>/<line>.
- Verify arithmetically against
QfcHomeController.Iteration.cs in the committed report: the true
per-file figure computed from the class-level union alone is 45/56 = 80.36%, while the emitted
attribute is 0.8625, which is exactly 69/80 - the blended numerator and denominator.
- Cross-check the recipe independently:
#424's own delta evidence
(docs/features/active/2026-08-06-quickfiler-high-confidence-queue-init-stall-424/evidence/qa-gates/coverage-delta.2026-08-07T00-48.md:10,41)
arrived at the class-level-only computation, confirming that the attribute is not the right source.
Expected Behavior
The emitted per-file line-rate should equal the rate computed from the merged class-level <lines>
set alone: distinct line numbers, max hits per number, hit count over total count.
Actual Behavior
The emitted line-rate mixes the merged class-level line set with the primary class's method-level
line set, producing a figure that corresponds to neither the true per-file rate nor any single
class's rate.
Logs / Screenshots
Impact / Severity
Any consumer reading the per-file line-rate attribute gets a wrong number, and the error is not in
a consistent direction because it depends on how much of a file's coverage sits in the primary class
versus its siblings. Epic #136 gates every one of its fifteen children on a per-file line rate, so an
uncorrected attribute would produce false passes and false failures across the whole epic.
Source
From: docs/features/potential/2026-08-07-merge-cobertura-classes-blends-union-with-primary-methods.md
Summary
Merge-CoberturaClassesByFilenameunions the class-level<lines>of all<class>elements sharinga
filenamecorrectly, but never merges the corresponding<methods>subtrees. It then recomputesline-rateover the descendant axis.//lines/line, which sees the correct union plus only theprimary class's method-level lines. The emitted per-file
line-rateis therefore a blend of twodifferent denominators and matches neither. This is distinct from, and additional to, issue #441.
Environment
scripts/vscode/Invoke-MSTestWithCoverage.ps1post-processing pathdocs/features/active/2026-08-06-quickfiler-high-confidence-queue-init-stall-424/evidence/qa-gates/coverage-final.cobertura.xmlSteps to Reproduce
Merge-CoberturaClassesByFilenameinscripts/vscode/Invoke-MSTestWithCoverage.Helpers.ps1, beginning at:167.<lines>union at:217-268. It correctly takes max hits per line numberacross every
<class>element sharing afilename.<methods>subtrees of the non-primary group members are not merged into theprimary class element.
.//lines/line. That axismatches both the merged class-level
<lines>and the unmerged, primary-only<methods>/<method>/<lines>/<line>.QfcHomeController.Iteration.csin the committed report: the trueper-file figure computed from the class-level union alone is 45/56 = 80.36%, while the emitted
attribute is
0.8625, which is exactly 69/80 - the blended numerator and denominator.#424's own delta evidence(
docs/features/active/2026-08-06-quickfiler-high-confidence-queue-init-stall-424/evidence/qa-gates/coverage-delta.2026-08-07T00-48.md:10,41)arrived at the class-level-only computation, confirming that the attribute is not the right source.
Expected Behavior
The emitted per-file
line-rateshould equal the rate computed from the merged class-level<lines>set alone: distinct line numbers, max hits per number, hit count over total count.
Actual Behavior
The emitted
line-ratemixes the merged class-level line set with the primary class's method-levelline set, producing a figure that corresponds to neither the true per-file rate nor any single
class's rate.
Logs / Screenshots
QfcHomeController.Iteration.cs- true per-file45/56 = 0.8036; emitted attribute0.8625 = 69/80. Confirmed againstscripts/vscode/Invoke-MSTestWithCoverage.Helpers.ps1:167(function start) and
:217-268(the correct union). Discovered during preparation research forissue Feature: quickfiler-collection-controller-coverage #454 (epic Feature: quickfiler-80-per-file-coverage #136, child F11); full analysis in
docs/features/active/2026-08-07-quickfiler-collection-controller-coverage-454/research/coverage-harness-contract.mdsection A.
Impact / Severity
Any consumer reading the per-file
line-rateattribute gets a wrong number, and the error is not ina consistent direction because it depends on how much of a file's coverage sits in the primary class
versus its siblings. Epic #136 gates every one of its fifteen children on a per-file line rate, so an
uncorrected attribute would produce false passes and false failures across the whole epic.
Source
From: docs/features/potential/2026-08-07-merge-cobertura-classes-blends-union-with-primary-methods.md