From 98c7b1b292257b78b950e25a65e62780a89da040 Mon Sep 17 00:00:00 2001 From: kiannidev <156195510+kiannidev@users.noreply.github.com> Date: Fri, 19 Jun 2026 03:01:27 +0200 Subject: [PATCH 1/2] feat(scoring): model upstream review-collateral and non-code caps (Fixes #809) Pull MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER, MAX_LINES_SCORED_FOR_NON_CODE_EXT, and DEFAULT_ISSUE_DISCOVERY_SHARE into the scoring snapshot and apply them in preview collateral math, non-code line capping, and registry normalization defaults. Co-authored-by: Cursor --- apps/gittensory-ui/public/openapi.json | 28 ++++++ src/api/routes.ts | 2 + src/openapi/schemas.ts | 1 + src/registry/normalize.ts | 5 +- src/scoring/model.ts | 3 + src/scoring/preview.ts | 29 +++++- src/signals/local-branch.ts | 1 + test/unit/scoring.test.ts | 119 +++++++++++++++++++++++++ 8 files changed, 182 insertions(+), 6 deletions(-) diff --git a/apps/gittensory-ui/public/openapi.json b/apps/gittensory-ui/public/openapi.json index a282fa0de3..1ba78fa46c 100644 --- a/apps/gittensory-ui/public/openapi.json +++ b/apps/gittensory-ui/public/openapi.json @@ -4299,6 +4299,9 @@ }, "credibilityObserved": { "type": "number" + }, + "reviewCollateralMultiplier": { + "type": "number" } }, "required": [ @@ -4306,6 +4309,7 @@ "openPrThreshold", "openPrCount", "collateralFraction", + "reviewCollateralMultiplier", "credibilityFloor", "credibilityObserved" ] @@ -4551,6 +4555,9 @@ }, "credibilityObserved": { "type": "number" + }, + "reviewCollateralMultiplier": { + "type": "number" } }, "required": [ @@ -4558,6 +4565,7 @@ "openPrThreshold", "openPrCount", "collateralFraction", + "reviewCollateralMultiplier", "credibilityFloor", "credibilityObserved" ] @@ -4803,6 +4811,9 @@ }, "credibilityObserved": { "type": "number" + }, + "reviewCollateralMultiplier": { + "type": "number" } }, "required": [ @@ -4810,6 +4821,7 @@ "openPrThreshold", "openPrCount", "collateralFraction", + "reviewCollateralMultiplier", "credibilityFloor", "credibilityObserved" ] @@ -5055,6 +5067,9 @@ }, "credibilityObserved": { "type": "number" + }, + "reviewCollateralMultiplier": { + "type": "number" } }, "required": [ @@ -5062,6 +5077,7 @@ "openPrThreshold", "openPrCount", "collateralFraction", + "reviewCollateralMultiplier", "credibilityFloor", "credibilityObserved" ] @@ -5307,6 +5323,9 @@ }, "credibilityObserved": { "type": "number" + }, + "reviewCollateralMultiplier": { + "type": "number" } }, "required": [ @@ -5314,6 +5333,7 @@ "openPrThreshold", "openPrCount", "collateralFraction", + "reviewCollateralMultiplier", "credibilityFloor", "credibilityObserved" ] @@ -6207,6 +6227,9 @@ }, "credibilityObserved": { "type": "number" + }, + "reviewCollateralMultiplier": { + "type": "number" } }, "required": [ @@ -6214,6 +6237,7 @@ "openPrThreshold", "openPrCount", "collateralFraction", + "reviewCollateralMultiplier", "credibilityFloor", "credibilityObserved" ] @@ -6455,6 +6479,9 @@ }, "credibilityObserved": { "type": "number" + }, + "reviewCollateralMultiplier": { + "type": "number" } }, "required": [ @@ -6462,6 +6489,7 @@ "openPrThreshold", "openPrCount", "collateralFraction", + "reviewCollateralMultiplier", "credibilityFloor", "credibilityObserved" ] diff --git a/src/api/routes.ts b/src/api/routes.ts index 8db71ad86c..2dd4ba1dbe 100644 --- a/src/api/routes.ts +++ b/src/api/routes.ts @@ -446,6 +446,7 @@ const localBranchScorerSchema = z sourceLines: z.number().min(0).optional(), testTokenScore: z.number().min(0).optional(), nonCodeTokenScore: z.number().min(0).optional(), + nonCodeLines: z.number().min(0).optional(), warnings: z.array(z.string().max(MAX_LOCAL_SCORER_WARNING_CHARS)).max(MAX_LOCAL_SCORER_WARNING_COUNT).optional(), }) .strict(); @@ -516,6 +517,7 @@ const scorePreviewSchema = z.object({ sourceLines: z.number().min(0).optional(), testTokenScore: z.number().min(0).optional(), nonCodeTokenScore: z.number().min(0).optional(), + nonCodeLines: z.number().min(0).optional(), existingContributorTokenScore: z.number().min(0).optional(), prAgeHours: z.number().min(0).optional(), openPrCount: z.number().int().min(0).optional(), diff --git a/src/openapi/schemas.ts b/src/openapi/schemas.ts index 448d3a90e3..a796bf25b9 100644 --- a/src/openapi/schemas.ts +++ b/src/openapi/schemas.ts @@ -1231,6 +1231,7 @@ const ScoreGatesSchema = z.object({ openPrThreshold: z.number(), openPrCount: z.number(), collateralFraction: z.number(), + reviewCollateralMultiplier: z.number(), credibilityFloor: z.number(), credibilityObserved: z.number(), }); diff --git a/src/registry/normalize.ts b/src/registry/normalize.ts index 9a10edd38b..acda35516c 100644 --- a/src/registry/normalize.ts +++ b/src/registry/normalize.ts @@ -1,9 +1,8 @@ +import { DEFAULT_SCORING_CONSTANTS } from "../scoring/model"; import type { JsonValue, RegistryRepoConfig, RegistrySnapshot, RepoTimeDecayOverrides } from "../types"; type RawRepoConfig = Record; -const DEFAULT_ISSUE_DISCOVERY_SHARE = 0.5; - export function normalizeRegistryPayload(payload: unknown, source: RegistrySnapshot["source"], fetchedAt: string): RegistrySnapshot { const repos = extractRepoEntries(payload).map(([repo, config]) => normalizeRepo(repo, config)); const totalEmissionShare = repos.reduce((sum, repo) => sum + repo.emissionShare, 0); @@ -59,7 +58,7 @@ function normalizeRepo(repo: string, config: RawRepoConfig): RegistryRepoConfig return { repo, emissionShare: numberValue(config.emission_share) ?? 0, - issueDiscoveryShare: numberValue(config.issue_discovery_share) ?? DEFAULT_ISSUE_DISCOVERY_SHARE, + issueDiscoveryShare: numberValue(config.issue_discovery_share) ?? DEFAULT_SCORING_CONSTANTS.DEFAULT_ISSUE_DISCOVERY_SHARE ?? 0.5, labelMultipliers, trustedLabelPipeline: booleanValue(config.trusted_label_pipeline), maintainerCut: numberValue(config.maintainer_cut) ?? 0, diff --git a/src/scoring/model.ts b/src/scoring/model.ts index c427b2305b..286d1ccfe4 100644 --- a/src/scoring/model.ts +++ b/src/scoring/model.ts @@ -28,6 +28,9 @@ export const DEFAULT_SCORING_CONSTANTS: Record = { OPEN_ISSUE_SPAM_TOKEN_SCORE_PER_SLOT: 300, MAX_OPEN_ISSUE_THRESHOLD: 30, OPEN_PR_COLLATERAL_PERCENT: 0.2, + MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER: 2.0, + MAX_LINES_SCORED_FOR_NON_CODE_EXT: 300, + DEFAULT_ISSUE_DISCOVERY_SHARE: 0.5, REVIEW_PENALTY_RATE: 0.15, STANDARD_ISSUE_MULTIPLIER: 1.33, MAINTAINER_ISSUE_MULTIPLIER: 1.66, diff --git a/src/scoring/preview.ts b/src/scoring/preview.ts index d358cedb4b..51f8c85de3 100644 --- a/src/scoring/preview.ts +++ b/src/scoring/preview.ts @@ -14,6 +14,8 @@ export type ScorePreviewInput = { sourceLines?: number | undefined; testTokenScore?: number | undefined; nonCodeTokenScore?: number | undefined; + /** Raw non-code line count before upstream's MAX_LINES_SCORED_FOR_NON_CODE_EXT cap. */ + nonCodeLines?: number | undefined; existingContributorTokenScore?: number | undefined; openPrCount?: number | undefined; credibility?: number | undefined; @@ -167,7 +169,10 @@ export type ScorePreviewResult = { baseTokenGatePassed: boolean; openPrThreshold: number; openPrCount: number; + /** Effective open-PR collateral fraction (OPEN_PR_COLLATERAL_PERCENT × reviewCollateralMultiplier). */ collateralFraction: number; + /** Upstream open-PR review-collateral multiplier from CHANGES_REQUESTED reviews (≥ 1, capped). */ + reviewCollateralMultiplier: number; credibilityFloor: number; credibilityObserved: number; }; @@ -288,7 +293,10 @@ function computeScoreCore( const directPrSlice = repoSlice * (1 - issueDiscoveryShare); const issueDiscoverySlice = repoSlice * issueDiscoveryShare; const sourceTokenScore = nonNegative(input.sourceTokenScore); - const totalTokenScore = nonNegative(input.totalTokenScore ?? sourceTokenScore + nonNegative(input.testTokenScore) + nonNegative(input.nonCodeTokenScore)); + const cappedNonCodeTokenScore = applyNonCodeLineCap(input, constants); + const totalTokenScore = nonNegative( + input.totalTokenScore ?? sourceTokenScore + nonNegative(input.testTokenScore) + cappedNonCodeTokenScore, + ); const sourceLines = Math.max(1, nonNegative(input.sourceLines ?? sourceTokenScore)); const fixedBaseScore = input.fixedBaseScore ?? config?.fixedBaseScore ?? undefined; const rawDensity = sourceTokenScore / sourceLines; @@ -315,7 +323,13 @@ function computeScoreCore( const credibilityFloor = constant(constants, "MIN_CREDIBILITY", 0.8); const credibilityMultiplier = credibilityObserved >= credibilityFloor ? 1 : credibilityObserved / credibilityFloor; const changesRequestedCount = nonNegative(input.changesRequestedCount); - const reviewPenaltyMultiplier = clamp(1 - changesRequestedCount * constant(constants, "REVIEW_PENALTY_RATE", 0.15), 0, 1); + const reviewPenaltyRate = constant(constants, "REVIEW_PENALTY_RATE", 0.15); + const reviewPenaltyMultiplier = clamp(1 - changesRequestedCount * reviewPenaltyRate, 0, 1); + const reviewCollateralMultiplier = Math.min( + constant(constants, "MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER", 2.0), + 1 + changesRequestedCount * reviewPenaltyRate, + ); + const openPrCollateralPercent = constant(constants, "OPEN_PR_COLLATERAL_PERCENT", 0.2); const openPrCount = nonNegative(input.openPrCount); // The concurrency allowance is earned from the contributor's established merged-history token // score; the planned PR's own tokens (totalTokenScore) must not inflate its own open-PR threshold. @@ -361,7 +375,8 @@ function computeScoreCore( baseTokenGatePassed, openPrThreshold, openPrCount, - collateralFraction: constant(constants, "OPEN_PR_COLLATERAL_PERCENT", 0.2), + reviewCollateralMultiplier: roundScore(reviewCollateralMultiplier), + collateralFraction: roundScore(openPrCollateralPercent * reviewCollateralMultiplier), credibilityFloor, credibilityObserved, }, @@ -898,6 +913,14 @@ function inferCredibility(evidence?: ContributorEvidenceRecord | null): number { return clamp(0.75 + merged * 0.04 - stale * 0.03 - unlinked * 0.02, 0.25, 1); } +function applyNonCodeLineCap(input: Pick, constants: Record): number { + const score = nonNegative(input.nonCodeTokenScore); + const lines = nonNegative(input.nonCodeLines); + if (score <= 0 || lines <= 0) return score; + const maxLines = constant(constants, "MAX_LINES_SCORED_FOR_NON_CODE_EXT", 300); + return lines <= maxLines ? score : score * (maxLines / lines); +} + function constant(constants: Record, key: string, fallback: number): number { const value = constants[key]; return typeof value === "number" && Number.isFinite(value) ? value : fallback; diff --git a/src/signals/local-branch.ts b/src/signals/local-branch.ts index dc7ca7dba6..9795b91d41 100644 --- a/src/signals/local-branch.ts +++ b/src/signals/local-branch.ts @@ -455,6 +455,7 @@ function buildLocalScoreInput(args: { sourceLines: scorer?.sourceLines ?? Math.max(1, sourceLineCount || args.changedLineCount || 1), testTokenScore: scorer?.testTokenScore ?? testLineCount, nonCodeTokenScore: scorer?.nonCodeTokenScore ?? nonCodeLineCount, + nonCodeLines: nonCodeLineCount, openPrCount: args.outcomeHistory.totals.openPullRequests, credibility: args.repoOutcome?.credibility ?? args.outcomeHistory.totals.credibility, metadataOnly: scorer?.mode !== "gittensor_root" && scorer?.mode !== "external_command", diff --git a/test/unit/scoring.test.ts b/test/unit/scoring.test.ts index ff8ce49c93..81222082c5 100644 --- a/test/unit/scoring.test.ts +++ b/test/unit/scoring.test.ts @@ -99,6 +99,125 @@ MAX_CODE_DENSITY_MULTIPLIER = 1.15 ).not.toContain("ISSUES_TREASURY_EMISSION_SHARE"); }); + it("models upstream review-collateral, non-code line cap, and issue-discovery defaults (#809)", () => { + expect(DEFAULT_SCORING_CONSTANTS).toMatchObject({ + MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER: 2.0, + MAX_LINES_SCORED_FOR_NON_CODE_EXT: 300, + DEFAULT_ISSUE_DISCOVERY_SHARE: 0.5, + }); + expect( + findUnmodeledUpstreamConstants(` +MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER = 2.0 +MAX_LINES_SCORED_FOR_NON_CODE_EXT = 300 +DEFAULT_ISSUE_DISCOVERY_SHARE = 0.5 +NOVELTY_BONUS_SCALAR = 3 +`), + ).toEqual(["NOVELTY_BONUS_SCALAR"]); + + const collateralPreview = buildScorePreview({ + repo, + snapshot: { + ...snapshot, + constants: { + ...snapshot.constants, + MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER: 2.0, + OPEN_PR_COLLATERAL_PERCENT: 0.2, + REVIEW_PENALTY_RATE: 0.15, + }, + }, + input: { + repoFullName: repo.fullName, + sourceTokenScore: 60, + totalTokenScore: 60, + sourceLines: 50, + changesRequestedCount: 4, + openPrCount: 1, + credibility: 1, + }, + }); + expect(collateralPreview.gates.reviewCollateralMultiplier).toBe(1.6); + expect(collateralPreview.gates.collateralFraction).toBeCloseTo(0.32, 5); + expect(collateralPreview.scoreEstimate.reviewPenaltyMultiplier).toBe(0.4); + + const cappedCollateral = buildScorePreview({ + repo, + snapshot: { + ...snapshot, + constants: { + ...snapshot.constants, + MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER: 2.0, + REVIEW_PENALTY_RATE: 0.15, + }, + }, + input: { + repoFullName: repo.fullName, + sourceTokenScore: 60, + totalTokenScore: 60, + sourceLines: 50, + changesRequestedCount: 10, + openPrCount: 1, + credibility: 1, + }, + }); + expect(cappedCollateral.gates.reviewCollateralMultiplier).toBe(2); + expect(cappedCollateral.gates.collateralFraction).toBeCloseTo(0.4, 5); + + const uncappedNonCode = buildScorePreview({ + repo, + snapshot: { + ...snapshot, + constants: { ...snapshot.constants, MAX_LINES_SCORED_FOR_NON_CODE_EXT: 300, CONTRIBUTION_SCORE_FOR_FULL_BONUS: 1500, MAX_CONTRIBUTION_BONUS: 25 }, + }, + input: { + repoFullName: repo.fullName, + sourceTokenScore: 100, + testTokenScore: 0, + nonCodeTokenScore: 600, + sourceLines: 100, + openPrCount: 0, + credibility: 1, + }, + }); + const cappedNonCode = buildScorePreview({ + repo, + snapshot: { + ...snapshot, + constants: { ...snapshot.constants, MAX_LINES_SCORED_FOR_NON_CODE_EXT: 300, CONTRIBUTION_SCORE_FOR_FULL_BONUS: 1500, MAX_CONTRIBUTION_BONUS: 25 }, + }, + input: { + repoFullName: repo.fullName, + sourceTokenScore: 100, + testTokenScore: 0, + nonCodeTokenScore: 600, + nonCodeLines: 600, + sourceLines: 100, + openPrCount: 0, + credibility: 1, + }, + }); + expect(uncappedNonCode.scoreEstimate.contributionBonus).toBeGreaterThan(cappedNonCode.scoreEstimate.contributionBonus); + expect(cappedNonCode.scoreEstimate.contributionBonus).toBeCloseTo( + buildScorePreview({ + repo, + snapshot: { + ...snapshot, + constants: { ...snapshot.constants, MAX_LINES_SCORED_FOR_NON_CODE_EXT: 300, CONTRIBUTION_SCORE_FOR_FULL_BONUS: 1500, MAX_CONTRIBUTION_BONUS: 25 }, + }, + input: { + repoFullName: repo.fullName, + sourceTokenScore: 100, + testTokenScore: 0, + nonCodeTokenScore: 300, + nonCodeLines: 300, + sourceLines: 100, + openPrCount: 0, + credibility: 1, + }, + }).scoreEstimate.contributionBonus, + 5, + ); + }); + it("detects the active model from fetched constants before default fallback constants", async () => { const env = createTestEnv({ GITHUB_PUBLIC_TOKEN: "token" }); vi.stubGlobal("fetch", async (input: RequestInfo | URL) => { From 40b0f4da05293fe4633241a311382f947b9b15e8 Mon Sep 17 00:00:00 2001 From: kiannidev <156195510+kiannidev@users.noreply.github.com> Date: Fri, 19 Jun 2026 03:05:33 +0200 Subject: [PATCH 2/2] test(registry): cover DEFAULT_ISSUE_DISCOVERY_SHARE default path (#916) Export a typed DEFAULT_ISSUE_DISCOVERY_SHARE constant and assert registry normalization uses it when issue_discovery_share is missing or invalid. Co-authored-by: Cursor --- src/registry/normalize.ts | 4 ++-- src/scoring/model.ts | 4 +++- test/unit/registry.test.ts | 10 +++++++++- test/unit/scoring.test.ts | 5 +++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/registry/normalize.ts b/src/registry/normalize.ts index acda35516c..fc30656332 100644 --- a/src/registry/normalize.ts +++ b/src/registry/normalize.ts @@ -1,4 +1,4 @@ -import { DEFAULT_SCORING_CONSTANTS } from "../scoring/model"; +import { DEFAULT_ISSUE_DISCOVERY_SHARE } from "../scoring/model"; import type { JsonValue, RegistryRepoConfig, RegistrySnapshot, RepoTimeDecayOverrides } from "../types"; type RawRepoConfig = Record; @@ -58,7 +58,7 @@ function normalizeRepo(repo: string, config: RawRepoConfig): RegistryRepoConfig return { repo, emissionShare: numberValue(config.emission_share) ?? 0, - issueDiscoveryShare: numberValue(config.issue_discovery_share) ?? DEFAULT_SCORING_CONSTANTS.DEFAULT_ISSUE_DISCOVERY_SHARE ?? 0.5, + issueDiscoveryShare: numberValue(config.issue_discovery_share) ?? DEFAULT_ISSUE_DISCOVERY_SHARE, labelMultipliers, trustedLabelPipeline: booleanValue(config.trusted_label_pipeline), maintainerCut: numberValue(config.maintainer_cut) ?? 0, diff --git a/src/scoring/model.ts b/src/scoring/model.ts index 286d1ccfe4..3df6f2b3a5 100644 --- a/src/scoring/model.ts +++ b/src/scoring/model.ts @@ -7,6 +7,8 @@ import { syncUnmodeledScoringConstantDrift } from "../upstream/unmodeled-scoring import type { JsonValue, ScoringModelSnapshotRecord } from "../types"; import { errorMessage, nowIso } from "../utils/json"; +export const DEFAULT_ISSUE_DISCOVERY_SHARE = 0.5; + export const DEFAULT_SCORING_CONSTANTS: Record = { OSS_EMISSION_SHARE: 0.9, // Upstream name is ISSUES_TREASURY_EMISSION_SHARE (plural). The prior singular spelling never matched @@ -30,7 +32,7 @@ export const DEFAULT_SCORING_CONSTANTS: Record = { OPEN_PR_COLLATERAL_PERCENT: 0.2, MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER: 2.0, MAX_LINES_SCORED_FOR_NON_CODE_EXT: 300, - DEFAULT_ISSUE_DISCOVERY_SHARE: 0.5, + DEFAULT_ISSUE_DISCOVERY_SHARE, REVIEW_PENALTY_RATE: 0.15, STANDARD_ISSUE_MULTIPLIER: 1.33, MAINTAINER_ISSUE_MULTIPLIER: 1.66, diff --git a/test/unit/registry.test.ts b/test/unit/registry.test.ts index ae1b530fe5..5ea072f2b1 100644 --- a/test/unit/registry.test.ts +++ b/test/unit/registry.test.ts @@ -1,6 +1,7 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { getRepository, upsertRepositoryFromGitHub } from "../../src/db/repositories"; import { normalizeRegistryPayload } from "../../src/registry/normalize"; +import { DEFAULT_ISSUE_DISCOVERY_SHARE } from "../../src/scoring/model"; import { getLatestRegistrySnapshot, persistRegistrySnapshot, refreshRegistry } from "../../src/registry/sync"; import { createTestEnv } from "../helpers/d1"; @@ -122,8 +123,15 @@ describe("registry normalization", () => { trustedLabelPipeline: true, }); expect(fromObjectMap.repositories.map((repo) => repo.repo)).toEqual(["JSONbored/gittensory"]); + expect(fromObjectMap.repositories[0]).toMatchObject({ + repo: "JSONbored/gittensory", + issueDiscoveryShare: DEFAULT_ISSUE_DISCOVERY_SHARE, + }); expect(fromArray.repositories.map((repo) => repo.repo)).toEqual(["JSONbored/gittensory", "bad/numbers"]); - expect(fromArray.repositories.find((repo) => repo.repo === "bad/numbers")).toMatchObject({ emissionShare: 0, issueDiscoveryShare: 0.5 }); + expect(fromArray.repositories.find((repo) => repo.repo === "bad/numbers")).toMatchObject({ + emissionShare: 0, + issueDiscoveryShare: DEFAULT_ISSUE_DISCOVERY_SHARE, + }); expect(empty.repoCount).toBe(0); }); diff --git a/test/unit/scoring.test.ts b/test/unit/scoring.test.ts index 81222082c5..7b0593e822 100644 --- a/test/unit/scoring.test.ts +++ b/test/unit/scoring.test.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { getLatestScoringModelSnapshot, listUpstreamDriftReports } from "../../src/db/repositories"; -import { DEFAULT_SCORING_CONSTANTS, detectActiveModel, findUnmodeledUpstreamConstants, isTimeDecayEnabled, parsePythonNumberConstants, refreshScoringModelSnapshot } from "../../src/scoring/model"; +import { DEFAULT_ISSUE_DISCOVERY_SHARE, DEFAULT_SCORING_CONSTANTS, detectActiveModel, findUnmodeledUpstreamConstants, isTimeDecayEnabled, parsePythonNumberConstants, refreshScoringModelSnapshot } from "../../src/scoring/model"; import { buildScorePreview, calculateTimeDecay, makeScorePreviewRecord, resolveTimeDecay } from "../../src/scoring/preview"; import { unmodeledScoringConstantsFingerprint } from "../../src/upstream/unmodeled-scoring-drift"; import type { ScorePreviewInput } from "../../src/scoring/preview"; @@ -103,8 +103,9 @@ MAX_CODE_DENSITY_MULTIPLIER = 1.15 expect(DEFAULT_SCORING_CONSTANTS).toMatchObject({ MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER: 2.0, MAX_LINES_SCORED_FOR_NON_CODE_EXT: 300, - DEFAULT_ISSUE_DISCOVERY_SHARE: 0.5, + DEFAULT_ISSUE_DISCOVERY_SHARE, }); + expect(DEFAULT_ISSUE_DISCOVERY_SHARE).toBe(0.5); expect( findUnmodeledUpstreamConstants(` MAX_OPEN_PR_REVIEW_COLLATERAL_MULTIPLIER = 2.0