Skip to content
Open
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
17 changes: 17 additions & 0 deletions model-overlays/sonnet-5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{INHERIT:claude}}

**Instructions are read literally.** Sonnet 5 does not silently generalize an
instruction from one item to the next, and it does not infer requests you didn't
make. When something should apply broadly, say so ("apply this to every section,
not just the first"). Re-baseline holdover style directives — they now land at
face value.

**Scope work to the request.** At lower effort especially, Sonnet 5 scopes to
exactly what was asked rather than going above and beyond. If reasoning looks
shallow on a genuinely complex task, that is an effort signal: raise effort rather
than adding prose guardrails.

**Verbosity tracks task complexity.** Responses calibrate length to how complex
the task looks — shorter on lookups, longer on open-ended analysis. If you need a
specific length or format, state it; a positive example of the target beats a
"don't be verbose" instruction.
2 changes: 2 additions & 0 deletions scripts/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
export const ALL_MODEL_NAMES = [
'claude',
'opus-4-7',
'sonnet-5',
'gpt',
'gpt-5.4',
'gemini',
Expand Down Expand Up @@ -53,6 +54,7 @@ export function resolveModel(input: string): Model | null {
if (/^gpt(-|$)/.test(s)) return 'gpt';
if (/^o[0-9]+(-|$)/.test(s)) return 'o-series';
if (/^claude-opus-4-7(-|$)/.test(s)) return 'opus-4-7';
if (/^claude-sonnet-5(-|$)/.test(s)) return 'sonnet-5';
if (/^claude(-|$)/.test(s)) return 'claude';
if (/^gemini(-|$)/.test(s)) return 'gemini';

Expand Down
56 changes: 56 additions & 0 deletions test/model-overlay-sonnet-5.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Sonnet 5 model overlay — gate-tier assertions on the family nudges.
*
* sonnet-5 inherits the claude base and adds Sonnet-5 family nudges: literal
* instruction following (state scope explicitly), scope work to the request
* (raise effort rather than prompting around shallow reasoning), and
* verbosity that tracks task complexity.
*/
import { describe, test, expect } from 'bun:test';
import * as fs from 'fs';
import * as path from 'path';
import type { TemplateContext } from '../scripts/resolvers/types';
import { HOST_PATHS } from '../scripts/resolvers/types';
import { generateModelOverlay } from '../scripts/resolvers/model-overlay';

function makeCtx(model: string): TemplateContext {
return {
skillName: 'test-skill',
tmplPath: 'test.tmpl',
host: 'claude',
paths: HOST_PATHS.claude,
preambleTier: 2,
model,
};
}

const ROOT = path.resolve(__dirname, '..');

describe('Sonnet 5 overlay — family nudges', () => {
test('raw sonnet-5.md contains the literal-instructions nudge', () => {
const raw = fs.readFileSync(path.join(ROOT, 'model-overlays/sonnet-5.md'), 'utf-8');
expect(raw).toContain('Instructions are read literally');
});

test('resolved overlay inherits from claude base (INHERIT:claude)', () => {
const out = generateModelOverlay(makeCtx('sonnet-5'));
expect(out).toContain('Todo-list discipline');
expect(out).toContain('subordinate');
});

test('resolved overlay carries the Sonnet 5 nudges', () => {
const out = generateModelOverlay(makeCtx('sonnet-5'));
expect(out).toContain('Instructions are read literally');
expect(out).toContain('Scope work to the request');
});

test('resolved overlay has no unresolved INHERIT directive', () => {
const out = generateModelOverlay(makeCtx('sonnet-5'));
expect(out).not.toContain('{{INHERIT:');
});

test('claude overlay (base) does not carry the Sonnet 5 nudge', () => {
const out = generateModelOverlay(makeCtx('claude'));
expect(out).not.toContain('Instructions are read literally');
});
});