feat(miner): add a committed benchmark suite for discovery ranking and the local-store path#5615
Conversation
…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.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. 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
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-13 10:24:09 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk 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.
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.
|
Summary
whether a future change to discovery/claiming made things faster or slower — this issue's stated deliverable.
packages/gittensory-miner/scripts/benchmark.mjs(+.d.mts), runnable withnpm run benchmark:minerfrom the repo root (or
npm --workspace @loopover/miner run benchmark), covering the discovery fan-outranking pass and the local-store read/write path:
discovery-fanout-rankingtimesrankCandidateIssues()(lib/opportunity-ranker.js) over 500deterministic synthetic candidates — the pure ranking pass discovery runs once per repo per cycle over
every open candidate.
local-store-read-writetimes 500enqueue()calls followed by 500dequeueNext()calls against a freshin-memory (
:memory:)portfolio-queue.jsstore — the same prepared-statement read/write path everyreal enqueue/claim exercises on disk, minus filesystem I/O, isolating the query-plan/schema cost this
package actually controls.
other one-off scheduling noise instead of trusting a single potentially-unlucky sample.
never
Math.random()/Date.now()— so two runs on the same machine get byte-identical input and the numbersare directly comparable (a REGRESSION test locks this in).
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.
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
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally —scripts/**is excluded from Codecov'spatchgate (seecodecov.yml), same as the existingscripts/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:workersnpm run build:mcpnpm run test:mcp-packnpm run build:minernpm run test:miner-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateRan the full local gate:
npm run test:ci(0 failures) andnpm audit --audit-level=moderate(0 vulnerabilities), both clean on the final commit. Also directly ran the exactFORBIDDEN_PATH/FORBIDDEN_CONTENTregexes fromscripts/check-miner-package.mjs/scripts/forbidden-content.mjsagainst every new/touched file — zero matches.New
test/unit/miner-benchmark-script.test.ts(7 tests), mirroring the existinggenerate-env-reference.mjsscript'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, finitemedianMs/opsPerSecondfor 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
UI Evidencesection below. — N/A, see below.BENCHMARKS.md, linked fromREADME.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.mjsdeliberately follows the same shape as the existingscripts/generate-env-reference.mjs: pure, independently-testable exported functions plus a thinif (import.meta.url === ...) main()CLI guard, with a companion hand-written.d.mtsfor the functions atest imports directly (same reason
generate-env-reference.d.mtsexists).test:cigate as a pass/fail check — a fixed wall-clockthreshold 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.