Files
gstack/test/preamble-compose.test.ts
Rocky 834c6db075
Some checks failed
Workflow Lint / actionlint (push) Has been cancelled
Build CI Image / build (push) Has been cancelled
Skill Docs Freshness / check-freshness (push) Has been cancelled
Periodic Evals / build-image (push) Has been cancelled
Periodic Evals / evals (map[file:test/codex-e2e.test.ts name:e2e-codex]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/gemini-e2e.test.ts name:e2e-gemini]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-design.test.ts name:e2e-design]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-plan.test.ts name:e2e-plan]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-bugs.test.ts name:e2e-qa-bugs]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-workflow.test.ts name:e2e-qa-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-review.test.ts name:e2e-review]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-workflow.test.ts name:e2e-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-routing-e2e.test.ts name:e2e-routing]) (push) Has been cancelled
Initial import from garrytan/gstack@026751e (main snapshot via local relay)
Source: https://github.com/garrytan/gstack/commit/026751e
2026-05-19 21:18:17 +02:00

73 lines
3.0 KiB
TypeScript

/**
* Preamble composition order — gate-tier test.
*
* Asserts that the AskUserQuestion Format section renders BEFORE the
* Model-Specific Behavioral Patch section in tier-≥2 preamble output.
* This order is load-bearing: Opus 4.7 reads top-to-bottom and absorbs
* the first pacing directive it hits. v1.6.4.0 regressed plan-review
* cadence because the overlay rendered first with "Batch your questions"
* as the ambient default.
*
* If someone later reorders `scripts/resolvers/preamble.ts` so Overlay
* comes before Format, this test catches it before the next model
* migration can silently re-break the plan-review pacing.
*/
import { describe, test, expect } from 'bun:test';
import type { TemplateContext } from '../scripts/resolvers/types';
import { HOST_PATHS } from '../scripts/resolvers/types';
import { generatePreamble } from '../scripts/resolvers/preamble';
function makeCtx(
host: 'claude' | 'codex',
tier: 1 | 2 | 3 | 4,
model?: string,
): TemplateContext {
return {
skillName: 'test-skill',
tmplPath: 'test.tmpl',
host,
paths: HOST_PATHS[host],
preambleTier: tier,
...(model ? { model } : {}),
};
}
describe('Preamble composition order', () => {
test('AskUserQuestion Format renders before Model-Specific Behavioral Patch (tier 2, claude)', () => {
const out = generatePreamble(makeCtx('claude', 2, 'claude'));
const formatIdx = out.indexOf('## AskUserQuestion Format');
const overlayIdx = out.indexOf('## Model-Specific Behavioral Patch');
expect(formatIdx).toBeGreaterThan(-1);
expect(overlayIdx).toBeGreaterThan(-1);
expect(formatIdx).toBeLessThan(overlayIdx);
});
test('AskUserQuestion Format renders before Model-Specific Behavioral Patch (tier 2, opus-4-7)', () => {
const out = generatePreamble(makeCtx('claude', 2, 'opus-4-7'));
const formatIdx = out.indexOf('## AskUserQuestion Format');
const overlayIdx = out.indexOf('## Model-Specific Behavioral Patch');
expect(formatIdx).toBeGreaterThan(-1);
expect(overlayIdx).toBeGreaterThan(-1);
expect(formatIdx).toBeLessThan(overlayIdx);
});
test('AskUserQuestion Format renders before Model-Specific Behavioral Patch (tier 3)', () => {
const out = generatePreamble(makeCtx('claude', 3, 'opus-4-7'));
const formatIdx = out.indexOf('## AskUserQuestion Format');
const overlayIdx = out.indexOf('## Model-Specific Behavioral Patch');
expect(formatIdx).toBeLessThan(overlayIdx);
});
test('AskUserQuestion Format renders before Model-Specific Behavioral Patch (codex host)', () => {
const out = generatePreamble(makeCtx('codex', 2, 'opus-4-7'));
const formatIdx = out.indexOf('## AskUserQuestion Format');
const overlayIdx = out.indexOf('## Model-Specific Behavioral Patch');
expect(formatIdx).toBeLessThan(overlayIdx);
});
test('tier 1 preamble does NOT include AskUserQuestion Format (but MAY include overlay)', () => {
const out = generatePreamble(makeCtx('claude', 1));
expect(out).not.toContain('## AskUserQuestion Format');
});
});