Skip to content

feat(scores): add hybrid v2 score rollout - #145

Draft
Albermonte wants to merge 4 commits into
mainfrom
albermonte/score-v2-dashboard
Draft

feat(scores): add hybrid v2 score rollout#145
Albermonte wants to merge 4 commits into
mainfrom
albermonte/score-v2-dashboard

Conversation

@Albermonte

@Albermonte Albermonte commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

  • add marker-gated, atomic activity synchronization and bounded repair
  • persist score v2 alongside v1 with off, shadow, and active rollout modes
  • expose current, stale, and no_score states without discarding trustworthy prior scores
  • add a dashboard score-version selector with URL persistence across overview, validator list, and details
  • infer missing high-stake election gaps as offline in v2 while preserving low-stake random non-election
  • add score-sync progress logging, development full-repair support, migrations, and tests

Why

Partial activity history could make a score look complete when it was not, while short recent outages were heavily diluted by the long-term window. This keeps v1 available for rollback and comparison while v2 adds a recent-performance component and explicit data-freshness handling.

Missing election rows are ambiguous: a high-stake validator disappearing for several finalized epochs is strong offline evidence, but the same gap is normal for a low-stake validator. V2 therefore requires both at least 1% estimated network stake and less than 0.1% aggregate random non-election probability before marking a complete gap inferred_offline.

Representative score changes

Calculated with the actual computeScore and computeScoreV2 implementations using a representative 550-epoch long-term window, 28-epoch recent window, two epochs per day, and 720 blocks per epoch. Low stake is modeled as 1% network dominance and high stake as 10%. Values are rounded synthetic examples, not production forecasts.

Case Score v1 Score v2 v2 − v1 Important behavior
Healthy, low stake 100.0% 100.0% 0.0 pp Healthy baseline stays unchanged.
Offline for 1 day, low stake 98.3% 96.4% -1.9 pp Recent downtime becomes visible sooner.
Offline for 3 days, low stake 95.4% 89.3% -6.1 pp A multi-day outage is no longer diluted by months of history.
Offline for 14 days, low stake 83.6% 49.8% -33.8 pp Sustained recent unavailability has a strong effect.
Healthy, high stake (10%) 95.2% 95.2% 0.0 pp The existing dominance penalty remains shared by both versions.
Offline for 3 days, high stake (10%) 90.8% 85.0% -5.8 pp Dominance and recent outage penalties compound.
Healthy at the 15% dominance threshold 0.0% 0.0% 0.0 pp The shared dominance component reaches zero at the configured threshold.
Miss 7 of 720 blocks every epoch 94.1% 94.1% 0.0 pp Persistent degraded performance remains primarily a reliability signal.
Miss 50% of blocks for the latest 3 days 97.5% 89.3% -8.3 pp v2 reacts to a sharp recent reliability regression.
Voluntarily inactive for the latest 3 days 100.0% 89.3% -10.7 pp v2 treats deliberate inactivity as lost recent availability.
Not elected by protocol randomness for 3 days 100.0% 100.0% 0.0 pp Random non-election remains neutral rather than being treated as downtime.

Missing-election guardrails

Finalized activity gap V2 classification Score impact
Estimated stake below 1% not_elected_randomness Neutral
Estimated stake at least 1%, but random non-election probability at least 0.1% not_elected_randomness Neutral
Estimated stake at least 1% and random non-election probability below 0.1% inferred_offline Reduces v2 availability
Incomplete epoch coverage No current v2 score Keeps prior trustworthy score stale when available

Rollout and safety

  • off: compute and serve v1
  • shadow: compute both versions and continue serving v1 by default
  • active: compute both versions and serve v2 by default
  • API and dashboard callers can explicitly request score-version=1|2
  • current v2 is withheld when recent activity coverage is incomplete
  • partial long-term coverage can retain the last trustworthy v2 as stale
  • production repair remains bounded; development mode supports a full repair and a shorter orphaned-sync lease

Verification

  • pnpm test run — 193 tests passed
  • pnpm typecheck — passed with Node 24
  • pnpm lint — passed
  • pnpm validate:json-files — passed
  • pnpm build — passed with Node 24
  • git diff --check — passed
  • local sync:scores — complete at epoch 1254 with 100% recent and long-term coverage; 53 v1 and 36 v2 scores

Targeted local verification confirms a validator observed with one slot (0.195% stake estimate) keeps 231 missing epochs as not_elected_randomness, while a validator near 6.4% stake retains its 20 high-confidence inferred_offline epochs.

Add marker-gated activity synchronization and independent v1/v2 score persistence. Expose score-version selection across the API and dashboard with freshness states, recovery logging, migrations, tests, and rollout documentation.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
validators-api-test 9d44e04 Commit Preview URL

Branch Preview URL
Jul 31 2026, 03:28 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
validators-api-main 9d44e04 Commit Preview URL

Branch Preview URL
Jul 31 2026, 03:27 PM

Treat finalized activity gaps as offline when zero-slot probability falls below 0.1%. Keep score v1 behavior unchanged.
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