Skip to content

feat(scoring): reward crown depth via a floored, EMA-anchored quality factor#449

Open
anderdc wants to merge 2 commits into
testfrom
feat/crown-depth-quality-bonus
Open

feat(scoring): reward crown depth via a floored, EMA-anchored quality factor#449
anderdc wants to merge 2 commits into
testfrom
feat/crown-depth-quality-bonus

Conversation

@anderdc
Copy link
Copy Markdown
Collaborator

@anderdc anderdc commented Jun 4, 2026

What & why

The crown is winner-take-all per direction: the best-rate miner earns the full pool whether their rate is 0.5% or 30% below market, so there's no marginal incentive to quote deeper. This scales crown reward by how far the rate beats a per-direction "market" reference, floored at 0.5 (forgiving, mirroring volume_factor). The unearned remainder recycles.

The reference is self-referential: a trimmed, volume-weighted, recency-decayed average of the subnet's own completed-swap clearing rates — no external oracle, no contract change. Trim + volume-weight + per-miner cap defend it against wash manipulation.

Changes

  • storage (state_store.py): clearing_rate column on swap_outcomes (CREATE + idempotent ALTER migration); get_clearing_rates_by_direction_since excludes clearing_rate=0 (legacy/timed-out) rows.
  • population (event_watcher.py): SwapCompleted resolves the swap's snapshotted rate from the live tracker; unparseable → 0.0.
  • scoring (scoring.py): compute_quality_reference / direction_aware_improvement / quality_factor helpers; a quality_weighted_blocks accumulator parallel to cap_weighted_blocks, folded into reward as base × vol_factor × quality (independent multiply — compounds to 0.25 worst case).
  • trace (scoring_trace.py): quality_f surfaced in the scoring log.

Safeguards

  • Cross-validator determinism (consensus-critical): stable total-order sort (rate, block, miner, vol) + math.fsum; now_block = window_end; no wall-clock. Guarded by a shuffle-invariance test.
  • Bootstrap no-op: reference disabled below QUALITY_N_MIN observations (factor 1.0) → the feature is a guaranteed no-op at deploy until real swap history accrues (legacy rows have clearing_rate=0).
  • Direction-aware: btc→tao deeper=higher, tao→btc deeper=lower.
  • Wash/flood resistance: trim + volume-weight + per-miner cap.

Scope (deliberately narrow)

Depth only. No breadth/rank-spillage. No σ-gate edge-sitter exclusion — that belongs to the reservation-bid-window workstream, which makes edge-sitters arbitrageable so the market polices them. The hard is_executable_rate dust floor stays.

⚠️ QUALITY_ANCHOR (0.05) is a placeholder — calibrate against live rate dispersion before trusting it.

Tests

23 new (reference math incl. shuffle-invariance, factor shape, e2e weighting incl. bootstrap/direction/stacking, storage round-trip, watcher population). Full suite 685 pass.

anderdc and others added 2 commits June 3, 2026 20:50
… factor

The crown is winner-take-all per direction: the best-rate miner earns the
full pool whether their rate is 0.5% or 30% below market, so there's no
marginal incentive to quote deeper. Scale crown reward by how far the rate
beats a per-direction "market" reference, floored at 0.5 (forgiving, like
volume_factor); the unearned remainder recycles.

The reference is self-referential: a trimmed, volume-weighted, recency-decayed
average of the subnet's own completed-swap clearing rates — no oracle, no
contract change. Trim + volume weight + per-miner cap defend it against wash
manipulation.

- storage: clearing_rate column on swap_outcomes (CREATE + idempotent ALTER),
  populated at SwapCompleted from the swap's snapshotted rate;
  get_clearing_rates_by_direction_since excludes 0-rate (legacy/timed-out) rows
- scoring: compute_quality_reference / quality_factor helpers; a
  quality_weighted_blocks accumulator parallel to cap_weighted_blocks, folded
  into reward as base * vol_factor * quality (independent multiply)
- determinism: stable total-order sort + math.fsum, now_block=window_end, no
  wall-clock — every validator must compute a byte-identical reference
- bootstrap: reference disabled below QUALITY_N_MIN observations (factor 1.0),
  so the feature is a no-op at deploy until real swap history accrues

Scope: depth only. No breadth/rank-spillage. No sigma-gate edge-sitter
exclusion — that belongs to the reservation-bid-window work, which makes
edge-sitters arbitrageable so the market polices them.

QUALITY_ANCHOR (0.05) is a placeholder — calibrate against live rate
dispersion before trusting it.

Tests: 23 new (reference math incl. shuffle-invariance, factor shape, e2e
weighting incl. bootstrap/direction/stacking, storage round-trip, watcher
population). Full suite 685 pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant