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
4 changes: 3 additions & 1 deletion src/scoring/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ export async function refreshScoringModelSnapshot(env: Env): Promise<ScoringMode
},
};
await persistScoringModelSnapshot(env, snapshot);
if (constantsResult.ok) {
// Only sync unmodeled-constant drift against a usable constants.py body — a 200-with-garbage
// response (no valid lastGood) must not open a spurious upstream_drift_reports row (#8902).
if (constantsUsable) {
await syncUnmodeledScoringConstantDrift(env, {
unmodeledConstants: findUnmodeledUpstreamConstants(constantsResult.value),
source: { repo: upstream.repo, ref: fetchRef, commitSha: upstreamSourceSha },
Expand Down
9 changes: 8 additions & 1 deletion test/unit/scoring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,14 +603,21 @@ NOVELTY_BONUS_SCALAR = 3
const env = createTestEnv();
vi.stubGlobal("fetch", async (input: RequestInfo | URL) => {
const url = input.toString();
if (url.includes("constants.py")) return new Response("<!DOCTYPE html><html><body>rate limited</body></html>");
// HTML garbage that still parses a few IDENT = number lines (or none) — below the recognized floor.
// Include a fake "unmodeled" CONSTANT so findUnmodeledUpstreamConstants would fire if the drift
// sync still ran on garbage (#8902).
if (url.includes("constants.py")) {
return new Response("<!DOCTYPE html><html><body>rate limited</body></html>\nFAKE_UNMODELED_CONSTANT = 1\n");
}
if (url.includes("programming_languages.json")) return Response.json({});
return new Response("not found", { status: 404 });
});
const refreshed = await refreshScoringModelSnapshot(env);
expect(refreshed.sourceKind).toBe("fallback"); // labeled fallback, NOT a deceptive raw-github
expect(refreshed.warnings.join(" ")).toMatch(/parsed only \d+ recognized constant/i);
expect(refreshed.constants.MERGED_PR_BASE_SCORE).toBe(25); // the hardcoded default
// Guard must check constantsUsable, not merely HTTP-ok — no spurious drift report (#8902).
await expect(listUpstreamDriftReports(env)).resolves.toEqual([]);
});

it("bootstraps to defaults (fallback) on a failed fetch ONLY when there is no verified last-good", async () => {
Expand Down