Repository navigation
Consider moving the coverage-gap mechanism into the edge-coverage machinery #52
Description
Context
As of d55ac91 (on weighted-pool-scheduler / PR #43), the coverage-gap plugin no longer receives a bespoke Set<UInt32> from the core. Instead:
- the core
.endevent carries a genericexecutionContext: RawExecutionContext(a run-spanning summary assembled from the installed probes); CoverageProbecontributes its union of covered edges underCoverageProbeKeyviacontributeCampaignSummary(to:);- the gap plugin (in the edge-coverage layer) reads
executionContext[CoverageProbeKey.self]?.coverageand runsCoverageGapDetector.
That removed the fictional generic (AggregateIndexReporting / totalCoveredIndices) and the core no longer names coverage to feed .end.
The remaining itch
The gap mechanism is still structured as a generic plugin on the engine's .end bus that happens to read a coverage key. It's arguably not where it belongs: gap analysis is intrinsically edge-coverage-specific (it interprets the indices as PCs/edges, symbolizes them via DWARF + the pc-table, and reports uncovered source regions). It only makes sense when edge coverage is the active signal, yet it currently rides a signal-agnostic seam (.end + RawExecutionContext) to get there.
So there's a lingering question of whether gap detection should instead be owned by the edge-coverage machinery itself rather than expressed as a plugin reading a key off a generic campaign summary.
Options to weigh (no decision yet)
- Status quo (
d55ac91): generic.endsummary + gap plugin readsCoverageProbeKey. Pro: uniform plugin model, core stays signal-agnostic. Con: the "generic".endsummary currently has exactly one producer and one consumer, both edge-coverage — the generality may still be fictional (same smell as Corpus shouldn't know about schedule bytes #51 and the originalAggregateIndexReporting). - Edge-coverage owns gap end-to-end: the edge-coverage module pairs the
CoverageProbewith gap detection directly (e.g. a probetearDown/campaign hook, or a coverage-module-internal end-of-run step), and drops gap's dependence on the core.endevent. Open problems to solve: gap detection is async and needs to recordIssues (the plugin.end→ action →Issue.recordpath is what provides both today), and with parallel engines each engine currently runs gap on its own coverage at.end— any new home must preserve that. - Something in between: keep
.endas the trigger but have the edge-coverage layer self-wire the probe↔gap pairing per engine (shared accumulator), so the core event carries no coverage at all.
Acceptance / definition of done
- Decide whether the generic
.endcampaign-summary seam earns its keep or whether gap should move fully into the edge-coverage machinery. - Whatever the choice: preserve current behavior (per-engine gap analysis, async detection, issues recorded at the right source locations), and keep
FuzzCorefree of coverage-specific concepts.
Related
- Corpus shouldn't know about schedule bytes #51 (corpus shouldn't know about schedule bytes) — sibling "stop leaking a specific mode into the generic core" cleanup.
- PR Engine-owned weighted mutation pool + feature-ownership culling #43 — the signal-agnostic FuzzCore split this builds on.
Activity