Skip to content

feat(scoring): surface upstream scoring constants gittensory does not model (staleness visibility) - #690

Merged
JSONbored merged 1 commit into
mainfrom
feat/scoring-currency-detection
Jun 14, 2026
Merged

feat(scoring): surface upstream scoring constants gittensory does not model (staleness visibility)#690
JSONbored merged 1 commit into
mainfrom
feat/scoring-currency-detection

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

The safe half of the scoring-currency work — makes drift visible without changing any score. (The ranking-changing time-decay implementation is deferred for your review with a before/after ranking diff, per your decision.)

The gap

The upstream constants.py parse is knownOnly — it keeps only constants gittensory already encodes, which silently hid upstream ADDITIONS. So when gittensor introduced new scoring dimensions (e.g. the TIME_DECAY_* constants the audit found), gittensory drifted behind with no signal at all.

Fix (detection only — no score changes)

  • New findUnmodeledUpstreamConstants() detects numeric constants upstream defines that gittensory doesn't model.
  • refreshScoringModelSnapshot now records them on the snapshot payload (unmodeledUpstreamConstants) and raises a warning — "Upstream gittensor defines N scoring constant(s) gittensory does not yet model: … . Scoring may be behind upstream." — which surfaces on /v1/scoring/model, /v1/upstream/status, and the operator dashboard. So "are we out of date?" is now answered automatically.

The live upstream-contract test already runs on a schedule via the existing upstream-contract.yml workflow (the audit was wrong that it's CI-skipped), so that half was already covered.

Tests

findUnmodeledUpstreamConstants flags TIME_DECAY_* (unmodeled) and not SRC_TOK_SATURATION_SCALE (modeled); refresh raises the staleness warning + records the payload field.

Verification

typecheck ✅ · test:coverage ✅ (97.01% branch, 1696 tests) · test:workers ✅ · git diff --check

Part of #525. Follow-up (your review): implement the TIME_DECAY_* scoring dimension to match upstream — changes live rankings, so I'll bring a before/after diff before merging.

… model (staleness visibility)

Makes scoring drift VISIBLE — the safe half of the scoring-currency work (the
ranking-changing time-decay implementation is deferred for owner review with a
before/after diff, per decision).

The upstream constants parse is `knownOnly` (it keeps only constants we already
encode), which silently HID upstream ADDITIONS — so when gittensor introduced new
scoring dimensions (e.g. the TIME_DECAY_* constants) gittensory drifted behind
with no signal. New findUnmodeledUpstreamConstants() detects constants upstream
defines that we don't model; refreshScoringModelSnapshot now records them on the
snapshot payload (unmodeledUpstreamConstants) AND raises a warning
("Upstream gittensor defines N scoring constant(s) gittensory does not yet model:
…. Scoring may be behind upstream."), which surfaces on /v1/scoring/model,
/v1/upstream/status, and the operator dashboard. Detection only — changes no score.

(The live upstream-contract test already runs on a schedule via the existing
upstream-contract.yml workflow, so that half was already covered.)

Tests: findUnmodeledUpstreamConstants flags TIME_DECAY_* (not modeled) and not
SRC_TOK_SATURATION_SCALE (modeled); refresh raises the staleness warning + records
the payload field. 97% branch.

Part of #525.
@ghost

ghost commented Jun 14, 2026

Copy link
Copy Markdown

Note

Gittensory Gate skipped

PR closed before full evaluation. No late first comment was created.

Signal Result Evidence Action
Gate result ⚠️ Skipped #690 is no longer open. No action.

💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

@ghost ghost added the gittensory:reviewed label Jun 14, 2026
@ghost

ghost commented Jun 14, 2026

Copy link
Copy Markdown

gittensory · advisory review

Reviewed 2 changed file(s) — two independent AI reviewers.

Suggested action: 🛠️ Request changes. (reviewers split: request changes / merge) Address the suggestions below before merging.

Reviewer A · gpt-oss-120b — recommends 🛠️ request changes
The PR adds functionality to surface upstream scoring constants that Gittensory does not yet model, emitting warnings and including the list in the snapshot payload, with accompanying unit tests. The implementation is clear and the tests pass, but type definitions for the snapshot payload may need updating to accommodate the new field.

Suggestions

  • Update the TypeScript type for the snapshot payload (e.g., ScoringModelSnapshotRecord or related interfaces) to include the new unmodeledUpstreamConstants property, ensuring compile‑time safety.
  • Verify that the snapshot payload is not unintentionally exposed via any public API endpoints; if it is, confirm that the added data does not violate the public/private boundary.
  • Consider adding a test that confirms the warning is not added when there are no unmodeled constants (edge‑case coverage).

Worth double-checking

  • Potential TypeScript type errors in parts of the codebase that consume the snapshot payload without expecting the new field.
  • If the payload is part of a public API response, the new data could increase surface area, though it does not contain forbidden terms.

Reviewer B · nemotron-3-120b-a12b — recommends ✅ merge
The PR adds visibility into upstream scoring constants that gittensory does not model, enhancing staleness awareness. It modifies the scoring model snapshot to include unmodeled constants and adds corresponding warnings. The change is minimal, well-tested, and does not affect scoring logic or violate public/private boundaries.

No blocking issues spotted.

@ghost ghost added the gittensory-review label Jun 14, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@JSONbored
JSONbored merged commit f92dc10 into main Jun 14, 2026
10 checks passed
@JSONbored
JSONbored deleted the feat/scoring-currency-detection branch June 14, 2026 08:51
@github-project-automation github-project-automation Bot moved this from Todo to Done in gittensory - v1 roadmap Jun 14, 2026
JSONbored added a commit that referenced this pull request Jun 14, 2026
…f flag (#703) (#731)

Ports upstream gittensor's sigmoid time-decay (the validator's calculate_time_decay)
into gittensory's score model. DEFAULT-OFF + owner-gated: the roadmap defers #703
pending owner review of a before/after ranking diff, so this changes nothing live
until SCORING_TIME_DECAY_ENABLED is set.

- scoring/model.ts: model the 4 upstream constants (TIME_DECAY_GRACE_PERIOD_HOURS 12,
  SIGMOID_MIDPOINT 10, SIGMOID_STEEPNESS_SCALAR 0.4, MIN_MULTIPLIER 0.05) so they no
  longer surface as unmodeled drift (#690); + isTimeDecayEnabled gate (default off).
- scoring/preview.ts: calculateTimeDecay (verbatim port: hard 12h grace -> 1.0, then a
  logistic on days-since-merge, 50% at 10d, floored at 0.05) + a timeDecayMultiplier
  applied to estimatedMergedScore. A fresh PR (age < grace) is unaffected even when
  enabled, so a normal new-PR preview never changes.
- prAgeHours input + the owner-gated applyTimeDecay flag injected server-side at the
  routes + MCP score-preview entry points (not caller-controllable).

Why per-PR projection (not a historical-aggregate refactor): gittensory's preview
scores a single fresh planned PR and surfaces the contributor's upstream-API standing
(already decayed upstream); it has no raw historical per-PR aggregation to decay, so
re-applying there would double-count. The faithful model is per-PR (predicted score x
decay-by-age).

Decay curve (the before/after to review): fresh 100% -> 5d ~88% -> 10d 50% -> >=20d 5% floor.

Tests: calculateTimeDecay vs upstream (grace, 50%@10D, floor, monotonic), constants
now modeled, the env gate, the preview applied/unapplied paths, and a before/after
trajectory. 97% coverage held; OpenAPI regenerated.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant