From dffeaa3097fc73f6a77f1bd81a88cfede7a5bb1a Mon Sep 17 00:00:00 2001 From: anderdc Date: Sat, 30 May 2026 16:35:16 -0500 Subject: [PATCH 1/3] feat(miners): show credibility auto-zeroed on excess timeouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The credibility card forced a 1.00x headline whenever closedSwaps met the ramp target, so a miner zeroed by the new timeout floor (>3 timeouts in the 30-day window) would wrongly read 1.00x while earning nothing. Key the headline off the actual ramp, and when it's hard-zeroed show 0.00x with an 'auto-zeroed · N timeouts (limit 3)' label plus a tooltip explaining the rolling rule. Surface credibilityTimedOut on the ScoreFactors model. --- src/api/models/MinersDashboard.ts | 2 ++ src/components/miners/ScoreFactorsStrip.tsx | 39 ++++++++++++++++----- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/api/models/MinersDashboard.ts b/src/api/models/MinersDashboard.ts index 0b8bad5..78b5c39 100644 --- a/src/api/models/MinersDashboard.ts +++ b/src/api/models/MinersDashboard.ts @@ -51,6 +51,8 @@ export type ScoreFactors = { closedSwaps: number; credibilityRamp: number; credibilityRampTarget: number; + // Timed-out swaps in the credibility window — used to explain a hard-zeroed ramp. + credibilityTimedOut: number; successRate30d: number; successMultiplier: number; }; diff --git a/src/components/miners/ScoreFactorsStrip.tsx b/src/components/miners/ScoreFactorsStrip.tsx index f195c12..21bb8ee 100644 --- a/src/components/miners/ScoreFactorsStrip.tsx +++ b/src/components/miners/ScoreFactorsStrip.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Box, Stack, Typography, alpha, useTheme } from '@mui/material'; +import { Box, Stack, Tooltip, Typography, alpha, useTheme } from '@mui/material'; import type { ScoreFactors } from '../../api'; import { FONTS } from '../../theme'; import { formatTao } from '../../utils/format'; @@ -19,10 +19,17 @@ type Card = { description: string; delta?: Delta; weak?: boolean; + tooltip?: string; }; +// Mirrors CREDIBILITY_MAX_TIMEOUTS in allways/das-allways — used for display copy +// only; the zeroing itself is computed server-side. +const CREDIBILITY_MAX_TIMEOUTS = 3; + const buildCards = (sf: ScoreFactors): Card[] => { const credibilityRamped = sf.closedSwaps >= sf.credibilityRampTarget; + // Ramp forced to 0 while closed swaps exist = the timeout hard-floor tripped. + const zeroedByTimeouts = sf.closedSwaps > 0 && sf.credibilityRamp === 0; return [ { label: 'Crown share', @@ -72,14 +79,21 @@ const buildCards = (sf: ScoreFactors): Card[] => { { label: 'Credibility', window: 'last 30d', - headline: credibilityRamped - ? fmtMultiplier(1.0) - : fmtMultiplier(sf.credibilityRamp), + headline: zeroedByTimeouts + ? fmtMultiplier(0) + : credibilityRamped + ? fmtMultiplier(1.0) + : fmtMultiplier(sf.credibilityRamp), fill: sf.credibilityRamp, - description: credibilityRamped - ? `fully ramped · ${sf.closedSwaps} of ${sf.credibilityRampTarget} closed` - : `${sf.closedSwaps} / ${sf.credibilityRampTarget} closed · resets if you fall below`, - weak: !credibilityRamped, + description: zeroedByTimeouts + ? `auto-zeroed · ${sf.credibilityTimedOut} timeouts (limit ${CREDIBILITY_MAX_TIMEOUTS})` + : credibilityRamped + ? `fully ramped · ${sf.closedSwaps} of ${sf.credibilityRampTarget} closed` + : `${sf.closedSwaps} / ${sf.credibilityRampTarget} closed · resets if you fall below`, + tooltip: zeroedByTimeouts + ? `More than ${CREDIBILITY_MAX_TIMEOUTS} timed-out swaps in the 30-day window zero your credibility — and with it your whole reward. It recovers as old timeouts age out of the window.` + : undefined, + weak: zeroedByTimeouts || !credibilityRamped, }, ]; }; @@ -169,7 +183,7 @@ const FactorCard: React.FC<{ card: Card }> = ({ card }) => { : theme.palette.primary.main; const headlineColor = card.weak ? 'text.secondary' : 'text.primary'; - return ( + const body = ( = ({ card }) => { ); + + if (!card.tooltip) return body; + return ( + + {body} + + ); }; const composeMultiplier = (sf: ScoreFactors): number => From c9795d73a6412eb2eb94eeee53eda219c293980f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 30 May 2026 21:38:08 +0000 Subject: [PATCH 2/3] style: auto-format code with prettier/eslint --- src/components/miners/ScoreFactorsStrip.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/miners/ScoreFactorsStrip.tsx b/src/components/miners/ScoreFactorsStrip.tsx index 21bb8ee..37cb8b0 100644 --- a/src/components/miners/ScoreFactorsStrip.tsx +++ b/src/components/miners/ScoreFactorsStrip.tsx @@ -1,5 +1,12 @@ import React from 'react'; -import { Box, Stack, Tooltip, Typography, alpha, useTheme } from '@mui/material'; +import { + Box, + Stack, + Tooltip, + Typography, + alpha, + useTheme, +} from '@mui/material'; import type { ScoreFactors } from '../../api'; import { FONTS } from '../../theme'; import { formatTao } from '../../utils/format'; From d854697cb58051c12a52b53f3f04e3c9dd0ec347 Mon Sep 17 00:00:00 2001 From: anderdc Date: Sun, 31 May 2026 10:22:03 -0500 Subject: [PATCH 3/3] fix(miners): lower credibility timeout limit to >2 Tighten the credibility hard-floor from CREDIBILITY_MAX_TIMEOUTS=3 to 2: 0-2 timeouts tolerated, the 3rd timeout in the credibility window zeros credibility (and the whole reward). --- src/components/miners/ScoreFactorsStrip.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/miners/ScoreFactorsStrip.tsx b/src/components/miners/ScoreFactorsStrip.tsx index 37cb8b0..c3593d3 100644 --- a/src/components/miners/ScoreFactorsStrip.tsx +++ b/src/components/miners/ScoreFactorsStrip.tsx @@ -31,7 +31,7 @@ type Card = { // Mirrors CREDIBILITY_MAX_TIMEOUTS in allways/das-allways — used for display copy // only; the zeroing itself is computed server-side. -const CREDIBILITY_MAX_TIMEOUTS = 3; +const CREDIBILITY_MAX_TIMEOUTS = 2; const buildCards = (sf: ScoreFactors): Card[] => { const credibilityRamped = sf.closedSwaps >= sf.credibilityRampTarget;