Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/scoring/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,27 @@
// Number() rejects underscore separators, so strip them before parsing.
constants[name] = Number(raw.replace(/_/g, ""));
}
return constants;

Check notice on line 167 in src/scoring/model.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.

Check notice on line 167 in src/scoring/model.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Open PR queue is busy

This repo has a busy open PR queue in the local Gittensory cache.
}

/**
* Upstream operational/infra constants gittensory intentionally does not model in score previews.
* They are not scoring dimensions — surfacing them as "unmodeled drift" is noise (#809).
*/
const NON_SCORING_UPSTREAM_CONSTANT_NAMES = new Set([
"SECONDS_PER_DAY",
"SECONDS_PER_HOUR",
"GITHUB_HTTP_TIMEOUT_SECONDS",
"MIRROR_HTTP_TIMEOUT_SECONDS",
"MIRROR_MAX_ATTEMPTS",
"TREE_SITTER_PARSE_TIMEOUT_MICROS",
"SCORING_SUBPROCESS_BUDGET_S",
"MAX_FILE_SIZE_BYTES",
"RECYCLE_UID",
"ISSUES_TREASURY_UID",
"MAX_ISSUE_ID",
]);

/**
* Numeric constant names upstream gittensor defines that gittensory's scoring engine does NOT model.
* The normal parse is `knownOnly` (it keeps only constants we already encode), which silently hides
Expand All @@ -176,7 +194,7 @@
*/
export function findUnmodeledConstantKeys(allConstants: Record<string, number>): string[] {
return Object.keys(allConstants)
.filter((name) => !SCORING_CONSTANT_NAMES.has(name))
.filter((name) => !SCORING_CONSTANT_NAMES.has(name) && !NON_SCORING_UPSTREAM_CONSTANT_NAMES.has(name))
.sort();
}

Expand Down
48 changes: 48 additions & 0 deletions test/unit/scoring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,57 @@
);
expect(unmodeled).toEqual(["NOVELTY_BONUS_SCALAR"]);
expect(unmodeled).not.toContain("SRC_TOK_SATURATION_SCALE");
expect(unmodeled).not.toContain("TIME_DECAY_GRACE_PERIOD_HOURS"); // modeled as of #703

Check notice on line 218 in test/unit/scoring.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.

Check notice on line 218 in test/unit/scoring.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Open PR queue is busy

This repo has a busy open PR queue in the local Gittensory cache.
});

it("excludes operational upstream constants from unmodeled scoring drift (#809)", () => {
const operationalOnly = findUnmodeledUpstreamConstants(`
SECONDS_PER_DAY = 86400
SECONDS_PER_HOUR = 3600
GITHUB_HTTP_TIMEOUT_SECONDS = 15
MIRROR_HTTP_TIMEOUT_SECONDS = 30
MIRROR_MAX_ATTEMPTS = 3
TREE_SITTER_PARSE_TIMEOUT_MICROS = 5_000_000
SCORING_SUBPROCESS_BUDGET_S = 120
MAX_FILE_SIZE_BYTES = 1_000_000
RECYCLE_UID = 0
ISSUES_TREASURY_UID = 111
MAX_ISSUE_ID = 999_999
`);
expect(operationalOnly).toEqual([]);

const withScoringGap = findUnmodeledUpstreamConstants(`
SECONDS_PER_DAY = 86400
GITHUB_HTTP_TIMEOUT_SECONDS = 15
NOVELTY_BONUS_SCALAR = 3
`);
expect(withScoringGap).toEqual(["NOVELTY_BONUS_SCALAR"]);
});

it("truncates the unmodeled-constants warning when upstream defines more than 12 (#809)", async () => {
const env = createTestEnv({
GITTENSOR_UPSTREAM_REPO: "custom/upstream",
GITTENSOR_UPSTREAM_REF: "staging",
});
const manyUnmodeled = Array.from({ length: 15 }, (_, index) => `UNMODELED_CONST_${String(index).padStart(2, "0")} = ${index + 1}`).join("\n");
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
if (url.includes("constants.py")) return new Response(manyUnmodeled);
if (url.includes("programming_languages.json")) return Response.json({});
return new Response("not found", { status: 404 });
});

const refreshed = await refreshScoringModelSnapshot(env);
const warning = refreshed.warnings.find((entry) => /does not yet model/i.test(entry));
expect(warning).toMatch(/UNMODELED_CONST_00/);
expect(warning).toMatch(/UNMODELED_CONST_11/);
expect(warning).not.toMatch(/UNMODELED_CONST_12/);
expect(warning).toMatch(/…/);
expect(refreshed.payload.constants).toMatchObject({
unmodeledUpstreamConstants: expect.arrayContaining(["UNMODELED_CONST_00", "UNMODELED_CONST_14"]),
});
});

it("warns on the snapshot when upstream defines an unmodeled scoring dimension", async () => {
const env = createTestEnv({
GITTENSOR_UPSTREAM_REPO: "custom/upstream",
Expand Down
Loading