Skip to content

feat(engine): add opportunity freshness scorer - #2780

Merged
JSONbored merged 4 commits into
JSONbored:mainfrom
kiannidev:feat/engine-opportunity-freshness
Jul 3, 2026
Merged

feat(engine): add opportunity freshness scorer#2780
JSONbored merged 4 commits into
JSONbored:mainfrom
kiannidev:feat/engine-opportunity-freshness

Conversation

@kiannidev

@kiannidev kiannidev commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add computeOpportunityFreshness to @jsonbored/gittensory-engine for the ranker freshness signal documented by opportunity-ranker.
  • Mirror the decay curve from src/signals/reward-risk.ts with an injected nowMs clock, case-normalized open states, and blank-timestamp fallback to createdAt.
  • Export through the engine barrel with tests importing from dist/index.js.

Test plan

  • npm test --workspace @jsonbored/gittensory-engine
  • CI green on upstream

Expose a pure computeOpportunityFreshness helper with an injected clock, case-normalized open states, and blank-timestamp fallback so miners can derive the ranker freshness signal without reward-risk IO.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kiannidev
kiannidev requested a review from JSONbored as a code owner July 3, 2026 12:40
@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 3, 2026
@loopover-orb

loopover-orb Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Caution

🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥

🛑 Gittensory review result - reject/close recommended

Review updated: 2026-07-03 20:15:07 UTC

3 files · 1 AI reviewer · 1 blocker · readiness 55/100 · CI green · blocked

🛑 Suggested Action - Reject/Close

  • AI reviewers agree on a likely critical defect: packages/gittensory-engine/src/opportunity-freshness.ts:50 calls `Math.min(...openIssues.map(...))`, so a repository with enough open issues will throw from exceeding V8's function-argument limit
  • replace it with a bounded loop/reduce over `openIssues` instead of spreading user-sized input. — Resolve the flagged defect, or override if the AI reviewers are mistaken, then re-run the gate.

Review summary
This adds and exports a pure opportunity freshness scorer with tests covering the public barrel, open-state normalization, decay, and timestamp fallback behavior. The scoring logic is mostly coherent, but the implementation computes the minimum age by spreading an unbounded issue-derived array into Math.min, which makes large repositories a reachable runtime failure instead of a normal low-cost scan.

Blockers

  • packages/gittensory-engine/src/opportunity-freshness.ts:50 calls `Math.min(...openIssues.map(...))`, so a repository with enough open issues will throw from exceeding V8's function-argument limit; replace it with a bounded loop/reduce over `openIssues` instead of spreading user-sized input.
Nits — 6 non-blocking
  • nit: packages/gittensory-engine/src/opportunity-freshness.ts:27 treats an open issue with no parseable `updatedAt` or `createdAt` as age 0, so confirm that intentionally means fully fresh rather than ignored or failed closed.
  • nit: packages/gittensory-engine/test/opportunity-freshness.test.ts:56 covers malformed `updatedAt` fallback, but it does not cover the all-timestamps-missing branch that currently returns 1.
  • Change packages/gittensory-engine/src/opportunity-freshness.ts:49 to iterate once, e.g. initialize `let mostRecentAgeDays = Number.POSITIVE_INFINITY` and update it inside a `for...of` loop before applying the existing clamp/round.
  • Add a focused test in packages/gittensory-engine/test/opportunity-freshness.test.ts for many open issues so the scorer proves it does not spread unbounded input.
  • Add an explicit test for an open issue with neither timestamp parseable and document whether that should score as fresh, stale, or be ignored.
  • Readiness score is below the configured threshold — Use the readiness panel as advisory maintainer context; the score does not block this PR.

Why this is blocked

  • packages/gittensory-engine/src/opportunity-freshness.ts:50 calls `Math.min(...openIssues.map(...))`, so a repository with enough open issues will throw from exceeding V8's function-argument limit; replace it with a bounded loop/reduce over `openIssues` instead of spreading user-sized input.
Signal Result Evidence
Code review ❌ 1 blocker 1 reviewer
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ⚠️ 1 scoped overlap Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (no linked issue context).
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: 1341 registered-repo PR(s), 659 merged, 47 issue(s).
Contributor context ✅ Confirmed Gittensor contributor kiannidev; Gittensor profile; 1341 PR(s), 47 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
Review context
  • Author: kiannidev
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 1341 PR(s), 47 issue(s).
  • Related work: Titles/paths share 10 meaningful terms. (issue #2280, issue #2278)
Contributor next steps
  • Explain no-issue PR.
  • Review top overlaps.
  • Add a concise scope and risk note.
  • Await review-lane availability.
  • Refresh registry data or choose a registered active repo.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
  • Check active issues and PRs before submitting.
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.

🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

kiannidev and others added 2 commits July 3, 2026 20:59
Validate timestamps while picking issue age input and trim open-state values so malformed updatedAt cannot score a stale issue as fresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve index.ts export conflict by exporting freshness and competition helpers together.

Co-authored-by: Cursor <cursoragent@cursor.com>

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Merge conflicts, please fix.

Resolve add/add conflict with main's opportunity-freshness module by keeping parseable timestamp fallback, bounded min-age iteration, and deduplicated barrel exports.

Co-authored-by: Cursor <cursoragent@cursor.com>
@JSONbored
JSONbored merged commit 0fcf8da into JSONbored:main Jul 3, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants