Duplicate Collector Strategy
A CollectorStrategy that finds near-duplicate propositions and marks all but the strongest member of each duplicate group.
Clusters from PropositionRepository.findClusters can overlap (a proposition may appear in more than one cluster), so survivors are picked once per connected component across all clusters. Within each component the survivor is the proposition with the highest effective confidence, with reinforcement count and id as tie-breakers. Every non-survivor gets a MarkReason.Duplicate mark pointing at its component's survivor; survivors are never marked.
Only propositions in the runner's candidate snapshot are considered: any cluster member absent from candidates is silently ignored. This keeps every emitted mark tied to a swept candidate and avoids a second read of the repository. The strategy never writes to the repository.
Given a traceStore and a real run (a non-blank CollectorRunContext.runId), each component that collapses is also written down as a CollectorDecision: the survivor, and for every loser the grounding, provenance and source ids the merging sweep will fold onto the survivor from it. That record is what com.embabel.dice.spi.undoSingleCollapse reads to reverse a collapse, so a sweep run without a trace store cannot be undone afterwards. The similarity edges and the components are recorded beside it, for inspection. Trace writes are best effort: a failure is logged and the marks are still returned.
Default similarityThreshold (0.7) and topK (10) match PropositionRepository.findClusters so behavior is consistent with the repository's own clustering out of the box.
Constructors
Functions
Same contract as CollectorStrategy.mark, but with the full run context available.