Context
Fred publicly committed on 2026-05-27 in Discord:
"Before we drop below 85% [burn] we'll score by tier, and the hardest challenges should accrue a big jackpot."
Today every win pays the same weight regardless of tier, so a 20-vars uf20 lock pays the same as a 127k-vars SHA-256 preimage. This blocks the burn-down ramp because there's no way to direct emission toward the work we actually want.
This issue covers the per-tier scoring multiplier mechanism. The "jackpot" piece (super-linear / first-mover / decay) is split into its own issue for design.
Scope
- Schema: add
score_multiplier REAL NOT NULL DEFAULT 1.0 to lane_challenges. Migration in ensure_sqlite_challenge_source_schema (idempotent ALTER TABLE ... ADD COLUMN per the existing migration pattern there).
- Operator-set per row: import flow stamps a multiplier based on
kind/tier at activation time (e.g., random_3sat=0.05, sha256_preimage tier-1=1.0, tier-2=3.0, tier-3=10.0).
- Weight policy reads it:
latest_policy_scores_by_hotkey in src/cathedral/publisher/weight_policy.py currently aggregates weighted_score * 1.0 per Task Family row. Change to weighted_score * lane_challenges.score_multiplier on the JOIN.
- Tests: existing weight-policy tests cover the math; add cases for multiplier ≠ 1.0 and verify aggregation matches.
- Public API surface: include
score_multiplier on current-challenge / active-challenges / recent-wins responses so miners can see what each tier pays.
Out of scope (separate issue)
- Jackpot mechanism (super-linear payout, first-mover bonus, time-since-active decay) — see linked issue.
Acceptance
- A tier-3 win pays N× a tier-1 win in the signed weight vector, where N is operator-tunable per challenge.
- Existing wins (where
score_multiplier is 1.0 by default) continue to pay as before — backward compatible.
- Public API consumers can see the multiplier per challenge.
References
Context
Fred publicly committed on 2026-05-27 in Discord:
Today every win pays the same weight regardless of tier, so a 20-vars
uf20lock pays the same as a 127k-vars SHA-256 preimage. This blocks the burn-down ramp because there's no way to direct emission toward the work we actually want.This issue covers the per-tier scoring multiplier mechanism. The "jackpot" piece (super-linear / first-mover / decay) is split into its own issue for design.
Scope
score_multiplier REAL NOT NULL DEFAULT 1.0tolane_challenges. Migration inensure_sqlite_challenge_source_schema(idempotentALTER TABLE ... ADD COLUMNper the existing migration pattern there).kind/tierat activation time (e.g.,random_3sat=0.05,sha256_preimagetier-1=1.0, tier-2=3.0, tier-3=10.0).latest_policy_scores_by_hotkeyinsrc/cathedral/publisher/weight_policy.pycurrently aggregatesweighted_score * 1.0per Task Family row. Change toweighted_score * lane_challenges.score_multiplieron the JOIN.score_multiplieroncurrent-challenge/active-challenges/recent-winsresponses so miners can see what each tier pays.Out of scope (separate issue)
Acceptance
score_multiplieris 1.0 by default) continue to pay as before — backward compatible.References
project_cathedral_tier_jackpot_commitment.md