diff --git a/drift-proposals/openai-gpt-6.1-terra-new-family.md b/drift-proposals/openai-gpt-6.1-terra-new-family.md new file mode 100644 index 00000000..13f75db9 --- /dev/null +++ b/drift-proposals/openai-gpt-6.1-terra-new-family.md @@ -0,0 +1,45 @@ +# New / unclassified model family: gpt-6.1-terra + +Provider: openai +Detected: 2026-10-26 +Status: RESOLVED — decision recorded below and applied to the registry + +This model family appeared in a live /models listing but matches no classification rule (include, exclude, -preview, gemma). drift-sync never silently classifies a new family. + +## Decision + +Decision: INCLUDE (applied 2026-10-26 — includeFamilies.openai in +`src/__tests__/drift/model-registry.ts`, with the `includeFamilies.openai` +re-pin in `src/__tests__/drift/logic-pin.test.ts`, plus the static OpenAI +/models wave in `src/__tests__/drift/models.drift.ts`). + +Rationale: gpt-6.1 point release of the included `gpt-5.6-terra` line and +sibling of the included `gpt-6.1-sol`. The normalizer keeps the `.1` version +token, so it is its own family and must be enumerated. + +Evidence (live, 2026-10-26): `GET /v1/models/gpt-6.1-terra` returned 200 with +`id`, `object`, `created: 1791908780`, `owned_by: "system"`, +`shutdown_date: null` — no capability field, the same shape as `gpt-6.1-sol`. +A minimal `POST /v1/chat/completions` with `model: "gpt-6.1-terra"` returned +200, `object: "chat.completion"`, `finish_reason: "stop"`, and a real assistant +text turn. It is text chat on the surface aimock mocks. Not a voice/audio +family, so no `knownVoiceModelFamilies` edit is needed. diff --git a/src/__tests__/drift/logic-pin.test.ts b/src/__tests__/drift/logic-pin.test.ts index 3151ca1f..13429a5d 100644 --- a/src/__tests__/drift/logic-pin.test.ts +++ b/src/__tests__/drift/logic-pin.test.ts @@ -456,7 +456,7 @@ describe("classification-logic checksum freeze (Phase-0 anti-silence guard)", () const DATA_FROZEN: Record string[]; pin: string }> = { "includeFamilies.openai": { members: () => [...includeFamilies.openai].sort(), - pin: "7c28e670d7ce3a5903b47aa605f3af391ba816529eaefbb4f81ac4f60c30ec0a", + pin: "d62f65955c9b867171e8889381bb818c724a3b5f9c3a60fcdf51716f82ee05ca", }, "includeFamilies.anthropic": { members: () => [...includeFamilies.anthropic].sort(), diff --git a/src/__tests__/drift/model-registry.ts b/src/__tests__/drift/model-registry.ts index e4c36097..b84df9bb 100644 --- a/src/__tests__/drift/model-registry.ts +++ b/src/__tests__/drift/model-registry.ts @@ -144,6 +144,23 @@ export const includeFamilies: Record> = { // Decision: INCLUDE, recorded in // drift-proposals/openai-gpt-6.1-sol-new-family.md. "gpt-6.1-sol", + // gpt-6.1 point release of the included `gpt-5.6-terra` line, sibling of + // `gpt-6.1-sol` above. First listed by drift run 40422235776 (2026-10-26; + // `created: 1791908780`). The normalizer keeps the `.1` version token, so + // it is its own family and must be enumerated. + // + // Classified on a LIVE PROBE (2026-10-26), not on lineage alone. + // `GET /v1/models/gpt-6.1-terra` returns only `id` / `object` / `created` / + // `owned_by: "system"` / `shutdown_date: null`, the same shape as + // `gpt-6.1-sol`. A minimal /v1/chat/completions call returned 200, + // `object: "chat.completion"`, `finish_reason: "stop"` and a real assistant + // text turn, the same shape `gpt-6.1-sol` returned. No name token places it + // in an excluded cluster, and it is not a voice/audio family, so no + // knownVoiceModelFamilies pairing. + // + // Decision: INCLUDE, recorded in + // drift-proposals/openai-gpt-6.1-terra-new-family.md. + "gpt-6.1-terra", // Codex line (coding chat; text output) "gpt-5-codex", "gpt-5.1-codex", diff --git a/src/__tests__/drift/models.drift.ts b/src/__tests__/drift/models.drift.ts index 83ef4dfa..14eb8475 100644 --- a/src/__tests__/drift/models.drift.ts +++ b/src/__tests__/drift/models.drift.ts @@ -1040,6 +1040,8 @@ describe("recorded /models family waves are classified", () => { // gpt-6.1 point release (2026-09-24..30 wave, first listed 09-30; its own // normalized family) "gpt-6.1-sol", + // gpt-6.1-terra (2026-10-26 wave, drift run 40422235776; probe-verified text chat) + "gpt-6.1-terra", // o-series reasoning "o1", "o1-pro", diff --git a/src/__tests__/drift/text-drift.test.ts b/src/__tests__/drift/text-drift.test.ts index 608e2526..eca6c4a4 100644 --- a/src/__tests__/drift/text-drift.test.ts +++ b/src/__tests__/drift/text-drift.test.ts @@ -11,7 +11,7 @@ import { describe, it, expect } from "vitest"; -import { isClassifiedFamily, excludeFamilies } from "./model-registry.js"; +import { isClassifiedFamily, excludeFamilies, includeFamilies } from "./model-registry.js"; import { normalizeModelFamily } from "./model-family.js"; import { unclassifiedFamilies } from "./text-drift.js"; @@ -562,3 +562,27 @@ describe("the 2026-10-14..18 model-family waves are classified", () => { ]); }); }); + +// --------------------------------------------------------------------------- +// The 2026-10-26 wave — BEHAVIOURAL coverage of `gpt-6.1-terra` (INCLUDE), in +// the same shape as the blocks above. Evidence sits beside the entry in +// model-registry.ts and in drift-proposals/. +// --------------------------------------------------------------------------- + +describe("the 2026-10-26 model-family wave is classified", () => { + it("gpt-6.1-terra is INCLUDED in a /models-shaped payload", () => { + expect(includeFamilies.openai.has("gpt-6.1-terra")).toBe(true); + expect(isClassifiedFamily("gpt-6.1-terra", "openai")).toBe(true); + expect(excludeFamilies.openai.has("gpt-6.1-terra")).toBe(false); + expect(unclassifiedFamilies(["gpt-6.1-sol", "gpt-6.1-terra"], "openai")).toEqual([]); + }); + + it("the new key does not classify a neighbouring family", () => { + // NEGATIVE CONTROLS: without these, `toEqual([])` above is also what a + // neutered `unclassifiedFamilies` would produce. + expect(normalizeModelFamily("gpt-6.1-terra", "openai")).toBe("gpt-6.1-terra"); + expect(unclassifiedFamilies(["gpt-6.1-luna"], "openai")).toEqual(["gpt-6.1-luna"]); + expect(unclassifiedFamilies(["gpt-6.2-terra"], "openai")).toEqual(["gpt-6.2-terra"]); + expect(unclassifiedFamilies(["gpt-6.1-terra-tts"], "openai")).toEqual(["gpt-6.1-terra-tts"]); + }); +});