Skip to content

fix(engine): correct computeOpportunityFreshness's contract and cover the non-finite clock - #9626

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
kai392:fix/9618-freshness-contract
Jul 29, 2026
Merged

fix(engine): correct computeOpportunityFreshness's contract and cover the non-finite clock#9626
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
kai392:fix/9618-freshness-contract

Conversation

@kai392

@kai392 kai392 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Closes #9618

What

computeOpportunityFreshness in packages/loopover-engine/src/opportunity-freshness.ts had a JSDoc that was wrong in three ways and a false coverage suppression:

  • Range. It claimed [0.05, 1], but two paths return 0 (no open issues, or a non-finite nowMs). 0 is a meaningful sentinel — 20x below the 0.05 floor in the multiplicative ranker score — so the JSDoc now names both 0 cases and distinguishes 0 (no signal) from 0.05 (measured, maximally stale).
  • Cross-reference. It cited opportunityFreshnessFactor in src/signals/reward-risk.ts (no such function there) and said this module mirrors it. opportunityFreshnessFactor still hand-duplicates its arithmetic and reads live Date.now(), unlike opportunityCompetitionFactor which #7529 converted to delegate to the pure mirror #8011 made opportunityFreshnessFactor in packages/loopover-engine/src/reward-risk.ts delegate to this module — so the reference is corrected and the direction reworded (this is the canonical implementation), matching the opportunityCompetitionFactor delegation comment.
  • Coverage suppression. The /* v8 ignore next */ on the !Number.isFinite(nowMs) guard claimed the branch was unreachable, but it's reachable from reward-risk.ts:289's args.nowMs ?? Date.now(). Removed, and the branch is now covered by a real test.

No behaviour change: the two 0 returns, the clamp(exp(-age/20), 0.05, 1) formula, round4, and the pickTimestamp order are byte-for-byte unchanged (the diff is JSDoc + the removed suppression comment only).

Tests

New named tests in the engine's own node:test suite (packages/loopover-engine/test/opportunity-freshness.test.ts): a non-finite clock (NaN/Infinity) → 0, no open issues → 0, and the exact measured floor/ceiling (0.05 / 1). The root vitest suite already exercised the non-finite branch, so both the engine and backend Codecov flags union to cover it. Verified: engine suite 10/10, root suite 4/4, tsc --noEmit clean, git diff --check clean.

@kai392
kai392 requested a review from JSONbored as a code owner July 29, 2026 01:16
@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-29 01:38:12 UTC

2 files · 1 AI reviewer · no blockers · CI green · clean

⏸️ Suggested Action - Manual Review

Review summary
The AI review returned non-blocking notes for this change but did not include a separate narrative summary. Review the nits below before deciding this PR.

Nits — 3 non-blocking

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9618
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 100 registered-repo PR(s), 49 merged, 7 issue(s).
Contributor context ✅ Confirmed Gittensor contributor kai392; Gittensor profile; 100 PR(s), 7 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: minor
Review context
  • Author: kai392
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is registered but has no active allocation in the current snapshot.
  • Public profile languages: Python, Cuda, JavaScript, Kotlin, Perl, Ruby, TypeScript, Vue
  • Official Gittensor activity: 100 PR(s), 7 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Await review-lane availability.
  • Then work through the remaining 2 steps in the Signals table above.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


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

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

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

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

… the non-finite clock (JSONbored#9618)

Its JSDoc claimed a [0.05, 1] range and said it mirrors `opportunityFreshnessFactor`
in `src/signals/reward-risk.ts` — both wrong: two paths return the 0 no-signal sentinel
(no open issues, or a non-finite clock), and JSONbored#8011 made `opportunityFreshnessFactor` in
`packages/loopover-engine/src/reward-risk.ts` delegate TO this module, so this is the
canonical implementation, not a mirror. The JSDoc now states the real 0-sentinel cases and
the [0.05, 1] measured range (and that 0 differs 20x from 0.05 in the ranker score).

The `/* v8 ignore next */` on the non-finite-`nowMs` guard was also false — that guard is
reachable from reward-risk.ts:289's `args.nowMs ?? Date.now()` — so it's removed and the
branch is now covered by a real test. No behaviour change: the two 0 returns, the
clamp(exp(-age/20), 0.05, 1) formula, round4, and pickTimestamp order are untouched.

Tests (engine node:test suite): non-finite clock -> 0, no open issues -> 0, and the exact
measured floor/ceiling (0.05 / 1). The root vitest suite already covers the non-finite branch,
so both the engine and backend Codecov flags union to cover it.

Closes JSONbored#9618
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.01%. Comparing base (bd139a5) to head (f9d4b50).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9626      +/-   ##
==========================================
- Coverage   90.02%   90.01%   -0.01%     
==========================================
  Files         888      888              
  Lines      111983   111986       +3     
  Branches    26570    26571       +1     
==========================================
- Hits       100810   100809       -1     
  Misses       9843     9843              
- Partials     1330     1334       +4     
Flag Coverage Δ
backend 95.56% <ø> (-0.01%) ⬇️
engine 66.55% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...kages/loopover-engine/src/opportunity-freshness.ts 97.18% <100.00%> (+0.12%) ⬆️

... and 1 file with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 29, 2026

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 7ba6e9e into JSONbored:main Jul 29, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

engine(freshness): computeOpportunityFreshness's documented range and mirror ref are wrong

2 participants