# 2026-07-10 — Pre-registration: confidence-propagation shadow, promotion rule

Registered **before** any certified pair has scored this transform, and anchored independently (see
`calibration/ANCHORS.md`). This document does NOT modify, reinterpret, or supersede any anchored
text. `calibration/hypothesis_log.md` and `calibration/shadow_adjustments.json` remain byte-identical
to their OpenTimestamps-anchored digests. Nothing here touches a lock, `locks.log`,
`certified_results`, or any client-facing number.

## The transform

Each stance verdict carries the classifier's self-reported confidence in `[0, 1]`. The headline share
discards it: a verdict the model was 55% sure of counts exactly as much as one it was 99% sure of.

The **fractional-stance** share weights each decided verdict's impact by that confidence:

```
fav_c        = sum(impact_i * confidence_i | supportive of c)
             / sum(impact_i * confidence_i | decided on c)
share_A      = fav_A / (fav_A + fav_B) * 100
```

Implemented in `sonar/social/confidence_shadow.py`. With every confidence at `1.0` it reduces exactly
to the headline share, so on data recorded before confidence was persisted it is a provable no-op.

## Status: `unvalidated_shadow`

It is a **companion series**. It never replaces `support_score`, never enters a lock, never enters
`locks.log`, and is never echoed as a client-facing number. `score-cycle` reports it beside the raw
lock on scoring day, so it accumulates a public record of hits AND misses at the same volume.

## Promotion rule (mechanical, no operator discretion)

The confidence shadow is promoted to a **live adjustment** — one that may be echoed alongside the raw
headline — **only** after all four conditions hold simultaneously:

1. **Three prospective, in-regime certified pairs.** Counted per `race_type` regime (`intra_party`
   and `general` calibrate differently). Prospective pairs only (`pair_origin == 'prospective'`); a
   retrospective seed licenses nothing. A pair scored in one regime never counts toward the other.

2. **The shadow wins on margin error on every one of those three pairs.**
   `shadow_margin_error < raw_margin_error`, where margin error is the absolute error on the decisive
   two-way margin between the certified top-two. A single pair on which the shadow ties or loses
   resets the count to zero — not to two.

3. **No flipped winner call.** On any pair where the RAW number called the winner correctly, the
   shadow must also call it correctly. Confidence weighting can in principle cross 50/50 (unlike the
   positive-`k` compression, which structurally cannot), so this is a real constraint and not a
   formality.

4. **The mean verdict confidence on those pairs is below 0.95.** If the classifier is essentially
   always certain, the fractional share is arithmetically indistinguishable from the headline, and
   three wins would be three coincidences rather than three tests of the idea. A transform must be
   given the chance to be wrong before its being right means anything.

Failing any condition on any pair keeps the label `unvalidated_shadow` and testing continues.

## Falsification (symmetric, fixed now)

- **REJECTED** if, across the first three in-regime prospective pairs, the shadow's mean margin error
  is greater than or equal to the raw's. Propagating confidence would then be adding noise, not
  removing it, and the transform is abandoned rather than retuned.
- **REJECTED** if the shadow flips a correct raw winner call on any pair.
- **SURVIVES** (not "adopted") when all four promotion conditions hold. Survival licenses echoing the
  shadow beside the raw headline. It never licenses replacing it.

## What promotion does NOT grant

Promotion permits an **echo**, alongside the raw number, both labelled. It never overwrites
`support_score`, never rewrites a lock, and never applies retroactively to a scored pair. The
dome-to-electorate mapping (`sonar/calibration/dome_to_electorate.py`) remains the only route from a
dome share to an electorate claim, and it is `render-and-route only`.

## Confidence

**Low, and n = 0.** Nothing has scored this transform. The rule above exists so that when the first
pair lands, the interpretation is already fixed and cannot be chosen to flatter the result.
