Skip to content

feat(miner): add a committed benchmark suite for discovery ranking and the local-store path#5615

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
galuis116:feat/miner-benchmark-suite
Jul 13, 2026
Merged

feat(miner): add a committed benchmark suite for discovery ranking and the local-store path#5615
JSONbored merged 1 commit into
JSONbored:mainfrom
galuis116:feat/miner-benchmark-suite

Conversation

@galuis116

Copy link
Copy Markdown
Contributor

Summary

  • No profiling or benchmark data existed anywhere for the miner package, so there was no baseline to know
    whether a future change to discovery/claiming made things faster or slower — this issue's stated deliverable.
  • Added packages/gittensory-miner/scripts/benchmark.mjs (+ .d.mts), runnable with npm run benchmark:miner
    from the repo root (or npm --workspace @loopover/miner run benchmark), covering the discovery fan-out
    ranking pass and the local-store read/write path:
    • discovery-fanout-ranking times rankCandidateIssues() (lib/opportunity-ranker.js) over 500
      deterministic synthetic candidates — the pure ranking pass discovery runs once per repo per cycle over
      every open candidate.
    • local-store-read-write times 500 enqueue() calls followed by 500 dequeueNext() calls against a fresh
      in-memory (:memory:) portfolio-queue.js store — the same prepared-statement read/write path every
      real enqueue/claim exercises on disk, minus filesystem I/O, isolating the query-plan/schema cost this
      package actually controls.
  • Both benchmarks repeat their work 5 times and report the median wall time, to smooth over GC pauses and
    other one-off scheduling noise instead of trusting a single potentially-unlucky sample.
  • The synthetic candidate generator is fully deterministic — every field is derived from the loop index alone,
    never Math.random()/Date.now() — so two runs on the same machine get byte-identical input and the numbers
    are directly comparable (a REGRESSION test locks this in).
  • It is a signal to read locally, not a hard CI gate: wall-clock timing on shared CI runners is too noisy to
    gate on reliably, so it does not fail the build on its own, matching the issue's "runs in CI or on demand"
    acceptance criterion via the "on demand" branch.
  • Documented in new packages/gittensory-miner/BENCHMARKS.md (what each benchmark measures, how to run it,
    a machine-dependent baseline sample run) and linked from README.md.

