⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
packages/loopover-engine/src/calibration/provider-track-record.ts's computeProviderTrackRecords (lines 85-161) builds a stancesByTarget map (93-101) that correctly collapses multiple same-provider signals for one targetKey to the latest vote via a Map, but the main aggregation loop (105-150) iterates the raw signals array directly, incrementing signals/decided/shared/consensus once per signal rather than once per distinct (provider, targetKey) pair. The real caller, loadLiveProviderTrackRecords, reads raw audit-event rows with no dedup, so a provider re-reviewing the same PR (common after a new push) gets its precision/agreement stats inflated proportionally to revote count, while its consensus stance reflects only the last vote.
Requirements
Dedupe signals to one entry per (provider, targetKey) pair -- using the already-built stancesByTarget map's latest-vote-wins semantics -- before running the aggregation loop, so a provider's repeated votes on one target contribute exactly once to its precision/agreement counters.
Deliverables
All of the above Deliverables are required in the same PR unless the deliverable text itself states otherwise.
Test Coverage Requirements
packages/loopover-engine/** -- 99%+ patch coverage, branch-counted, on the corrected dedup path.
Expected Outcome
A provider's precision/agreement track record is no longer inflated by re-voting on the same PR multiple times; each distinct (provider, target) pair contributes exactly once.
Links & Resources
packages/loopover-engine/src/calibration/provider-track-record.ts:85-161
Context
packages/loopover-engine/src/calibration/provider-track-record.ts'scomputeProviderTrackRecords(lines 85-161) builds astancesByTargetmap (93-101) that correctly collapses multiple same-provider signals for onetargetKeyto the latest vote via aMap, but the main aggregation loop (105-150) iterates the rawsignalsarray directly, incrementingsignals/decided/shared/consensusonce per signal rather than once per distinct (provider, targetKey) pair. The real caller,loadLiveProviderTrackRecords, reads raw audit-event rows with no dedup, so a provider re-reviewing the same PR (common after a new push) gets its precision/agreement stats inflated proportionally to revote count, while its consensus stance reflects only the last vote.Requirements
Dedupe
signalsto one entry per (provider, targetKey) pair -- using the already-builtstancesByTargetmap's latest-vote-wins semantics -- before running the aggregation loop, so a provider's repeated votes on one target contribute exactly once to its precision/agreement counters.Deliverables
computeProviderTrackRecordsoperates on deduped (provider, targetKey) entries, not raw signal rowssignals/decided/shared/consensuscountersAll of the above Deliverables are required in the same PR unless the deliverable text itself states otherwise.
Test Coverage Requirements
packages/loopover-engine/**-- 99%+ patch coverage, branch-counted, on the corrected dedup path.Expected Outcome
A provider's precision/agreement track record is no longer inflated by re-voting on the same PR multiple times; each distinct (provider, target) pair contributes exactly once.
Links & Resources
packages/loopover-engine/src/calibration/provider-track-record.ts:85-161