L2 asserts the three D2 counters are printed when every one of them is zero. That
proves the format string mentions them; it does not prove a real value makes it
through. Two things sit between the counter and the operator:
`segmentRecallBudget` slices the hits array — and `slice` does not copy
non-enumerable properties, which is what all the counters are;
`lastRecall` is assembled separately from the log line.
So "correct in the returned array" and "visible to an operator" are different
claims, and only the second one is what D2 is about.
## Fixture
Three blocks on separate axes, query mostly on axis 0, default `minScore`:
block0 cosine ~0.95 -> hit
block1 cosine ~0.30 -> skippedScore
block2 cosine 0 -> skippedNoEvidence
Measured through the real plugin path (apply + commit + contextForStep):
log : ... skipped=0 skippedDim=0 skippedScore=1 skippedNoEvidence=1 truncated=0 err=- ...
last: {"mode":"hybrid","skipped_score":1,"skipped_no_evidence":1,"truncated":0,...}
All three destinations are non-empty at once, so the criterion cannot pass by
accident of an empty fixture.
## Mutation
Removing the three fields from the log line turns both criteria red:
not ok 2 - L2: debugLog=true emits one line covering recall, budget, degradation and injection
not ok 4 - L2b: non-zero drop counters appear in the log and in last_recall
L2 alone would already catch that; L2b is what catches the other half — a counter
that survives the log formatting but dies in the slice, or lands in one surface
and not the other.
Gates: npm test 299/299 (0 skipped).