Skip to content

[Bug]: per-repo scoring.time_decay.grace_period_hours is not truncated to an integer (drifts from upstream resolve_time_decay) #1320

Description

@philluiz2323

Summary

The score-preview time-decay resolver does not coerce a repo's scoring.time_decay.grace_period_hours override to an integer, so a fractionally-configured grace period diverges from what the upstream gittensor validator awards. The preview reports a higher score than the validator for a PR aged between trunc(grace) and grace.

Area

Registry sync

Expected behavior

Upstream resolve_time_decay (gittensor/validator/utils/load_weights.py) coerces the grace period — and only the grace period — to an integer:

return ResolvedTimeDecay(
    grace_period_hours=int(pick(cfg.grace_period_hours, TIME_DECAY_GRACE_PERIOD_HOURS)),   # int() — truncates
    sigmoid_midpoint_days=float(pick(cfg.sigmoid_midpoint_days, TIME_DECAY_SIGMOID_MIDPOINT)),
    sigmoid_steepness=float(pick(cfg.sigmoid_steepness, TIME_DECAY_SIGMOID_STEEPNESS_SCALAR)),
    min_multiplier=float(pick(cfg.min_multiplier, TIME_DECAY_MIN_MULTIPLIER)),
)

Upstream's range check permits 0 <= grace_period_hours <= 168, so a maintainer can legally configure a fractional value (e.g. 13.9); upstream then truncates it to 13. gittensory's resolveTimeDecay (src/scoring/preview.ts) advertises that it "Mirrors upstream's resolve_time_decay" and should match this integer coercion.

Actual behavior

resolveTimeDecay passes the raw override through unchanged:

gracePeriodHours: pickOverride(overrides?.gracePeriodHours, constant(constants, "TIME_DECAY_GRACE_PERIOD_HOURS")),

and parseTimeDecayOverrides (src/registry/normalize.ts) reads grace_period_hours straight through with no truncation. calculateTimeDecay then compares prAgeHours < gracePeriodHours against the un-truncated float.

With scoring.time_decay.grace_period_hours = 13.9 and time-decay enabled (SCORING_TIME_DECAY_ENABLED), a PR aged 13.5h:

  • Upstream: grace = 13 -> 13.5 >= 13 -> out of grace -> decay multiplier < 1, score reduced.
  • gittensory preview: grace = 13.9 -> 13.5 < 13.9 -> treated as fresh -> multiplier 1.0, no decay.

The preview silently over-states the score relative to the validator — the same class of upstream-parity drift addressed in #806/#807/#808/#812.

Reproduction

With a repo registry config of scoring.time_decay.grace_period_hours: 13.9 and applyTimeDecay on, calculateTimeDecay(13.5, constants, { gracePeriodHours: 13.9 }) returns 1 (no decay) instead of a value < 1.

Validation

Fix is local to resolveTimeDecay; covered by test/unit/scoring.test.ts (resolveTimeDecay overlays per-repo overrides…, calculateTimeDecay …). A regression test pins both the truncation and the boundary-decay behavior. Full local gate (npm run test:ci) is green.

Metadata

Metadata

Assignees

No one assigned

    Labels

    slopAI slop and/or attempts to game additional points via manipulation or alt profiles.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions