tests/governance-cli.test.ts
Rama main · réplica de lectura del repositorio original.
import assert from 'node:assert/strict';
import { readFile, writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import test from 'node:test';
import { Store } from '../src/adapters/storage/file-store.js';
import { main } from '../src/cli/bootstrap.js';
import { governanceFixture } from './governance-helpers.js';
test('CLI exports a pinned suite, replays it offline and applies previewed policy changes under operator control', async () => {
const { root, config, policy, evaluation, governance } = await governanceFixture();
const configPath = resolve(root, 'config.json'), suitePath = resolve(root, 'suite.json');
await writeFile(configPath, JSON.stringify(config)); let lines: string[] = [];
const output = { write: (value: string) => lines.push(value), error: (value: string) => assert.fail(value) };
const run = async (...args: string[]) => { lines = []; const code = await main([...args, '--config', configPath], output); return { code, value: JSON.parse(lines.at(-1)!) }; };
assert.equal((await run('decisions', 'suite', '--suite', 'decision-triage', '--output', suitePath)).code, 0);
assert.equal(JSON.parse(await readFile(suitePath, 'utf8')).cases.length, 4);
await assert.rejects(run('decisions', 'suite', '--suite', 'decision-triage', '--output', suitePath), /EEXIST/);
const replayed = await run('decisions', 'replay', '--spec', suitePath, '--policy', policy.id);
assert.equal(replayed.code, 0); assert.equal(replayed.value.id, evaluation.id); assert.equal(replayed.value.providerCalls, 0);
assert.equal((await run('decisions', 'sweep', '--spec', suitePath, '--policy', policy.id)).value.results.length, 9);
const preview = await run('policies', 'activate', policy.id, '--evaluation', evaluation.id);
assert.equal(preview.value.eligible, true);
const release = await new Store(root).acquire();
try {
await run('policies', 'activate', policy.id, '--evaluation', evaluation.id, '--apply', '--expected', preview.value.token);
assert.equal((await governance.requests(config.repository)).length, 1);
assert.equal((await run('policies', 'status')).value.revision, 0);
await assert.rejects(run('policies', 'activate', policy.id, '--evaluation', evaluation.id, '--apply', '--expected', 'f'.repeat(24)), /preview/);
} finally { await release(); }
assert.equal((await run('decisions', 'process')).value[0].status, 'applied');
assert.equal((await run('policies', 'status')).value.active, policy.id);
const rollback = await run('policies', 'rollback');
await run('policies', 'rollback', '--apply', '--expected', rollback.value.token); await run('decisions', 'process');
assert.equal((await run('policies', 'status')).value.revision, 2);
assert.equal((await run('policies', 'status')).value.active, rollback.value.target);
});
test('decision replay and policy commands reject foreign IDs, unknown actions and malformed promotion requests', async () => {
const { root, config, policy, evaluation } = await governanceFixture(); const configPath = resolve(root, 'config.json');
await writeFile(configPath, JSON.stringify({ ...config, repository: 'other/repo' }));
const output = { write: (_value: string) => {}, error: (_value: string) => {} };
for (const args of [['policies', 'show', policy.id], ['decisions', 'compare', '--baseline', evaluation.id, '--candidate', evaluation.id],
['policies', 'unknown'], ['decisions', 'unknown'], ['policies', 'rollback', policy.id], ['policies', 'activate', '../policy']])
await assert.rejects(main([...args, '--config', configPath], output));
});