Files
TORCH/test/fleet/product-surface.test.mjs
T

75 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { createConsoleServer } from '../../src/console/server.mjs';
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
import { proposeDomains } from '../../src/kernel/domains.mjs';
import { inspectRepository } from '../../src/kernel/git.mjs';
import { installProject } from '../../src/kernel/install.mjs';
import { observeProject } from '../../src/observability/snapshot.mjs';
function fixture() {
const root = mkdtempSync(join(tmpdir(), 'torch-console-'));
execFileSync('git', ['init', '-b', 'main', root]);
execFileSync('git', ['-C', root, 'config', 'user.email', '[email protected]']);
execFileSync('git', ['-C', root, 'config', 'user.name', 'TORCH Test']);
writeFileSync(join(root, 'README.md'), '# Console fixture\n');
execFileSync('git', ['-C', root, 'add', '.']);
execFileSync('git', ['-C', root, 'commit', '-m', 'fixture']);
return root;
}
test('SCN-product-site: public surface explains the portable fleet and separates the local console', () => {
const html = readFileSync(new URL('../../site/index.html', import.meta.url), 'utf8');
const consoleHtml = readFileSync(new URL('../../site/console.html', import.meta.url), 'utf8');
assert.match(html, /One repository[\s\S]*coordinated AI engineering team/);
assert.match(html, /id="route-toggle"/);
assert.match(html, /Exact-commit checks/);
assert.match(html, /Live gate open/);
assert.match(html, /Context savings are a measured hypothesis/);
assert.match(html, /torch\.mjs bootstrap/);
assert.match(html, /manager can propose another specialist[\s\S]*owner approval/i);
assert.doesNotMatch(html, /nostr|relay coordination|task lock/i);
assert.match(consoleHtml, /Local Fleet Console/);
assert.match(consoleHtml, /noindex,nofollow/);
});
test('SCN-console-readonly: HTTP console serves fixed assets and observes an installed fleet without mutation', async (context) => {
const root = fixture();
const env = { ...process.env, XDG_DATA_HOME: mkdtempSync(join(tmpdir(), 'torch-console-state-')) };
const repository = inspectRepository(root);
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
proposal.review = {
status: 'approved', reviewedAt: '2026-09-27T00:00:00Z', reviewedBy: 'fixture-owner', notes: [],
};
installProject({ repository, proposal, env, projectId: 'console-fixture' });
const databasePath = join(env.XDG_DATA_HOME, 'torch', 'projects', 'console-fixture', 'state.db');
assert.equal(existsSync(databasePath), false);
const before = execFileSync('git', ['-C', root, 'status', '--porcelain'], { encoding: 'utf8' });
const observed = observeProject({ repositoryRoot: root, env, now: () => new Date('2026-09-27T00:00:00Z') });
assert.equal(observed.mode, 'installed');
assert.equal(observed.mutationPerformed, false);
assert.equal(observed.agents.length, proposal.domains.length + 1);
assert.equal(observed.contextLocality.measured, false);
assert.deepEqual(observed.fleetChanges, []);
assert.equal(existsSync(databasePath), false);
assert.equal(execFileSync('git', ['-C', root, 'status', '--porcelain'], { encoding: 'utf8' }), before);
const server = createConsoleServer({ repositoryRoot: root, env });
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
context.after(() => server.close());
const origin = `http://127.0.0.1:${server.address().port}`;
const page = await fetch(`${origin}/`);
assert.equal(page.status, 200);
assert.match(page.headers.get('content-security-policy'), /default-src 'self'/);
assert.match(await page.text(), /coordinated AI engineering team/);
const snapshot = await fetch(`${origin}/api/snapshot`);
assert.equal(snapshot.status, 200);
assert.equal((await snapshot.json()).mutationPerformed, false);
assert.equal((await fetch(`${origin}/../package.json`)).status, 404);
assert.equal(execFileSync('git', ['-C', root, 'status', '--porcelain'], { encoding: 'utf8' }), before);
});