Multi Signal Collector Strategy
Composes any number of candidate-pair sources and signal scorers into one duplicate-collapse strategy, replacing the single-cosine cut in com.embabel.dice.projection.memory.DuplicateCollectorStrategy with a pluggable multi-signal blend.
A run has four stages:
every CandidatePairSource proposes pairs; they're canonicalized (smaller id as anchor) and deduped;
every CollectorSignalScorer scores each pair, abstentions (null) dropped, and CollectorEdgeAggregator blends what's left into one CollectorCandidateEdge per pair;
componentsFinder groups candidate ids into components using the non-vetoed edges at or above matchThreshold; because this unions transitively, two members can end up in the same component even when their own direct pair was never proposed (A~B, B~C puts A and C together even if no source ever proposed (A,C)), or even when it was proposed and scored but vetoed - a veto only drops that one edge from the union, it doesn't stop A and C landing in the same component via bridging B. So before survivors are picked, every such never-scored or vetoed intra-component pair is treated as a cannot-cohabit constraint and one side of any contradicting pair is vetoed out of the component (see
resolveContradictions);each surviving component of size 2+ gets one survivor (via survivorPolicy); everyone else in the component is marked MarkReason.Duplicate pointing at the survivor.
Every edge, component, and decision is recorded in traceStore under the run's id, so a run can be inspected or reversed after the fact — see RetiredProposition for what's kept about each folded proposition.
Constructors
Functions
Runs one full mark pass over candidates and returns the duplicate marks it produced. Never writes to repository — the run is entirely read-and-report, same contract as com.embabel.dice.projection.memory.CollectorStrategy.