Files
gstack/test/fixtures/model-policy-freshness.ts
Garry Tan 92cfd07a79 v1.91.45.0 feat: configurable model tiers and advisory freshness (#3073)
* feat: add configurable model tiers and advisory freshness

* fix: disclose role selections before Claude review execution

* fix: reject malformed model policies and keep model pins portable

* fix: separate readiness diagnostics and bound version checks

* fix: preserve actionable model failures and validate review inputs before probes

* fix: retry released probe locks and retain late-rejection repair context

* feat: finalize configurable model tiers and verified release repairs

* fix: preserve strict model policy reads on Windows

* fix: keep fixture probes read-only and clarify pending CEO decisions

* fix: verify native terminal closure before bounded descriptor settlement
2026-10-08 08:00:08 +00:00

43 lines
2.4 KiB
TypeScript

import { readFileSync } from 'node:fs';
import { FRESHNESS_SOURCES, parseOfficialSource, sha256, type SourceId, type SourceResult } from '../../lib/model-policy-freshness-sources';
import type { CatalogIdentity, FreshnessObservation } from '../../lib/model-policy-freshness';
export const freshnessCatalog: CatalogIdentity = {
sha256: sha256('catalog-v1'), sourceSha256: sha256('catalog-source-v1'), version: 1,
models: [
{ provider: 'anthropic', tier: 'frontier', modelId: 'claude-fable-5-1' },
{ provider: 'anthropic', tier: 'smart', modelId: 'claude-opus-5-5' },
{ provider: 'openai', tier: 'frontier', modelId: 'gpt-6-astra' },
{ provider: 'openai', tier: 'smart', modelId: 'gpt-6.1-sol' },
],
};
export function freshnessFixture(id: SourceId): string {
return readFileSync(new URL(`./model-policy-freshness/${id}.md`, import.meta.url), 'utf8');
}
export function freshnessObservation(id = '100', at = '2026-10-07T12:00:00.000Z', overrides: Partial<Record<SourceId, string | null>> = {}): FreshnessObservation {
const sources: SourceResult[] = FRESHNESS_SOURCES.map(source => {
const text = overrides[source.id] === undefined ? freshnessFixture(source.id) : overrides[source.id];
return text === null ? { id: source.id, error: 'http-503' } : {
id: source.id, receipt: { id: source.id, url: source.url, finalUrl: source.url, sha256: sha256(text!), bytes: Buffer.byteLength(text!), parsed: parseOfficialSource(source.id, text!) },
};
});
return { catalog: structuredClone(freshnessCatalog), checkedAt: at, run: { id, attempt: 1, startedAt: new Date(Date.parse(at) - 1000).toISOString(), headSha: 'a'.repeat(40) }, sources };
}
export function retirementFixture(): string {
return freshnessFixture('anthropic-lifecycle').replace('claude-fable-5-1 | Active | N/A | Not sooner than September 1, 2027', 'claude-fable-5-1 | Deprecated | October 1, 2026 | November 1, 2026');
}
export function freshnessReplacementObservation(): FreshnessObservation {
const observation = freshnessObservation('101', '2026-10-08T12:00:00.000Z', {
'anthropic-models': freshnessFixture('anthropic-models').replaceAll('fable-5-1', 'fable-5-2'),
'anthropic-lifecycle': freshnessFixture('anthropic-lifecycle').replaceAll('fable-5-1', 'fable-5-2'),
});
observation.catalog.models[0].modelId = 'claude-fable-5-2';
observation.catalog.sha256 = 'b'.repeat(64);
observation.catalog.sourceSha256 = 'c'.repeat(64);
return observation;
}