Fixes #4845

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally — scripts/** is excluded from Codecov's patch gate (see codecov.yml), same as the existing scripts/generate-env-reference.mjs; this PR still ships a full unit + end-to-end CLI test suite for the new script (see below).
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run build:miner
  • npm run test:miner-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

Ran the full local gate: npm run test:ci (0 failures) and npm audit --audit-level=moderate (0 vulnerabilities), both clean on the final commit. Also directly ran the exact FORBIDDEN_PATH/FORBIDDEN_CONTENT regexes from scripts/check-miner-package.mjs/scripts/forbidden-content.mjs against every new/touched file — zero matches.

New test/unit/miner-benchmark-script.test.ts (7 tests), mirroring the existing generate-env-reference.mjs script's own test pattern: a REGRESSION test proving synthetic candidate generation is byte-for-byte deterministic across calls; candidate-shape validation; both benchmarks report a positive, finite medianMs/opsPerSecond for custom option sizes; both fall back to the documented default counts when no options are passed; a deterministic-report-rendering test with no locale-dependent number formatting (toLocaleString() is deliberately avoided since its output format varies by system locale); and an end-to-end test spawning the real CLI script as a subprocess and asserting on its stdout.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. — N/A, no auth/session/CORS surface touched (a local, synchronous benchmark script only, no network calls).
  • API/OpenAPI/MCP behavior is updated and tested where needed. — no public API/OpenAPI/MCP surface touched; this is a new local dev-tooling script only.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. — N/A, no UI surface.
  • Visible UI changes include a UI Evidence section below. — N/A, see below.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs. — added BENCHMARKS.md, linked from README.md.

UI Evidence

N/A — this is a local dev-tooling script (one new npm command) with no visible UI surface. No screenshots apply.

Notes

  • scripts/benchmark.mjs deliberately follows the same shape as the existing
    scripts/generate-env-reference.mjs: pure, independently-testable exported functions plus a thin
    if (import.meta.url === ...) main() CLI guard, with a companion hand-written .d.mts for the functions a
    test imports directly (same reason generate-env-reference.d.mts exists).
  • Deliberately did not wire this into the required test:ci gate as a pass/fail check — a fixed wall-clock
    threshold on a shared CI runner would be flaky by construction (unrelated CI load changes the number, not
    just real regressions in the code under test). The issue's own acceptance criterion allows "runs in CI or
    on demand"; this ships the "on demand" half with clear docs on when/how to run it manually around a change.

…d the local-store path

No profiling or baseline data existed for the miner package's two purely local,
synchronous hot paths, so a future change to the ranking pass or the SQLite
store layer had no repeatable number to compare against.

Adds packages/gittensory-miner/scripts/benchmark.mjs (npm run benchmark:miner),
which times rankCandidateIssues() over 500 deterministic synthetic candidates
and 500 enqueue/dequeue cycles against an in-memory portfolio-queue store,
reporting the median of 5 runs. Documented in BENCHMARKS.md with a baseline
sample run.
@galuis116 galuis116 requested a review from JSONbored as a code owner July 13, 2026 09:48
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.01%. Comparing base (1f515de) to head (db78dd4).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5615   +/-   ##
=======================================
  Coverage   95.01%   95.01%           
=======================================
  Files         574      574           
  Lines       45684    45684           
  Branches    14661    14661           
=======================================
  Hits        43405    43405           
  Misses       1528     1528           
  Partials      751      751           
Flag Coverage Δ
shard-1 43.99% <ø> (ø)
shard-2 35.65% <ø> (-0.08%) ⬇️
shard-3 32.21% <ø> (-0.03%) ⬇️
shard-4 32.67% <ø> (+0.06%) ⬆️
shard-5 31.75% <ø> (ø)
shard-6 44.07% <ø> (ø)

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

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 13, 2026
@loopover-orb

loopover-orb Bot commented Jul 13, 2026

Copy link
Copy Markdown

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-13 10:24:09 UTC

7 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

⏸️ Suggested Action - Manual Review

  • AI review could not be completed: The dual-model AI review did not return a usable verdict for this change.

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 — 6 non-blocking
  • packages/gittensory-miner/scripts/benchmark.mjs:36 — the synthetic `htmlUrl` hardcodes `github.com`, which is a bit inconsistent with the repo's stated forge-agnostic direction (`lib/forge-config.js`), though harmless since it's never dereferenced.
  • packages/gittensory-miner/scripts/benchmark.mjs:27-38 — several magic numbers (3_600_000ms step, %7 repo bucket, %11 comment count, %5 iterations) could use named constants for readability, though they're clearly synthetic/arbitrary by design.
  • console.log at packages/gittensory-miner/scripts/benchmark.mjs:129 is appropriate here since this is a CLI report script, not library code — not actually a concern.
  • The BENCHMARKS.md baseline numbers are explicitly marked machine-dependent/informational, which is the right call to avoid readers treating them as a hard target.
  • Consider extracting the repo-bucket modulus (7) and comment-count modulus (11) into named constants like `SYNTHETIC_REPO_BUCKET_COUNT` for a bit more self-documentation, per the external brief's magic-number flags.
  • AI review could not be completed — The gate is held for a human reviewer rather than passed automatically; it re-evaluates on the next update.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4845
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 ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 1883 registered-repo PR(s), 1242 merged, 49 issue(s).
Contributor context ✅ Confirmed Gittensor contributor galuis116; Gittensor profile; 1883 PR(s), 49 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Improvement ✅ Minor risk: clean · value: minor — Code changes are accompanied by test evidence. LLM value judgment: moderate — The PR delivers exactly what issue #4845 asks for — a committed, deterministic, non-gating benchmark for the two previously-unmeasured hot local paths — with tests and docs, making it a genuine, well-targeted improvement in observability tooling rather than a large feature addition.
Review context
  • Author: galuis116
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: JavaScript, Python, Dart, TypeScript, HTML, MDX, Rust, C++
  • Official Gittensor activity: 1883 PR(s), 49 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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.
[BETA] Chat with Gittensory

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

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

Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands

🟩 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

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 13, 2026
@JSONbored JSONbored merged commit a05e02e into JSONbored:main Jul 13, 2026
16 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. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add committed profiling/benchmarks for the miner package

2 participants