Files
autogame-17_capability-evolver/test/prompt.test.js

110 lines
4.3 KiB
JavaScript
Raw Normal View History

const { describe, it, beforeEach, afterEach } = require('node:test');
const assert = require('node:assert/strict');
const path = require('path');
const savedEnv = {};
const envKeys = ['EVOLVER_REPO_ROOT', 'WORKSPACE_DIR', 'OPENCLAW_WORKSPACE', 'MEMORY_DIR', 'EVOLUTION_DIR'];
beforeEach(() => {
for (const k of envKeys) { savedEnv[k] = process.env[k]; }
process.env.EVOLVER_REPO_ROOT = path.resolve(__dirname, '..');
});
afterEach(() => {
for (const k of envKeys) {
if (savedEnv[k] === undefined) delete process.env[k];
else process.env[k] = savedEnv[k];
}
});
function buildMinimalPrompt(overrides) {
const { buildGepPrompt } = require('../src/gep/prompt');
return buildGepPrompt({
nowIso: '2026-01-01T00:00:00.000Z',
context: '',
signals: ['test_signal'],
selector: { selectedBy: 'test' },
parentEventId: null,
selectedGene: null,
capsuleCandidates: '(none)',
genesPreview: '[]',
capsulesPreview: '[]',
capabilityCandidatesPreview: '(none)',
externalCandidatesPreview: '(none)',
hubMatchedBlock: '',
cycleId: '0001',
recentHistory: '',
failedCapsules: [],
hubLessons: [],
strategyPolicy: null,
...overrides,
});
}
describe('buildGepPrompt -- cross-platform status write', () => {
it('uses node -e for status file creation (not bash heredoc)', () => {
const prompt = buildMinimalPrompt();
assert.ok(prompt.includes('node -e'), 'prompt should contain node -e command');
assert.ok(!prompt.includes('cat >'), 'prompt should NOT contain bash cat > redirect');
assert.ok(!prompt.includes('STATUSEOF'), 'prompt should NOT contain heredoc delimiter');
assert.ok(!prompt.includes('<< '), 'prompt should NOT contain heredoc operator');
});
it('labels the status write as cross-platform', () => {
const prompt = buildMinimalPrompt();
assert.ok(prompt.includes('cross-platform'), 'prompt should mention cross-platform');
});
it('uses mkdirSync with recursive:true for logs directory', () => {
const prompt = buildMinimalPrompt();
assert.ok(prompt.includes('mkdirSync'), 'prompt should use mkdirSync');
assert.ok(prompt.includes('recursive:true') || prompt.includes('recursive: true'),
'prompt should use recursive mkdir');
});
it('uses writeFileSync for status JSON', () => {
const prompt = buildMinimalPrompt();
assert.ok(prompt.includes('writeFileSync'), 'prompt should use writeFileSync');
});
it('includes cycle ID in status filename', () => {
const prompt = buildMinimalPrompt({ cycleId: '0042' });
assert.ok(prompt.includes('status_0042'), 'prompt should include cycle ID in filename');
});
it('escapes backslash paths for Windows compatibility', () => {
process.env.WORKSPACE_DIR = 'D:\\Projects\\evolver';
const prompt = buildMinimalPrompt();
assert.ok(!prompt.includes('D:\\Projects\\evolver/logs') || prompt.includes('D:/Projects/evolver/logs'),
'backslash paths should be normalized to forward slashes in the node -e command');
});
});
describe('buildGepPrompt -- structure', () => {
it('contains GEP protocol header', () => {
const prompt = buildMinimalPrompt();
assert.ok(prompt.includes('GEP'), 'prompt should contain GEP header');
assert.ok(prompt.includes('GENOME EVOLUTION PROTOCOL'), 'prompt should contain full protocol name');
});
it('contains mandatory object model section', () => {
const prompt = buildMinimalPrompt();
assert.ok(prompt.includes('Mutation'), 'prompt should contain Mutation object');
assert.ok(prompt.includes('PersonalityState'), 'prompt should contain PersonalityState');
assert.ok(prompt.includes('EvolutionEvent'), 'prompt should contain EvolutionEvent');
assert.ok(prompt.includes('Gene'), 'prompt should contain Gene');
assert.ok(prompt.includes('Capsule'), 'prompt should contain Capsule');
});
it('contains constitutional ethics section', () => {
const prompt = buildMinimalPrompt();
assert.ok(prompt.includes('CONSTITUTIONAL ETHICS'), 'prompt should contain ethics section');
assert.ok(prompt.includes('HUMAN WELFARE'), 'prompt should contain human welfare principle');
});
it('contains cycle ID in report requirement', () => {
const prompt = buildMinimalPrompt({ cycleId: '0099' });
assert.ok(prompt.includes('0099'), 'prompt should reference cycle ID');
});
});