mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-08 01:38:10 +01:00
106 lines
6.3 KiB
TypeScript
106 lines
6.3 KiB
TypeScript
import { expect, test } from 'bun:test';
|
||
import { hasNativePostAnswerCeoPosture, nativeCeoModeAnswer } from './helpers/ceo-mode-option';
|
||
import type { PlanCountTranscript } from './helpers/plan-count-transcript';
|
||
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
|
||
import captured from './fixtures/ceo-hold-commitment-ar.json';
|
||
|
||
const posture = /\b(rigor|bulletproof|hold\s*scope|maximum\s+rigor)\b/i;
|
||
const original = captured.transcript.assistantMessages[0]!.text;
|
||
const replay = () => structuredClone(captured.transcript) as PlanCountTranscript;
|
||
const matches = (transcript = replay()) => hasNativePostAnswerCeoPosture(
|
||
transcript, 'HOLD SCOPE', posture, captured.selectionStartedAt,
|
||
);
|
||
const withText = (text: string) => { const t = replay(); t.assistantMessages[0]!.text = text; return matches(t); };
|
||
|
||
test('the actual failed attempt adopted HOLD through scope, hardening and exclusion', () => {
|
||
expect(captured.provenance.actualState).toBe('failed');
|
||
expect(nativeCeoModeAnswer(replay(), 'HOLD SCOPE', captured.selectionStartedAt)?.toolUseId)
|
||
.toBe('toolu_01E1HnYjRCz79826bo7nNnoK');
|
||
expect(posture.test(original)).toBe(false);
|
||
expect(matches()).toBe(true);
|
||
// This is prospective posture recognition, not evidence of completed work.
|
||
for (const prefix of ["I'm keeping", 'I am keeping', 'I will keep', "We'll keep", 'We will keep', 'We are keeping']) {
|
||
expect(withText(original.replace("I'll keep", prefix)), prefix).toBe(true);
|
||
}
|
||
expect(withText(original.replace("I'll", 'I’ll').replace("PLAN.md's", 'PLAN.md’s'))).toBe(true);
|
||
});
|
||
|
||
test('explicitly future, conditional and quoted statements are not adopted current posture', () => {
|
||
for (const text of [
|
||
original.replace("I'll keep", 'I will later keep'),
|
||
original.replace("I'll keep", 'I will eventually keep'),
|
||
original.replace("I'll keep", 'I would keep'),
|
||
original.replace("I'll keep", 'I may keep'),
|
||
original.replace("I'll keep", "I'll not keep"),
|
||
original.replace('scope fixed', 'scope tomorrow fixed'),
|
||
original.replace('production visibility', 'production visibility next week'),
|
||
original.replace('production visibility', 'production visibility tomorrow'),
|
||
...['after approval', 'once approved', 'when approved', 'after launch', 'pending approval', 'subject to approval'].map(when =>
|
||
original.replace('production visibility', 'production visibility ' + when)),
|
||
'Later, ' + original, 'If you approve, ' + original,
|
||
'Hypothetical scenario. ' + original, 'Example only: ' + original,
|
||
'"' + original + '"', '> ' + original,
|
||
'```text\n' + original + '\n```', '~~~text\n' + original + '\n~~~',
|
||
'Read(file)\n' + original, 'The user said: ' + original,
|
||
]) expect(withText(text), text).toBe(false);
|
||
});
|
||
|
||
test('all three obligations remain concrete and bound to the selected plan', () => {
|
||
for (const [from, to] of [
|
||
['PLAN.md', 'OTHER.md'], ['PLAN.md', 'archive/PLAN.md'],
|
||
["PLAN.md's four bullets plus the approved schema", 'the future expanded plan'],
|
||
['plus the approved schema', 'plus a new unapproved schema'],
|
||
[', pressure-testing every stated behavior for failure modes, errors, tests, and production visibility', ''],
|
||
['errors, tests, and production visibility', 'word choice and formatting'],
|
||
['while deferring anything extra rather than adding it silently', 'while adding anything extra'],
|
||
['while deferring', 'while not deferring'], ['pressure-testing', 'not pressure-testing'],
|
||
]) expect(withText(original.replace(from!, to!)), from).toBe(false);
|
||
for (const contextChange of [
|
||
(text: string) => text.replace('PLAN.md', 'PLAN.md and OTHER.md'),
|
||
(text: string) => text.replace('schema) approved', 'schema) not approved'),
|
||
(text: string) => text.replace('schema) approved', 'schema) discussed'),
|
||
...['approved if the user agrees', 'approved once migration finishes', 'approved pending migration', 'approved subject to migration'].map(status =>
|
||
(text: string) => text.replace('schema) approved', 'schema) ' + status)),
|
||
]) {
|
||
const t = replay(); const q = t.calls[0]!.questions[0]!; const prior = q.question;
|
||
q.question = contextChange(q.question); t.calls[0]!.answers = { [q.question]: t.calls[0]!.answers![prior]! };
|
||
expect(matches(t)).toBe(false);
|
||
}
|
||
});
|
||
|
||
test('current corrections withdraw a commitment; quoted corrections do not', () => {
|
||
for (const correction of [
|
||
'Correction: I will expand scope to include defaults.',
|
||
'Correction: I will not keep scope fixed to these requirements.',
|
||
'Correction: I am no longer keeping scope to those requirements.',
|
||
'The formerly excluded additions are in scope.',
|
||
]) {
|
||
expect(withText(original + '\n\n' + correction), correction).toBe(false);
|
||
for (const quote of ['> ' + correction, '```text\n' + correction + '\n```', '~~~text\n' + correction + '\n~~~', 'A quotation: "' + correction + '"']) {
|
||
expect(withText(original + '\n\n' + quote), quote).toBe(true);
|
||
}
|
||
}
|
||
});
|
||
|
||
test('native selection, session and timestamp evidence remain required', () => {
|
||
for (const change of [
|
||
(t: PlanCountTranscript) => { t.status = 'missing'; },
|
||
(t: PlanCountTranscript) => { t.calls[0]!.answered = false; },
|
||
(t: PlanCountTranscript) => { t.calls[0]!.failed = true; },
|
||
(t: PlanCountTranscript) => { t.calls[0]!.answeredAt = new Date(captured.selectionStartedAt - 1).toISOString(); },
|
||
(t: PlanCountTranscript) => { t.calls[0]!.answers![t.calls[0]!.questions[0]!.question] = 'Scope expansion'; },
|
||
(t: PlanCountTranscript) => { t.calls[0]!.answers![t.calls[0]!.questions[0]!.question] = 'Unknown'; },
|
||
(t: PlanCountTranscript) => { t.assistantMessages[0]!.sessionId = 'foreign'; },
|
||
(t: PlanCountTranscript) => { t.assistantMessages[0]!.timestamp = t.calls[0]!.answeredAt!; },
|
||
(t: PlanCountTranscript) => { t.assistantMessages[0]!.timestamp = 'invalid'; },
|
||
(t: PlanCountTranscript) => { t.assistantMessages[0]!.timestamp = new Date(Date.now() + 60_000).toISOString(); },
|
||
(t: PlanCountTranscript) => { t.assistantMessages = []; },
|
||
]) { const t = replay(); change(t); expect(matches(t)).toBe(false); }
|
||
});
|
||
|
||
test('new posture evidence selects the existing mode owner', () => {
|
||
for (const file of ['test/ceo-hold-commitment-ar.test.ts', 'test/fixtures/ceo-hold-commitment-ar.json']) {
|
||
expect(selectTests([file], E2E_TOUCHFILES, []).selected).toEqual(['plan-ceo-mode-routing']);
|
||
}
|
||
});
|