Files
OmniRoute/tests/unit/check-model-lifecycle-gate.test.ts
MumuTW ae7a843e86 fix(autoCombo,sse): catalog hygiene — retire dead FITNESS_TABLE rows, fix 7 BUILT_IN_ALIASES targets, add model-lifecycle gate (#11503) (#11507)
Validated in a combined 4-PR batch worktree off release/v3.8.51 tip. This PR's diff overlapped taskFitness.ts and autoCombo.test.ts with the already-merged #11492/#11506 — git's merge auto-resolved both hunks cleanly (non-overlapping layers: #11492/#11506 touch layer 2 arena lookup, this PR touches layer 4 static-table hygiene); verified no conflict markers remained and re-ran the full suite after boarding.
- npm run check:model-lifecycle — PASS, 68 retired ids, 1327 catalog ids, 0 violations (re-ran with the correct `node --import tsx/esm` loader after an initial bare-node invocation mistakenly failed on path-alias resolution — that was my invocation error, not the gate)
- Focused tests: fitness-table-hygiene-11503.test.ts, taskFitness-pattern-order-8603.test.ts, model-deprecation-aliases-11503.test.ts, check-model-lifecycle-gate.test.ts, model-deprecation.test.ts, autoCombo.test.ts — part of batch's 126/126 vitest + 246/246 node:test runs
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity, check:cycles — all OK
- Full-repo lint: 228 problems remaining, all pre-existing dashboard react-hooks/* findings unrelated to this diff (zero errors in any file this PR touches)

Thanks for this — genuinely thorough methodology (segment-boundary matching, provider-scoped alias guard, offline lifecycle gate with a documented burn-down list for the 6 remaining catalog offenders).
2026-08-25 13:52:23 -03:00

96 lines
3.5 KiB
TypeScript

/**
* Unit coverage for the #11503 drift gate (`scripts/check/check-model-lifecycle.mjs`).
*
* The gate's value is that it goes red when a hand-maintained routing table starts
* pointing at a model the vendor retired, so each of its three checks is exercised here
* against small fixtures rather than against the live catalog (which would make the test
* a duplicate of the gate run itself, and red for reasons unrelated to the logic).
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import {
collectCatalogIds,
isRetiredId,
findRetiredFitnessRows,
findBadAliasTargets,
findUnforwardedRetiredIds,
} from "../../scripts/check/check-model-lifecycle.mjs";
const RETIRED = new Set(["dead-model-1", "dead-model-2", "gpt-5.2-codex"]);
describe("check-model-lifecycle: catalog extraction", () => {
it("collects model ids and their aliases", () => {
const registry = {
alpha: { models: [{ id: "live-1", aliases: ["live-1-alias"] }, { id: "dead-model-1" }] },
beta: { models: [{ id: "live-2" }] },
gamma: {},
};
assert.deepEqual(collectCatalogIds(registry).sort(), [
"dead-model-1",
"live-1",
"live-1-alias",
"live-2",
]);
});
it("treats a vendor-prefixed id as retired when its bare form is", () => {
assert.equal(isRetiredId("openai/gpt-5.2-codex", RETIRED), true);
assert.equal(isRetiredId("GPT-5.2-Codex", RETIRED), true);
assert.equal(isRetiredId("live-1", RETIRED), false);
});
});
describe("check-model-lifecycle: (a) retired ids scored by FITNESS_TABLE", () => {
const scoreFor = (id: string, task: string) =>
id === "dead-model-1" && task === "coding" ? 0.98 : null;
it("flags a retired id the table still scores", () => {
const violations = findRetiredFitnessRows(["dead-model-1"], scoreFor, ["coding", "review"]);
assert.equal(violations.length, 1);
assert.match(violations[0], /dead-model-1 scores 0\.98 for "coding"/);
});
it("passes when no retired id resolves through the table", () => {
assert.deepEqual(findRetiredFitnessRows(["dead-model-2"], scoreFor, ["coding"]), []);
});
});
describe("check-model-lifecycle: (b) alias targets", () => {
const catalog = ["live-1", "dead-model-1"];
it("flags a target absent from the catalog", () => {
const violations = findBadAliasTargets({ old: "not-in-catalog" }, catalog, RETIRED);
assert.equal(violations.length, 1);
assert.match(violations[0], /no provider in REGISTRY serves this id/);
});
it("flags a target the vendor has retired", () => {
const violations = findBadAliasTargets({ old: "dead-model-1" }, catalog, RETIRED);
assert.equal(violations.length, 1);
assert.match(violations[0], /the vendor has retired this id/);
});
it("passes for a live catalog target", () => {
assert.deepEqual(findBadAliasTargets({ old: "live-1" }, catalog, RETIRED), []);
});
});
describe("check-model-lifecycle: (c) routable retired ids", () => {
it("flags a retired id with neither forward nor allowlist entry", () => {
const violations = findUnforwardedRetiredIds(["dead-model-1"], {}, []);
assert.equal(violations.length, 1);
assert.match(violations[0], /retired but still routable/);
});
it("accepts an allowlisted id", () => {
assert.deepEqual(findUnforwardedRetiredIds(["dead-model-1"], {}, ["dead-model-1"]), []);
});
it("accepts an id that has a BUILT_IN_ALIASES forward", () => {
assert.deepEqual(
findUnforwardedRetiredIds(["dead-model-1"], { "dead-model-1": "live-1" }, []),
[]
);
});
});