Files
gstack/test/model-overlay-gpt-5.6-sol.test.ts
T
Garry TanandClaude Fable 5 3bc3b5d5f9 fix(test): drop stale generate-lake-intro import (generator deleted in the emission-layer move)
Sol scope discipline stays pinned via the model overlay + completeness
section; the lake intro is now a single script-emitted blurb.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 17:52:26 +00:00

85 lines
3.9 KiB
TypeScript

import { describe, expect, test } from 'bun:test';
import { resolveModel } from '../scripts/models';
import { generateModelOverlay, readOverlay } from '../scripts/resolvers/model-overlay';
import { generateCompletenessSection } from '../scripts/resolvers/preamble/generate-completeness-section';
import { generateSetupCommand } from '../scripts/resolvers/utility';
import type { TemplateContext } from '../scripts/resolvers/types';
function ctx(model: TemplateContext['model']): TemplateContext {
return {
skillName: 'investigate',
tmplPath: 'investigate/SKILL.md.tmpl',
host: 'codex',
paths: {
skillRoot: '$GSTACK_ROOT',
localSkillRoot: '.agents/skills/gstack',
binDir: '$GSTACK_BIN',
browseDir: '$GSTACK_BROWSE',
designDir: '$GSTACK_DESIGN',
makePdfDir: '$GSTACK_MAKE_PDF',
},
preambleTier: 3,
model,
};
}
describe('GPT-5.6 Sol model profile', () => {
test('only the exact Sol ID selects the Sol profile', () => {
expect(resolveModel('gpt-5.6-sol')).toBe('gpt-5.6-sol');
expect(resolveModel('gpt-5.6-terra')).toBe('gpt');
expect(resolveModel('gpt-5.6-luna')).toBe('gpt');
expect(resolveModel('gpt-5.6-sol-preview')).toBe('gpt');
expect(resolveModel('gpt-5.7')).toBe('gpt');
});
test('standalone overlay does not inherit generic GPT completion bias', () => {
const raw = readOverlay('gpt-5.6-sol');
expect(raw).toContain('The explicit task is the lake');
expect(raw).toContain('one clean relevant verification pass');
expect(raw).toContain('report-only');
expect(raw).not.toContain('{{INHERIT:gpt}}');
expect(raw).not.toContain('make your best judgment and proceed');
});
test('wrapper gives scope interpretation precedence but preserves concrete gates', () => {
const out = generateModelOverlay(ctx('gpt-5.6-sol'));
expect(out).toContain('disambiguate scope');
expect(out).toContain('Concrete skill workflow steps');
expect(out).toContain('Never use this patch to skip a concrete requirement');
});
// The lake intro moved from a per-model render-time generator into
// bin/gstack-skill-start's one-time emission layer (token-reduction Phase 2).
// Sol's scope discipline is carried by the model overlay + completeness
// section (both still model-conditional and pinned here); the intro itself
// is a single display-once blurb emitted by the script.
test('completeness copy stays inside the explicit task boundary', () => {
const completeness = generateCompletenessSection(ctx('gpt-5.6-sol'));
expect(completeness).toContain("inside the user's explicit task boundary");
expect(completeness).toContain('report them, do not implement them');
expect(completeness).toContain('all relevant in-scope edge cases');
});
test('generic GPT copy remains unchanged', () => {
const generic = generateModelOverlay(ctx('gpt'));
const completeness = generateCompletenessSection(ctx('gpt'));
expect(generic).toContain('make your best judgment and proceed');
expect(completeness).toContain('the complete thing is the goal');
});
test('terse mode still suppresses the completeness section for Sol', () => {
// Terse short-circuits before the Sol branch — a check-order flip would
// ship Sol completeness prose to terse users (a token regression).
expect(generateCompletenessSection({ ...ctx('gpt-5.6-sol'), explainLevel: 'terse' })).toBe('');
});
});
describe('SETUP_COMMAND resolver', () => {
test('claude keeps bare ./setup; every other host reinstalls itself', () => {
expect(generateSetupCommand({ ...ctx('claude'), host: 'claude' })).toBe('./setup');
expect(generateSetupCommand({ ...ctx('gpt'), host: 'codex' })).toBe('./setup --host codex');
expect(generateSetupCommand({ ...ctx('claude'), host: 'kiro' })).toBe('./setup --host kiro');
expect(generateSetupCommand({ ...ctx('claude'), host: 'factory' })).toBe('./setup --host factory');
});
});